Sat Jun 10 06:30:07 2017 UTC ()
Pull up following revision(s) (requested by manu in ticket #27):
	external/bsd/dhcp/dist/relay/dhcrelay.c: revision 1.7
Fix buggy dhcrelay(8) requirement to stay in foreground
This version of dhcrelay(8) needed to stay inforeground with -d flag in
order to service requests. Running inbackground turned it deaf to DHCP
requests.
This was caused by wrong kqueue(2) usage, where kevent(2) was used with
a file descriptor obtained by a kqueue(2) call done before fork(2).
kqueue(2) man page says "The queue is not inherited by a child created
with fork(2)". As a result, kevent(2) calls always got EBADF.
The fix is to reorder function calls in dhcrelay(8) main() function.
dhcp_context_create(), which causes kqueue(2) to be invoked, is
moved with its dependencies after fork(2). This matches the code layout
of dhclient(8) and dhcpd(8), which do not have the bug.
The fix was not submitted upstream since latest ISC DHCP code was
refactored and does not have the bug anymore.


(snj)
diff -r1.6 -r1.6.8.1 src/external/bsd/dhcp/dist/relay/dhcrelay.c

cvs diff -r1.6 -r1.6.8.1 src/external/bsd/dhcp/dist/relay/Attic/dhcrelay.c (expand / switch to unified diff)

--- src/external/bsd/dhcp/dist/relay/Attic/dhcrelay.c 2016/01/10 20:10:45 1.6
+++ src/external/bsd/dhcp/dist/relay/Attic/dhcrelay.c 2017/06/10 06:30:07 1.6.8.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: dhcrelay.c,v 1.6 2016/01/10 20:10:45 christos Exp $ */ 1/* $NetBSD: dhcrelay.c,v 1.6.8.1 2017/06/10 06:30:07 snj Exp $ */
2/* dhcrelay.c 2/* dhcrelay.c
3 3
4 DHCP/BOOTP Relay Agent. */ 4 DHCP/BOOTP Relay Agent. */
5 5
6/* 6/*
7 * Copyright(c) 2004-2015 by Internet Systems Consortium, Inc.("ISC") 7 * Copyright(c) 2004-2015 by Internet Systems Consortium, Inc.("ISC")
8 * Copyright(c) 1997-2003 by Internet Software Consortium 8 * Copyright(c) 1997-2003 by Internet Software Consortium
9 * 9 *
10 * Permission to use, copy, modify, and distribute this software for any 10 * Permission to use, copy, modify, and distribute this software for any
11 * purpose with or without fee is hereby granted, provided that the above 11 * purpose with or without fee is hereby granted, provided that the above
12 * copyright notice and this permission notice appear in all copies. 12 * copyright notice and this permission notice appear in all copies.
13 * 13 *
14 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 14 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
@@ -18,27 +18,27 @@ @@ -18,27 +18,27 @@
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 19 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
20 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 * 21 *
22 * Internet Systems Consortium, Inc. 22 * Internet Systems Consortium, Inc.
23 * 950 Charter Street 23 * 950 Charter Street
24 * Redwood City, CA 94063 24 * Redwood City, CA 94063
25 * <info@isc.org> 25 * <info@isc.org>
26 * https://www.isc.org/ 26 * https://www.isc.org/
27 * 27 *
28 */ 28 */
29 29
30#include <sys/cdefs.h> 30#include <sys/cdefs.h>
31__RCSID("$NetBSD: dhcrelay.c,v 1.6 2016/01/10 20:10:45 christos Exp $"); 31__RCSID("$NetBSD: dhcrelay.c,v 1.6.8.1 2017/06/10 06:30:07 snj Exp $");
32 32
33#include "dhcpd.h" 33#include "dhcpd.h"
34#include <syslog.h> 34#include <syslog.h>
35#include <signal.h> 35#include <signal.h>
36#include <sys/time.h> 36#include <sys/time.h>
37 37
38TIME default_lease_time = 43200; /* 12 hours... */ 38TIME default_lease_time = 43200; /* 12 hours... */
39TIME max_lease_time = 86400; /* 24 hours... */ 39TIME max_lease_time = 86400; /* 24 hours... */
40struct tree_cache *global_options[256]; 40struct tree_cache *global_options[256];
41 41
42struct option *requested_opts[2]; 42struct option *requested_opts[2];
43 43
44/* Needed to prevent linking against conflex.c. */ 44/* Needed to prevent linking against conflex.c. */
@@ -197,33 +197,26 @@ main(int argc, char **argv) { @@ -197,33 +197,26 @@ main(int argc, char **argv) {
197 if (fd == 1) 197 if (fd == 1)
198 fd = open("/dev/null", O_RDWR); 198 fd = open("/dev/null", O_RDWR);
199 if (fd == 2) 199 if (fd == 2)
200 log_perror = 0; /* No sense logging to /dev/null. */ 200 log_perror = 0; /* No sense logging to /dev/null. */
201 else if (fd != -1) 201 else if (fd != -1)
202 close(fd); 202 close(fd);
203 203
204 openlog("dhcrelay", DHCP_LOG_OPTIONS, LOG_DAEMON); 204 openlog("dhcrelay", DHCP_LOG_OPTIONS, LOG_DAEMON);
205 205
206#if !defined(DEBUG) 206#if !defined(DEBUG)
207 setlogmask(LOG_UPTO(LOG_INFO)); 207 setlogmask(LOG_UPTO(LOG_INFO));
208#endif  208#endif
209 209
210 /* Set up the isc and dns library managers */ 
211 status = dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB, 
212 NULL, NULL); 
213 if (status != ISC_R_SUCCESS) 
214 log_fatal("Can't initialize context: %s", 
215 isc_result_totext(status)); 
216 
217 /* Set up the OMAPI. */ 210 /* Set up the OMAPI. */
218 status = omapi_init(); 211 status = omapi_init();
219 if (status != ISC_R_SUCCESS) 212 if (status != ISC_R_SUCCESS)
220 log_fatal("Can't initialize OMAPI: %s", 213 log_fatal("Can't initialize OMAPI: %s",
221 isc_result_totext(status)); 214 isc_result_totext(status));
222 215
223 /* Set up the OMAPI wrappers for the interface object. */ 216 /* Set up the OMAPI wrappers for the interface object. */
224 interface_setup(); 217 interface_setup();
225 218
226 for (i = 1; i < argc; i++) { 219 for (i = 1; i < argc; i++) {
227 if (!strcmp(argv[i], "-4")) { 220 if (!strcmp(argv[i], "-4")) {
228#ifdef DHCPv6 221#ifdef DHCPv6
229 if (local_family_set && (local_family == AF_INET6)) { 222 if (local_family_set && (local_family == AF_INET6)) {
@@ -526,37 +519,26 @@ main(int argc, char **argv) { @@ -526,37 +519,26 @@ main(int argc, char **argv) {
526 dhcpv6_universe.code_hash, 519 dhcpv6_universe.code_hash,
527 &code, 0, MDL)) 520 &code, 0, MDL))
528 log_fatal("Unable to find the RELAY_MSG " 521 log_fatal("Unable to find the RELAY_MSG "
529 "option definition."); 522 "option definition.");
530 code = D6O_INTERFACE_ID; 523 code = D6O_INTERFACE_ID;
531 if (!option_code_hash_lookup(&requested_opts[1], 524 if (!option_code_hash_lookup(&requested_opts[1],
532 dhcpv6_universe.code_hash, 525 dhcpv6_universe.code_hash,
533 &code, 0, MDL)) 526 &code, 0, MDL))
534 log_fatal("Unable to find the INTERFACE_ID " 527 log_fatal("Unable to find the INTERFACE_ID "
535 "option definition."); 528 "option definition.");
536 } 529 }
537#endif 530#endif
538 531
539 /* Get the current time... */ 
540 gettimeofday(&cur_tv, NULL); 
541 
542 /* Discover all the network interfaces. */ 
543 discover_interfaces(DISCOVER_RELAY); 
544 
545#ifdef DHCPv6 
546 if (local_family == AF_INET6) 
547 setup_streams(); 
548#endif 
549 
550 /* Become a daemon... */ 532 /* Become a daemon... */
551 if (!no_daemon) { 533 if (!no_daemon) {
552 int pid; 534 int pid;
553 FILE *pf; 535 FILE *pf;
554 int pfdesc; 536 int pfdesc;
555 537
556 log_perror = 0; 538 log_perror = 0;
557 539
558 if ((pid = fork()) < 0) 540 if ((pid = fork()) < 0)
559 log_fatal("Can't fork daemon: %m"); 541 log_fatal("Can't fork daemon: %m");
560 else if (pid) 542 else if (pid)
561 exit(0); 543 exit(0);
562 544
@@ -577,26 +559,44 @@ main(int argc, char **argv) { @@ -577,26 +559,44 @@ main(int argc, char **argv) {
577 fclose(pf); 559 fclose(pf);
578 }  560 }
579 } 561 }
580 } 562 }
581 563
582 (void) close(0); 564 (void) close(0);
583 (void) close(1); 565 (void) close(1);
584 (void) close(2); 566 (void) close(2);
585 (void) setsid(); 567 (void) setsid();
586 568
587 IGNORE_RET (chdir("/")); 569 IGNORE_RET (chdir("/"));
588 } 570 }
589 571
 572 /* Set up the isc and dns library managers */
 573 status = dhcp_context_create(DHCP_CONTEXT_PRE_DB | DHCP_CONTEXT_POST_DB,
 574 NULL, NULL);
 575 if (status != ISC_R_SUCCESS)
 576 log_fatal("Can't initialize context: %s",
 577 isc_result_totext(status));
 578
 579 /* Get the current time... */
 580 gettimeofday(&cur_tv, NULL);
 581
 582 /* Discover all the network interfaces. */
 583 discover_interfaces(DISCOVER_RELAY);
 584
 585#ifdef DHCPv6
 586 if (local_family == AF_INET6)
 587 setup_streams();
 588#endif
 589
