Workaround for reported recvmsg() ignoring MSG_PEEK.
diff --git a/src/dhcp-common.c b/src/dhcp-common.c
index ea449cb..eae9886 100644
--- a/src/dhcp-common.c
+++ b/src/dhcp-common.c
@@ -38,7 +38,7 @@
 
 ssize_t recv_dhcp_packet(int fd, struct msghdr *msg)
 {  
-  ssize_t sz;
+  ssize_t sz, new_sz;
  
   while (1)
     {
@@ -65,9 +65,18 @@
 	}
     }
   
-  while ((sz = recvmsg(fd, msg, 0)) == -1 && errno == EINTR);
+  while ((new_sz = recvmsg(fd, msg, 0)) == -1 && errno == EINTR);
+
+  /* Some kernels seem to ignore MSG_PEEK, and dequeue the packet anyway. 
+     If that happens we get EAGAIN here because the socket is non-blocking.
+     Use the result of the original testing recvmsg as long as the buffer
+     was big enough. There's a small race here that may lose the odd packet,
+     but it's UDP anyway. */
   
-  return (msg->msg_flags & MSG_TRUNC) ? -1 : sz;
+  if (new_sz == -1 && (errno == EWOULDBLOCK || errno == EAGAIN))
+    new_sz = sz;
+  
+  return (msg->msg_flags & MSG_TRUNC) ? -1 : new_sz;
 }
 
 struct dhcp_netid *run_tag_if(struct dhcp_netid *tags)