diff options
Diffstat (limited to 'src/postscreen/postscreen_haproxy.c')
-rw-r--r-- | src/postscreen/postscreen_haproxy.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/src/postscreen/postscreen_haproxy.c b/src/postscreen/postscreen_haproxy.c new file mode 100644 index 0000000..45c6b9a --- /dev/null +++ b/src/postscreen/postscreen_haproxy.c @@ -0,0 +1,137 @@ +/*++ +/* NAME +/* postscreen_haproxy 3 +/* SUMMARY +/* haproxy protocol adapter +/* SYNOPSIS +/* #include <postscreen_haproxy.h> +/* +/* void psc_endpt_haproxy_lookup(smtp_client_stream, lookup_done) +/* VSTRING *smtp_client_stream; +/* void (*lookup_done)(status, smtp_client_stream, +/* smtp_client_addr, smtp_client_port, +/* smtp_server_addr, smtp_server_port) +/* int status; +/* MAI_HOSTADDR_STR *smtp_client_addr; +/* MAI_SERVPORT_STR *smtp_client_port; +/* MAI_HOSTADDR_STR *smtp_server_addr; +/* MAI_SERVPORT_STR *smtp_server_port; +/* DESCRIPTION +/* psc_endpt_haproxy_lookup() looks up connection endpoint +/* information via the haproxy protocol, or looks up local +/* information if the haproxy handshake indicates that a +/* connection is not proxied. Arguments and results conform +/* to the postscreen_endpt(3) API. +/* LICENSE +/* .ad +/* .fi +/* The Secure Mailer license must be distributed with this software. +/* AUTHOR(S) +/* Wietse Venema +/* IBM T.J. Watson Research +/* P.O. Box 704 +/* Yorktown Heights, NY 10598, USA +/* +/* Wietse Venema +/* Google, Inc. +/* 111 8th Avenue +/* New York, NY 10011, USA +/*--*/ + +/* System library. */ + +#include <sys_defs.h> +#include <stdio.h> +#include <stdarg.h> +#include <stdlib.h> + +/* Utility library. */ + +#include <msg.h> +#include <mymalloc.h> +#include <events.h> +#include <myaddrinfo.h> +#include <vstream.h> +#include <vstring.h> +#include <stringops.h> + +/* Global library. */ + +#include <haproxy_srvr.h> +#include <mail_params.h> + +/* Application-specific. */ + +#include <postscreen.h> +#include <postscreen_haproxy.h> + + /* + * Per-session state. + */ +typedef struct { + VSTREAM *stream; + PSC_ENDPT_LOOKUP_FN notify; +} PSC_HAPROXY_STATE; + +/* psc_endpt_haproxy_event - read or time event */ + +static void psc_endpt_haproxy_event(int event, void *context) +{ + const char *myname = "psc_endpt_haproxy_event"; + PSC_HAPROXY_STATE *state = (PSC_HAPROXY_STATE *) context; + int status = 0; + MAI_HOSTADDR_STR smtp_client_addr; + MAI_SERVPORT_STR smtp_client_port; + MAI_HOSTADDR_STR smtp_server_addr; + MAI_SERVPORT_STR smtp_server_port; + int non_proxy = 0; + + switch (event) { + case EVENT_TIME: + msg_warn("haproxy read: time limit exceeded"); + status = -1; + break; + case EVENT_READ: + status = haproxy_srvr_receive(vstream_fileno(state->stream), &non_proxy, + &smtp_client_addr, &smtp_client_port, + &smtp_server_addr, &smtp_server_port); + } + + /* + * Terminate this pseudo thread, and notify the caller. + */ + PSC_CLEAR_EVENT_REQUEST(vstream_fileno(state->stream), + psc_endpt_haproxy_event, context); + if (status == 0 && non_proxy) + psc_endpt_local_lookup(state->stream, state->notify); + else + state->notify(status, state->stream, + &smtp_client_addr, &smtp_client_port, + &smtp_server_addr, &smtp_server_port); + /* Note: the stream may be closed at this point. */ + myfree((void *) state); +} + +/* psc_endpt_haproxy_lookup - event-driven haproxy client */ + +void psc_endpt_haproxy_lookup(VSTREAM *stream, + PSC_ENDPT_LOOKUP_FN notify) +{ + const char *myname = "psc_endpt_haproxy_lookup"; + PSC_HAPROXY_STATE *state; + + /* + * Prepare the per-session state. XXX To improve overload behavior, + * maintain a pool of these so that we can reduce memory allocator + * activity. + */ + state = (PSC_HAPROXY_STATE *) mymalloc(sizeof(*state)); + state->stream = stream; + state->notify = notify; + + /* + * Read the haproxy line. + */ + PSC_READ_EVENT_REQUEST(vstream_fileno(stream), psc_endpt_haproxy_event, + (void *) state, var_psc_uproxy_tmout); +} |