back out the previous ICMP simplifying diff, it caused livelocks.
authorpelikan <pelikan@openbsd.org>
Wed, 7 May 2014 13:20:47 +0000 (13:20 +0000)
committerpelikan <pelikan@openbsd.org>
Wed, 7 May 2014 13:20:47 +0000 (13:20 +0000)
reported by Mikolaj Kucharski, thanks!
ok krw

usr.sbin/dhcpd/dhcpd.c
usr.sbin/dhcpd/dhcpd.h
usr.sbin/dhcpd/icmp.c

index 8d1cb68..046504f 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dhcpd.c,v 1.43 2014/05/05 18:30:44 pelikan Exp $ */
+/*     $OpenBSD: dhcpd.c,v 1.44 2014/05/07 13:20:47 pelikan Exp $ */
 
 /*
  * Copyright (c) 2004 Henning Brauer <henning@cvs.openbsd.org>
@@ -175,7 +175,7 @@ main(int argc, char *argv[])
                if (setrtable(rdomain) == -1)
                        error("setrtable (%m)");
 
-       icmp_startup();
+       icmp_startup(1, lease_pinged);
 
        if (syncsend || syncrecv) {
                syncfd = sync_init(sync_iface, sync_baddr, sync_port);
index d19a0d6..03b367b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: dhcpd.h,v 1.49 2014/05/05 18:30:44 pelikan Exp $ */
+/*     $OpenBSD: dhcpd.h,v 1.50 2014/05/07 13:20:47 pelikan Exp $ */
 
 /*
  * Copyright (c) 1995, 1996, 1997, 1998, 1999
@@ -685,9 +685,9 @@ u_int32_t   checksum(unsigned char *, unsigned, u_int32_t);
 u_int32_t      wrapsum(u_int32_t);
 
 /* icmp.c */
-void   icmp_startup(void);
-int    icmp_echorequest(struct iaddr *);
-void   icmp_echoreply(struct protocol *);
+void icmp_startup(int, void (*)(struct iaddr, u_int8_t *, int));
+int icmp_echorequest(struct iaddr *);
+void icmp_echoreply(struct protocol *);
 
 /* pfutils.c */
 __dead void pftable_handler(void);
index 7f7a361..5673631 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: icmp.c,v 1.11 2014/05/05 18:27:57 pelikan Exp $ */
+/*     $OpenBSD: icmp.c,v 1.12 2014/05/07 13:20:47 pelikan Exp $ */
 
 /*
  * Copyright (c) 1997, 1998 The Internet Software Consortium.
@@ -49,7 +49,7 @@ static int icmp_protocol_fd;
 /* Initialize the ICMP protocol. */
 
 void
-icmp_startup(void)
+icmp_startup(int routep, void (*handler)(struct iaddr, u_int8_t *, int))
 {
        struct protoent *proto;
        int protocol = 1, state;
@@ -73,7 +73,7 @@ icmp_startup(void)
            &state, sizeof(state)) == -1)
                error("Unable to disable SO_DONTROUTE on ICMP socket: %m");
 
-       add_protocol("icmp", icmp_protocol_fd, icmp_echoreply, NULL);
+       add_protocol("icmp", icmp_protocol_fd, icmp_echoreply, (void *)handler);
 }
 
 int
@@ -114,6 +114,7 @@ icmp_echorequest(struct iaddr *addr)
 void
 icmp_echoreply(struct protocol *protocol)
 {
+       void (*handler)(struct iaddr, u_int8_t *, int);
        struct sockaddr_in from;
        u_int8_t icbuf[1500];
        struct icmp *icfrom;
@@ -140,7 +141,12 @@ icmp_echoreply(struct protocol *protocol)
        if (icfrom->icmp_type != ICMP_ECHOREPLY)
                return;
 
-       memcpy(ia.iabuf, &from.sin_addr, sizeof from.sin_addr);
-       ia.len = sizeof from.sin_addr;
-       lease_pinged(ia, icbuf, len);
+       /* If we were given a second-stage handler, call it. */
+       if (protocol->local) {
+               handler = ((void (*)(struct iaddr, u_int8_t *, int))
+                   protocol->local);
+               memcpy(ia.iabuf, &from.sin_addr, sizeof from.sin_addr);
+               ia.len = sizeof from.sin_addr;
+               (*handler)(ia, icbuf, len);
+       }
 }