Home | History | Annotate | Line # | Download | only in postscreen
      1 /*	$NetBSD: postscreen_haproxy.c,v 1.3 2020/03/18 19:05:19 christos Exp $	*/
      2 
      3 /*++
      4 /* NAME
      5 /*	postscreen_haproxy 3
      6 /* SUMMARY
      7 /*	haproxy protocol adapter
      8 /* SYNOPSIS
      9 /*	#include <postscreen_haproxy.h>
     10 /*
     11 /*	void	psc_endpt_haproxy_lookup(smtp_client_stream, lookup_done)
     12 /*	VSTRING	*smtp_client_stream;
     13 /*	void	(*lookup_done)(status, smtp_client_stream,
     14 /*				smtp_client_addr, smtp_client_port,
     15 /*				smtp_server_addr, smtp_server_port)
     16 /*	int	status;
     17 /*	MAI_HOSTADDR_STR *smtp_client_addr;
     18 /*	MAI_SERVPORT_STR *smtp_client_port;
     19 /*	MAI_HOSTADDR_STR *smtp_server_addr;
     20 /*	MAI_SERVPORT_STR *smtp_server_port;
     21 /* DESCRIPTION
     22 /*	psc_endpt_haproxy_lookup() looks up connection endpoint
     23 /*	information via the haproxy protocol, or looks up local
     24 /*	information if the haproxy handshake indicates that a
     25 /*	connection is not proxied. Arguments and results conform
     26 /*	to the postscreen_endpt(3) API.
     27 /* LICENSE
     28 /* .ad
     29 /* .fi
     30 /*	The Secure Mailer license must be distributed with this software.
     31 /* AUTHOR(S)
     32 /*	Wietse Venema
     33 /*	IBM T.J. Watson Research
     34 /*	P.O. Box 704
     35 /*	Yorktown Heights, NY 10598, USA
     36 /*
     37 /*	Wietse Venema
     38 /*	Google, Inc.
     39 /*	111 8th Avenue
     40 /*	New York, NY 10011, USA
     41 /*--*/
     42 
     43 /* System library. */
     44 
     45 #include <sys_defs.h>
     46 #include <stdio.h>
     47 #include <stdarg.h>
     48 #include <stdlib.h>
     49 
     50 /* Utility library. */
     51 
     52 #include <msg.h>
     53 #include <mymalloc.h>
     54 #include <events.h>
     55 #include <myaddrinfo.h>
     56 #include <vstream.h>
     57 #include <vstring.h>
     58 #include <stringops.h>
     59 
     60 /* Global library. */
     61 
     62 #include <haproxy_srvr.h>
     63 #include <mail_params.h>
     64 
     65 /* Application-specific. */
     66 
     67 #include <postscreen.h>
     68 #include <postscreen_haproxy.h>
     69 
     70  /*
     71   * Per-session state.
     72   */
     73 typedef struct {
     74     VSTREAM *stream;
     75     PSC_ENDPT_LOOKUP_FN notify;
     76 } PSC_HAPROXY_STATE;
     77 
     78 /* psc_endpt_haproxy_event - read or time event */
     79 
     80 static void psc_endpt_haproxy_event(int event, void *context)
     81 {
     82     const char *myname = "psc_endpt_haproxy_event";
     83     PSC_HAPROXY_STATE *state = (PSC_HAPROXY_STATE *) context;
     84     int     status = 0;
     85     MAI_HOSTADDR_STR smtp_client_addr;
     86     MAI_SERVPORT_STR smtp_client_port;
     87     MAI_HOSTADDR_STR smtp_server_addr;
     88     MAI_SERVPORT_STR smtp_server_port;
     89     int     non_proxy = 0;
     90 
     91     switch (event) {
     92     case EVENT_TIME:
     93 	msg_warn("haproxy read: time limit exceeded");
     94 	status = -1;
     95 	break;
     96     case EVENT_READ:
     97 	status = haproxy_srvr_receive(vstream_fileno(state->stream), &non_proxy,
     98 				      &smtp_client_addr, &smtp_client_port,
     99 				      &smtp_server_addr, &smtp_server_port);
    100     }
    101 
    102     /*
    103      * Terminate this pseudo thread, and notify the caller.
    104      */
    105     PSC_CLEAR_EVENT_REQUEST(vstream_fileno(state->stream),
    106 			    psc_endpt_haproxy_event, context);
    107     if (status == 0 && non_proxy)
    108 	psc_endpt_local_lookup(state->stream, state->notify);
    109     else
    110 	state->notify(status, state->stream,
    111 		      &smtp_client_addr, &smtp_client_port,
    112 		      &smtp_server_addr, &smtp_server_port);
    113     /* Note: the stream may be closed at this point. */
    114     myfree((void *) state);
    115 }
    116 
    117 /* psc_endpt_haproxy_lookup - event-driven haproxy client */
    118 
    119 void    psc_endpt_haproxy_lookup(VSTREAM *stream,
    120 				         PSC_ENDPT_LOOKUP_FN notify)
    121 {
    122     const char *myname = "psc_endpt_haproxy_lookup";
    123     PSC_HAPROXY_STATE *state;
    124 
    125     /*
    126      * Prepare the per-session state. XXX To improve overload behavior,
    127      * maintain a pool of these so that we can reduce memory allocator
    128      * activity.
    129      */
    130     state = (PSC_HAPROXY_STATE *) mymalloc(sizeof(*state));
    131     state->stream = stream;
    132     state->notify = notify;
    133 
    134     /*
    135      * Read the haproxy line.
    136      */
    137     PSC_READ_EVENT_REQUEST(vstream_fileno(stream), psc_endpt_haproxy_event,
    138 			   (void *) state, var_psc_uproxy_tmout);
    139 }
    140