diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-03-17 08:35:44 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-03-17 08:35:44 +0000 |
commit | aefed941c26aade36c5b51c8ef5ea6f740cc0e5d (patch) | |
tree | 761f70714a935be54cac8ec4efb196638a092ae9 /ipsvd | |
parent | 9f153f610fe82528bcd0f976fd9ce2122c516b2d (diff) | |
download | busybox-w32-aefed941c26aade36c5b51c8ef5ea6f740cc0e5d.tar.gz busybox-w32-aefed941c26aade36c5b51c8ef5ea6f740cc0e5d.tar.bz2 busybox-w32-aefed941c26aade36c5b51c8ef5ea6f740cc0e5d.zip |
tcpsvd,udpsvd: make them NOMMU-capable
inetd: make udp nowait work
function old new delta
inetd_main 1797 2036 +239
tcpudpsvd_main 1839 1973 +134
xsetenv_plain - 39 +39
xsetenv_proto 23 40 +17
bump_nofile 169 170 +1
sig_term_handler 72 69 -3
sig_child_handler 239 233 -6
connection_status 37 31 -6
parse_one_line 1102 1092 -10
------------------------------------------------------------------------------
(add/remove: 1/0 grow/shrink: 4/4 up/down: 430/-25) Total: 405 bytes
text data bss dec hex filename
798437 661 7428 806526 c4e7e busybox_old
798734 661 7428 806823 c4fa7 busybox_unstripped
Diffstat (limited to 'ipsvd')
-rw-r--r-- | ipsvd/tcpudp.c | 231 |
1 files changed, 135 insertions, 96 deletions
diff --git a/ipsvd/tcpudp.c b/ipsvd/tcpudp.c index 5362af5fd..2e8dffa0f 100644 --- a/ipsvd/tcpudp.c +++ b/ipsvd/tcpudp.c | |||
@@ -13,12 +13,12 @@ | |||
13 | * | 13 | * |
14 | * Code inside "#ifdef SSLSVD" is for sslsvd and is currently unused. | 14 | * Code inside "#ifdef SSLSVD" is for sslsvd and is currently unused. |
15 | * | 15 | * |
16 | * Output of verbose mode matches original (modulo bugs and | 16 | * Busybox version exports TCPLOCALADDR instead of |
17 | * unimplemented stuff). Unnatural splitting of IP and PORT | 17 | * TCPLOCALIP + TCPLOCALPORT pair. ADDR more closely matches reality |
18 | * is retained (personally I prefer one-value "IP:PORT" notation - | 18 | * (which is "struct sockaddr_XXX". Port is not a separate entity, |
19 | * it is a natural string representation of struct sockaddr_XX). | 19 | * it's just a part of (AF_INET[6]) sockaddr!). |
20 | * | 20 | * |
21 | * TCPORIGDST{IP,PORT} is busybox-specific addition | 21 | * TCPORIGDSTADDR is Busybox-specific addition. |
22 | * | 22 | * |
23 | * udp server is hacked up by reusing TCP code. It has the following | 23 | * udp server is hacked up by reusing TCP code. It has the following |
24 | * limitation inherent in Unix DGRAM sockets implementation: | 24 | * limitation inherent in Unix DGRAM sockets implementation: |
@@ -46,6 +46,8 @@ struct globals { | |||
46 | unsigned cur_per_host; | 46 | unsigned cur_per_host; |
47 | unsigned cnum; | 47 | unsigned cnum; |
48 | unsigned cmax; | 48 | unsigned cmax; |
49 | char **env_cur; | ||
50 | char *env_var[1]; /* actually bigger */ | ||
49 | }; | 51 | }; |
50 | #define G (*(struct globals*)&bb_common_bufsiz1) | 52 | #define G (*(struct globals*)&bb_common_bufsiz1) |
51 | #define verbose (G.verbose ) | 53 | #define verbose (G.verbose ) |
@@ -53,21 +55,46 @@ struct globals { | |||
53 | #define cur_per_host (G.cur_per_host) | 55 | #define cur_per_host (G.cur_per_host) |
54 | #define cnum (G.cnum ) | 56 | #define cnum (G.cnum ) |
55 | #define cmax (G.cmax ) | 57 | #define cmax (G.cmax ) |
58 | #define env_cur (G.env_cur ) | ||
59 | #define env_var (G.env_var ) | ||
56 | #define INIT_G() \ | 60 | #define INIT_G() \ |
57 | do { \ | 61 | do { \ |
58 | cmax = 30; \ | 62 | cmax = 30; \ |
63 | env_cur = &env_var[0]; \ | ||
59 | } while (0) | 64 | } while (0) |
60 | 65 | ||
61 | 66 | ||
67 | /* We have to be careful about leaking memory in repeated setenv's */ | ||
68 | static void xsetenv_plain(const char *n, const char *v) | ||
69 | { | ||
70 | char *var = xasprintf("%s=%s", n, v); | ||
71 | *env_cur++ = var; | ||
72 | putenv(var); | ||
73 | } | ||
74 | |||
62 | static void xsetenv_proto(const char *proto, const char *n, const char *v) | 75 | static void xsetenv_proto(const char *proto, const char *n, const char *v) |
63 | { | 76 | { |
64 | putenv(xasprintf("%s%s=%s", proto, n, v)); | 77 | char *var = xasprintf("%s%s=%s", proto, n, v); |
78 | *env_cur++ = var; | ||
79 | putenv(var); | ||
80 | } | ||
81 | |||
82 | static void undo_xsetenv(void) | ||
83 | { | ||
84 | char **pp = env_cur = &env_var[0]; | ||
85 | while (*pp) { | ||
86 | char *var = *pp; | ||
87 | *strchrnul(var, '=') = '\0'; | ||
88 | unsetenv(var); | ||
89 | free(var); | ||
90 | *pp++ = NULL; | ||
91 | } | ||
65 | } | 92 | } |
66 | 93 | ||
67 | static void sig_term_handler(int sig) | 94 | static void sig_term_handler(int sig) |
68 | { | 95 | { |
69 | if (verbose) | 96 | if (verbose) |
70 | printf("%s: info: sigterm received, exit\n", applet_name); | 97 | bb_error_msg("got signal %u, exit", sig); |
71 | kill_myself_with_sig(sig); | 98 | kill_myself_with_sig(sig); |
72 | } | 99 | } |
73 | 100 | ||
@@ -85,7 +112,7 @@ static void print_waitstat(unsigned pid, int wstat) | |||
85 | cause = "signal"; | 112 | cause = "signal"; |
86 | e = WTERMSIG(wstat); | 113 | e = WTERMSIG(wstat); |
87 | } | 114 | } |
88 | printf("%s: info: end %d %s %d\n", applet_name, pid, cause, e); | 115 | bb_error_msg("end %d %s %d", pid, cause, e); |
89 | } | 116 | } |
90 | 117 | ||
91 | /* Must match getopt32 in main! */ | 118 | /* Must match getopt32 in main! */ |
@@ -113,7 +140,7 @@ static void connection_status(void) | |||
113 | { | 140 | { |
114 | /* "only 1 client max" desn't need this */ | 141 | /* "only 1 client max" desn't need this */ |
115 | if (cmax > 1) | 142 | if (cmax > 1) |
116 | printf("%s: info: status %u/%u\n", applet_name, cnum, cmax); | 143 | bb_error_msg("status %u/%u", cnum, cmax); |
117 | } | 144 | } |
118 | 145 | ||
119 | static void sig_child_handler(int sig) | 146 | static void sig_child_handler(int sig) |
@@ -145,13 +172,11 @@ int tcpudpsvd_main(int argc, char **argv) | |||
145 | #ifndef SSLSVD | 172 | #ifndef SSLSVD |
146 | struct bb_uidgid_t ugid; | 173 | struct bb_uidgid_t ugid; |
147 | #endif | 174 | #endif |
148 | bool need_hostnames, need_remote_ip, tcp; | 175 | bool tcp; |
149 | uint16_t local_port; | 176 | uint16_t local_port; |
150 | char *local_hostname = NULL; | 177 | char *preset_local_hostname = NULL; |
151 | char *remote_hostname = (char*)""; /* "" used if no -h */ | 178 | char *remote_hostname = remote_hostname; /* for compiler */ |
152 | char *local_addr = local_addr; /* gcc */ | 179 | char *remote_addr = remote_addr; /* for compiler */ |
153 | char *remote_addr = remote_addr; /* gcc */ | ||
154 | char *remote_ip = remote_addr; /* gcc */ | ||
155 | len_and_sockaddr *lsa; | 180 | len_and_sockaddr *lsa; |
156 | len_and_sockaddr local, remote; | 181 | len_and_sockaddr local, remote; |
157 | socklen_t sa_len; | 182 | socklen_t sa_len; |
@@ -168,12 +193,12 @@ int tcpudpsvd_main(int argc, char **argv) | |||
168 | opt_complementary = "-3:i--i:ph:vv"; | 193 | opt_complementary = "-3:i--i:ph:vv"; |
169 | #ifdef SSLSVD | 194 | #ifdef SSLSVD |
170 | getopt32(argv, "+c:C:i:x:u:l:Eb:hpt:vU:/:Z:K:", | 195 | getopt32(argv, "+c:C:i:x:u:l:Eb:hpt:vU:/:Z:K:", |
171 | &str_c, &str_C, &instructs, &instructs, &user, &local_hostname, | 196 | &str_c, &str_C, &instructs, &instructs, &user, &preset_local_hostname, |
172 | &str_b, &str_t, &ssluser, &root, &cert, &key, &verbose | 197 | &str_b, &str_t, &ssluser, &root, &cert, &key, &verbose |
173 | ); | 198 | ); |
174 | #else | 199 | #else |
175 | getopt32(argv, "+c:C:i:x:u:l:Eb:hpt:v", | 200 | getopt32(argv, "+c:C:i:x:u:l:Eb:hpt:v", |
176 | &str_c, &str_C, &instructs, &instructs, &user, &local_hostname, | 201 | &str_c, &str_C, &instructs, &instructs, &user, &preset_local_hostname, |
177 | &str_b, &str_t, &verbose | 202 | &str_b, &str_t, &verbose |
178 | ); | 203 | ); |
179 | #endif | 204 | #endif |
@@ -210,26 +235,21 @@ int tcpudpsvd_main(int argc, char **argv) | |||
210 | if (!tcp) | 235 | if (!tcp) |
211 | max_per_host = 0; | 236 | max_per_host = 0; |
212 | 237 | ||
213 | /* stdout is used for logging, don't buffer */ | ||
214 | setlinebuf(stdout); | ||
215 | bb_sanitize_stdio(); /* fd# 0,1,2 must be opened */ | 238 | bb_sanitize_stdio(); /* fd# 0,1,2 must be opened */ |
216 | 239 | ||
217 | need_hostnames = verbose || !(option_mask32 & OPT_E); | ||
218 | need_remote_ip = max_per_host || need_hostnames; | ||
219 | |||
220 | #ifdef SSLSVD | 240 | #ifdef SSLSVD |
221 | sslser = user; | 241 | sslser = user; |
222 | client = 0; | 242 | client = 0; |
223 | if ((getuid() == 0) && !(option_mask32 & OPT_u)) { | 243 | if ((getuid() == 0) && !(option_mask32 & OPT_u)) { |
224 | xfunc_exitcode = 100; | 244 | xfunc_exitcode = 100; |
225 | bb_error_msg_and_die("fatal: -U ssluser must be set when running as root"); | 245 | bb_error_msg_and_die("-U ssluser must be set when running as root"); |
226 | } | 246 | } |
227 | if (option_mask32 & OPT_u) | 247 | if (option_mask32 & OPT_u) |
228 | if (!uidgid_get(&sslugid, ssluser, 1)) { | 248 | if (!uidgid_get(&sslugid, ssluser, 1)) { |
229 | if (errno) { | 249 | if (errno) { |
230 | bb_perror_msg_and_die("fatal: cannot get user/group: %s", ssluser); | 250 | bb_perror_msg_and_die("fatal: cannot get user/group: %s", ssluser); |
231 | } | 251 | } |
232 | bb_error_msg_and_die("fatal: unknown user/group '%s'", ssluser); | 252 | bb_error_msg_and_die("unknown user/group '%s'", ssluser); |
233 | } | 253 | } |
234 | if (!cert) cert = "./cert.pem"; | 254 | if (!cert) cert = "./cert.pem"; |
235 | if (!key) key = cert; | 255 | if (!key) key = cert; |
@@ -246,7 +266,7 @@ int tcpudpsvd_main(int argc, char **argv) | |||
246 | 266 | ||
247 | sig_block(SIGCHLD); | 267 | sig_block(SIGCHLD); |
248 | signal(SIGCHLD, sig_child_handler); | 268 | signal(SIGCHLD, sig_child_handler); |
249 | signal(SIGTERM, sig_term_handler); | 269 | bb_signals(BB_SIGS_FATAL, sig_term_handler); |
250 | signal(SIGPIPE, SIG_IGN); | 270 | signal(SIGPIPE, SIG_IGN); |
251 | 271 | ||
252 | if (max_per_host) | 272 | if (max_per_host) |
@@ -254,6 +274,8 @@ int tcpudpsvd_main(int argc, char **argv) | |||
254 | 274 | ||
255 | local_port = bb_lookup_port(argv[1], tcp ? "tcp" : "udp", 0); | 275 | local_port = bb_lookup_port(argv[1], tcp ? "tcp" : "udp", 0); |
256 | lsa = xhost2sockaddr(argv[0], local_port); | 276 | lsa = xhost2sockaddr(argv[0], local_port); |
277 | argv += 2; | ||
278 | |||
257 | sock = xsocket(lsa->u.sa.sa_family, tcp ? SOCK_STREAM : SOCK_DGRAM, 0); | 279 | sock = xsocket(lsa->u.sa.sa_family, tcp ? SOCK_STREAM : SOCK_DGRAM, 0); |
258 | setsockopt_reuseaddr(sock); | 280 | setsockopt_reuseaddr(sock); |
259 | sa_len = lsa->len; /* I presume sockaddr len stays the same */ | 281 | sa_len = lsa->len; /* I presume sockaddr len stays the same */ |
@@ -274,14 +296,13 @@ int tcpudpsvd_main(int argc, char **argv) | |||
274 | 296 | ||
275 | if (verbose) { | 297 | if (verbose) { |
276 | char *addr = xmalloc_sockaddr2dotted(&lsa->u.sa); | 298 | char *addr = xmalloc_sockaddr2dotted(&lsa->u.sa); |
277 | printf("%s: info: listening on %s", applet_name, addr); | 299 | bb_error_msg("listening on %s, starting", addr); |
278 | free(addr); | 300 | free(addr); |
279 | #ifndef SSLSVD | 301 | #ifndef SSLSVD |
280 | if (option_mask32 & OPT_u) | 302 | if (option_mask32 & OPT_u) |
281 | printf(", uid %u, gid %u", | 303 | printf(", uid %u, gid %u", |
282 | (unsigned)ugid.uid, (unsigned)ugid.gid); | 304 | (unsigned)ugid.uid, (unsigned)ugid.gid); |
283 | #endif | 305 | #endif |
284 | puts(", starting"); | ||
285 | } | 306 | } |
286 | 307 | ||
287 | /* Main accept() loop */ | 308 | /* Main accept() loop */ |
@@ -297,14 +318,15 @@ int tcpudpsvd_main(int argc, char **argv) | |||
297 | close(0); | 318 | close(0); |
298 | again2: | 319 | again2: |
299 | sig_unblock(SIGCHLD); | 320 | sig_unblock(SIGCHLD); |
321 | local.len = remote.len = sa_len; | ||
300 | if (tcp) { | 322 | if (tcp) { |
301 | remote.len = sa_len; | ||
302 | conn = accept(sock, &remote.u.sa, &remote.len); | 323 | conn = accept(sock, &remote.u.sa, &remote.len); |
303 | } else { | 324 | } else { |
304 | /* In case recv_from_to won't be able to recover local addr. | 325 | /* In case recv_from_to won't be able to recover local addr. |
305 | * Also sets port - recv_from_to is unable to do it. */ | 326 | * Also sets port - recv_from_to is unable to do it. */ |
306 | local = *lsa; | 327 | local = *lsa; |
307 | conn = recv_from_to(sock, NULL, 0, MSG_PEEK, &remote.u.sa, &local.u.sa, sa_len); | 328 | conn = recv_from_to(sock, NULL, 0, MSG_DONTWAIT | MSG_PEEK, |
329 | &remote.u.sa, &local.u.sa, sa_len); | ||
308 | } | 330 | } |
309 | sig_block(SIGCHLD); | 331 | sig_block(SIGCHLD); |
310 | if (conn < 0) { | 332 | if (conn < 0) { |
@@ -317,19 +339,19 @@ int tcpudpsvd_main(int argc, char **argv) | |||
317 | if (max_per_host) { | 339 | if (max_per_host) { |
318 | /* Drop connection immediately if cur_per_host > max_per_host | 340 | /* Drop connection immediately if cur_per_host > max_per_host |
319 | * (minimizing load under SYN flood) */ | 341 | * (minimizing load under SYN flood) */ |
320 | remote_ip = xmalloc_sockaddr2dotted_noport(&remote.u.sa); | 342 | remote_addr = xmalloc_sockaddr2dotted_noport(&remote.u.sa); |
321 | cur_per_host = ipsvd_perhost_add(remote_ip, max_per_host, &hccp); | 343 | cur_per_host = ipsvd_perhost_add(remote_addr, max_per_host, &hccp); |
322 | if (cur_per_host > max_per_host) { | 344 | if (cur_per_host > max_per_host) { |
323 | /* ipsvd_perhost_add detected that max is exceeded | 345 | /* ipsvd_perhost_add detected that max is exceeded |
324 | * (and did not store ip in connection table) */ | 346 | * (and did not store ip in connection table) */ |
325 | free(remote_ip); | 347 | free(remote_addr); |
326 | if (msg_per_host) { | 348 | if (msg_per_host) { |
327 | /* don't block or test for errors */ | 349 | /* don't block or test for errors */ |
328 | ndelay_on(0); | 350 | send(0, msg_per_host, len_per_host, MSG_DONTWAIT); |
329 | write(0, msg_per_host, len_per_host); | ||
330 | } | 351 | } |
331 | goto again1; | 352 | goto again1; |
332 | } | 353 | } |
354 | /* NB: remote_addr is not leaked, it is stored in conn table */ | ||
333 | } | 355 | } |
334 | 356 | ||
335 | if (!tcp) { | 357 | if (!tcp) { |
@@ -372,19 +394,21 @@ int tcpudpsvd_main(int argc, char **argv) | |||
372 | #endif | 394 | #endif |
373 | } | 395 | } |
374 | 396 | ||
375 | pid = fork(); | 397 | pid = vfork(); |
376 | if (pid == -1) { | 398 | if (pid == -1) { |
377 | bb_perror_msg("fork"); | 399 | bb_perror_msg("vfork"); |
378 | goto again; | 400 | goto again; |
379 | } | 401 | } |
380 | 402 | ||
381 | if (pid != 0) { | 403 | if (pid != 0) { |
382 | /* parent */ | 404 | /* Parent */ |
383 | cnum++; | 405 | cnum++; |
384 | if (verbose) | 406 | if (verbose) |
385 | connection_status(); | 407 | connection_status(); |
386 | if (hccp) | 408 | if (hccp) |
387 | hccp->pid = pid; | 409 | hccp->pid = pid; |
410 | /* clean up changes done by vforked child */ | ||
411 | undo_xsetenv(); | ||
388 | goto again; | 412 | goto again; |
389 | } | 413 | } |
390 | 414 | ||
@@ -394,78 +418,93 @@ int tcpudpsvd_main(int argc, char **argv) | |||
394 | if (tcp) | 418 | if (tcp) |
395 | close(sock); | 419 | close(sock); |
396 | 420 | ||
397 | if (need_remote_ip) | 421 | { /* vfork alert! every xmalloc in this block should be freed! */ |
398 | remote_addr = xmalloc_sockaddr2dotted(&remote.u.sa); | 422 | char *local_hostname = local_hostname; /* for compiler */ |
399 | 423 | char *local_addr = NULL; | |
400 | if (need_hostnames) { | 424 | char *free_me0 = NULL; |
401 | if (option_mask32 & OPT_h) { | 425 | char *free_me1 = NULL; |
402 | remote_hostname = xmalloc_sockaddr2host_noport(&remote.u.sa); | 426 | char *free_me2 = NULL; |
403 | if (!remote_hostname) { | 427 | |
404 | bb_error_msg("warning: cannot look up hostname for %s", remote_addr); | 428 | if (verbose || !(option_mask32 & OPT_E)) { |
405 | remote_hostname = (char*)""; | 429 | if (!max_per_host) /* remote_addr is not yet known */ |
430 | free_me0 = remote_addr = xmalloc_sockaddr2dotted(&remote.u.sa); | ||
431 | if (option_mask32 & OPT_h) { | ||
432 | free_me1 = remote_hostname = xmalloc_sockaddr2host_noport(&remote.u.sa); | ||
433 | if (!remote_hostname) { | ||
434 | bb_error_msg("cannot look up hostname for %s", remote_addr); | ||
435 | remote_hostname = remote_addr; | ||
436 | } | ||
437 | } | ||
438 | /* Find out local IP peer connected to. | ||
439 | * Errors ignored (I'm not paranoid enough to imagine kernel | ||
440 | * which doesn't know local IP). */ | ||
441 | if (tcp) | ||
442 | getsockname(0, &local.u.sa, &local.len); | ||
443 | /* else: for UDP it is done earlier by parent */ | ||
444 | local_addr = xmalloc_sockaddr2dotted(&local.u.sa); | ||
445 | if (option_mask32 & OPT_h) { | ||
446 | local_hostname = preset_local_hostname; | ||
447 | if (!local_hostname) { | ||
448 | free_me2 = local_hostname = xmalloc_sockaddr2host_noport(&local.u.sa); | ||
449 | if (!local_hostname) | ||
450 | bb_error_msg_and_die("cannot look up hostname for %s", local_addr); | ||
451 | } | ||
452 | /* else: local_hostname is not NULL, but is NOT malloced! */ | ||
406 | } | 453 | } |
407 | } | 454 | } |
408 | /* Find out local IP peer connected to. | 455 | if (verbose) { |
409 | * Errors ignored (I'm not paranoid enough to imagine kernel | 456 | pid = getpid(); |
410 | * which doesn't know local IP). */ | 457 | if (max_per_host) { |
411 | if (tcp) { | 458 | bb_error_msg("concurrency %s %u/%u", |
412 | local.len = sa_len; | 459 | remote_addr, |
413 | getsockname(0, &local.u.sa, &local.len); | 460 | cur_per_host, max_per_host); |
414 | } | 461 | } |
415 | local_addr = xmalloc_sockaddr2dotted(&local.u.sa); | 462 | bb_error_msg((option_mask32 & OPT_h) |
416 | if (!local_hostname) { | 463 | ? "start %u %s-%s (%s-%s)" |
417 | local_hostname = xmalloc_sockaddr2host_noport(&local.u.sa); | 464 | : "start %u %s-%s", |
418 | if (!local_hostname) | 465 | pid, |
419 | bb_error_msg_and_die("warning: cannot look up hostname for %s"+9, local_addr); | 466 | local_addr, remote_addr, |
467 | local_hostname, remote_hostname); | ||
420 | } | 468 | } |
421 | } | ||
422 | 469 | ||
423 | if (verbose) { | 470 | if (!(option_mask32 & OPT_E)) { |
424 | pid = getpid(); | 471 | /* setup ucspi env */ |
425 | printf("%s: info: pid %u from %s\n", applet_name, pid, remote_addr); | 472 | const char *proto = tcp ? "TCP" : "UDP"; |
426 | if (max_per_host) | 473 | |
427 | printf("%s: info: concurrency %u %s %u/%u\n", | 474 | /* Extract "original" destination addr:port |
428 | applet_name, pid, remote_ip, cur_per_host, max_per_host); | 475 | * from Linux firewall. Useful when you redirect |
429 | printf("%s: info: start %u %s:%s :%s:%s\n", | 476 | * an outbond connection to local handler, and it needs |
430 | applet_name, pid, | 477 | * to know where it originally tried to connect */ |
431 | local_hostname, local_addr, | 478 | if (tcp && getsockopt(0, SOL_IP, SO_ORIGINAL_DST, &local.u.sa, &local.len) == 0) { |
432 | remote_hostname, remote_addr); | 479 | char *addr = xmalloc_sockaddr2dotted(&local.u.sa); |
433 | } | 480 | xsetenv_plain("TCPORIGDSTADDR", addr); |
434 | 481 | free(addr); | |
435 | if (!(option_mask32 & OPT_E)) { | 482 | } |
436 | /* setup ucspi env */ | 483 | xsetenv_plain("PROTO", proto); |
437 | const char *proto = tcp ? "TCP" : "UDP"; | 484 | xsetenv_proto(proto, "LOCALADDR", local_addr); |
438 | 485 | xsetenv_proto(proto, "REMOTEADDR", remote_addr); | |
439 | /* Extract "original" destination addr:port | 486 | if (option_mask32 & OPT_h) { |
440 | * from Linux firewall. Useful when you redirect | 487 | xsetenv_proto(proto, "LOCALHOST", local_hostname); |
441 | * an outbond connection to local handler, and it needs | 488 | xsetenv_proto(proto, "REMOTEHOST", remote_hostname); |
442 | * to know where it originally tried to connect */ | 489 | } |
443 | if (tcp && getsockopt(0, SOL_IP, SO_ORIGINAL_DST, &lsa->u.sa, &lsa->len) == 0) { | 490 | //compat? xsetenv_proto(proto, "REMOTEINFO", ""); |
444 | char *addr = xmalloc_sockaddr2dotted(&lsa->u.sa); | 491 | /* additional */ |
445 | xsetenv("TCPORIGDSTADDR", addr); | 492 | if (cur_per_host > 0) /* can not be true for udp */ |
446 | free(addr); | 493 | xsetenv_plain("TCPCONCURRENCY", utoa(cur_per_host)); |
447 | } | ||
448 | xsetenv("PROTO", proto); | ||
449 | xsetenv_proto(proto, "LOCALADDR", local_addr); | ||
450 | xsetenv_proto(proto, "LOCALHOST", local_hostname); | ||
451 | xsetenv_proto(proto, "REMOTEADDR", remote_addr); | ||
452 | if (option_mask32 & OPT_h) { | ||
453 | xsetenv_proto(proto, "REMOTEHOST", remote_hostname); | ||
454 | } | 494 | } |
455 | xsetenv_proto(proto, "REMOTEINFO", ""); | 495 | free(local_addr); |
456 | /* additional */ | 496 | free(free_me0); |
457 | if (cur_per_host > 0) /* can not be true for udp */ | 497 | free(free_me1); |
458 | xsetenv("TCPCONCURRENCY", utoa(cur_per_host)); | 498 | free(free_me2); |
459 | } | 499 | } |
460 | 500 | ||
461 | dup2(0, 1); | 501 | xdup2(0, 1); |
462 | 502 | ||
463 | signal(SIGTERM, SIG_DFL); | 503 | signal(SIGTERM, SIG_DFL); |
464 | signal(SIGPIPE, SIG_DFL); | 504 | signal(SIGPIPE, SIG_DFL); |
465 | signal(SIGCHLD, SIG_DFL); | 505 | signal(SIGCHLD, SIG_DFL); |
466 | sig_unblock(SIGCHLD); | 506 | sig_unblock(SIGCHLD); |
467 | 507 | ||
468 | argv += 2; | ||
469 | #ifdef SSLSVD | 508 | #ifdef SSLSVD |
470 | strcpy(id, utoa(pid)); | 509 | strcpy(id, utoa(pid)); |
471 | ssl_io(0, argv); | 510 | ssl_io(0, argv); |