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