xref: /netbsd-src/external/ibm-public/postfix/dist/src/postscreen/postscreen_haproxy.c (revision 33881f779a77dce6440bdc44610d94de75bebefe)
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 
psc_endpt_haproxy_event(int event,void * context)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 
psc_endpt_haproxy_lookup(VSTREAM * stream,PSC_ENDPT_LOOKUP_FN notify)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