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