590 /* Set up the packet handler... */ 590 /* Set up the packet handler... */
591 if (local_family == AF_INET) 591 if (local_family == AF_INET)
592 bootp_packet_handler = do_relay4; 592 bootp_packet_handler = do_relay4;
593#ifdef DHCPv6 593#ifdef DHCPv6
594 else 594 else
595 dhcpv6_packet_handler = do_packet6; 595 dhcpv6_packet_handler = do_packet6;
596#endif 596#endif
597 597
598#if defined(ENABLE_GENTLE_SHUTDOWN) 598#if defined(ENABLE_GENTLE_SHUTDOWN)
599 /* no signal handlers until we deal with the side effects */ 599 /* no signal handlers until we deal with the side effects */
600 /* install signal handlers */ 600 /* install signal handlers */
601 signal(SIGINT, dhcp_signal_handler); /* control-c */ 601 signal(SIGINT, dhcp_signal_handler); /* control-c */
602 signal(SIGTERM, dhcp_signal_handler); /* kill */ 602 signal(SIGTERM, dhcp_signal_handler); /* kill */
@@ -938,27 +938,27 @@ find_interface_by_agent_option(struct dh @@ -938,27 +938,27 @@ find_interface_by_agent_option(struct dh
938 938
939 /* If we didn't get a match, the circuit ID was bogus. */ 939 /* If we didn't get a match, the circuit ID was bogus. */
940 ++bad_circuit_id; 940 ++bad_circuit_id;
941 return (-1); 941 return (-1);
942} 942}
943 943
944/* 944/*
945 * Examine a packet to see if it's a candidate to have a Relay 945 * Examine a packet to see if it's a candidate to have a Relay
946 * Agent Information option tacked onto its tail. If it is, tack 946 * Agent Information option tacked onto its tail. If it is, tack
947 * the option on. 947 * the option on.
948 */ 948 */
949 949
950#include <sys/cdefs.h> 950#include <sys/cdefs.h>
951__RCSID("$NetBSD: dhcrelay.c,v 1.6 2016/01/10 20:10:45 christos Exp $"); 951__RCSID("$NetBSD: dhcrelay.c,v 1.6.8.1 2017/06/10 06:30:07 snj Exp $");
952static int 952static int
953add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet, 953add_relay_agent_options(struct interface_info *ip, struct dhcp_packet *packet,
954 unsigned length, struct in_addr giaddr) { 954 unsigned length, struct in_addr giaddr) {
955 int is_dhcp = 0, mms; 955 int is_dhcp = 0, mms;
956 unsigned optlen; 956 unsigned optlen;
957 u_int8_t *op, *nextop, *sp, *max, *end_pad = NULL; 957 u_int8_t *op, *nextop, *sp, *max, *end_pad = NULL;
958 958
959 /* If we're not adding agent options to packets, we can skip 959 /* If we're not adding agent options to packets, we can skip
960 this. */ 960 this. */
961 if (!add_agent_options) 961 if (!add_agent_options)
962 return (length); 962 return (length);
963 963
964 /* If there's no cookie, it's a bootp packet, so we should just 964 /* If there's no cookie, it's a bootp packet, so we should just