From 0d43d2fcb7ac5264c739dc2f67f93ed0985a418a Mon Sep 17 00:00:00 2001
From: Tom Gundersen <teg@jklm.no>
Date: Tue, 24 Nov 2015 18:25:52 +0100
Subject: [PATCH] libsystemd-network: clean up recv functions

---
 src/libsystemd-network/sd-dhcp-client.c  | 43 ++++++++++++++++----------------
 src/libsystemd-network/sd-dhcp-server.c  | 13 ++++++----
 src/libsystemd-network/sd-dhcp6-client.c | 22 ++++++++++------
 src/libsystemd-network/sd-ndisc.c        | 12 ++++++---
 4 files changed, 54 insertions(+), 36 deletions(-)

diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c
index 5ec0e66..66b8f10 100644
--- a/src/libsystemd-network/sd-dhcp-client.c
+++ b/src/libsystemd-network/sd-dhcp-client.c
@@ -1513,9 +1513,8 @@ static int client_receive_message_udp(sd_event_source *s, int fd,
 
         r = ioctl(fd, FIONREAD, &buflen);
         if (r < 0)
-                return r;
-
-        if (buflen < 0)
+                return -errno;
+        else if (buflen < 0)
                 /* this can't be right */
                 return -EIO;
 
@@ -1525,26 +1524,28 @@ static int client_receive_message_udp(sd_event_source *s, int fd,
 
         len = read(fd, message, buflen);
         if (len < 0) {
-                log_dhcp_client(client, "could not receive message from UDP "
-                                "socket: %m");
-                return 0;
+                if (errno == EAGAIN || errno == EINTR)
+                        return 0;
+
+                log_dhcp_client(client, "Could not receive message from UDP socket: %m");
+                return -errno;
         } else if ((size_t)len < sizeof(DHCPMessage)) {
-                log_dhcp_client(client, "too small to be a DHCP message: ignoring");
+                log_dhcp_client(client, "Too small to be a DHCP message: ignoring");
                 return 0;
         }
 
         if (be32toh(message->magic) != DHCP_MAGIC_COOKIE) {
-                log_dhcp_client(client, "not a DHCP message: ignoring");
+                log_dhcp_client(client, "Not a DHCP message: ignoring");
                 return 0;
         }
 
         if (message->op != BOOTREPLY) {
-                log_dhcp_client(client, "not a BOOTREPLY message: ignoring");
+                log_dhcp_client(client, "Not a BOOTREPLY message: ignoring");
                 return 0;
         }
 
         if (message->htype != client->arp_type) {
-                log_dhcp_client(client, "packet type does not match client type");
+                log_dhcp_client(client, "Packet type does not match client type");
                 return 0;
         }
 
@@ -1558,13 +1559,12 @@ static int client_receive_message_udp(sd_event_source *s, int fd,
         }
 
         if (message->hlen != expected_hlen) {
-                log_dhcp_client(client, "unexpected packet hlen %d", message->hlen);
+                log_dhcp_client(client, "Unexpected packet hlen %d", message->hlen);
                 return 0;
         }
 
         if (memcmp(&message->chaddr[0], expected_chaddr, ETH_ALEN)) {
-                log_dhcp_client(client, "received chaddr does not match "
-                                "expected: ignoring");
+                log_dhcp_client(client, "Received chaddr does not match expected: ignoring");
                 return 0;
         }
 
@@ -1572,8 +1572,7 @@ static int client_receive_message_udp(sd_event_source *s, int fd,
             be32toh(message->xid) != client->xid) {
                 /* in BOUND state, we may receive FORCERENEW with xid set by server,
                    so ignore the xid in this case */
-                log_dhcp_client(client, "received xid (%u) does not match "
-                                "expected (%u): ignoring",
+                log_dhcp_client(client, "Received xid (%u) does not match expected (%u): ignoring",
                                 be32toh(message->xid), client->xid);
                 return 0;
         }
@@ -1602,9 +1601,8 @@ static int client_receive_message_raw(sd_event_source *s, int fd,
 
         r = ioctl(fd, FIONREAD, &buflen);
         if (r < 0)
-                return r;
-
-        if (buflen < 0)
+                return -errno;
+        else if (buflen < 0)
                 /* this can't be right */
                 return -EIO;
 
@@ -1617,9 +1615,12 @@ static int client_receive_message_raw(sd_event_source *s, int fd,
 
         len = recvmsg(fd, &msg, 0);
         if (len < 0) {
-                log_dhcp_client(client, "could not receive message from raw "
-                                "socket: %m");
-                return 0;
+                if (errno == EAGAIN || errno == EINTR)
+                        return 0;
+
+                log_dhcp_client(client, "Could not receive message from raw socket: %m");
+
+                return -errno;
         } else if ((size_t)len < sizeof(DHCPPacket))
                 return 0;
 
diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c
index 277c88e..3e2ecda 100644
--- a/src/libsystemd-network/sd-dhcp-server.c
+++ b/src/libsystemd-network/sd-dhcp-server.c
@@ -963,10 +963,10 @@ static int server_receive_message(sd_event_source *s, int fd,
 
         if (ioctl(fd, FIONREAD, &buflen) < 0)
                 return -errno;
-        if (buflen < 0)
+        else if (buflen < 0)
                 return -EIO;
 
-        message = malloc0(buflen);
+        message = malloc(buflen);
         if (!message)
                 return -ENOMEM;
 
@@ -974,9 +974,12 @@ static int server_receive_message(sd_event_source *s, int fd,
         iov.iov_len = buflen;
 
         len = recvmsg(fd, &msg, 0);
-        if (len < buflen)
-                return 0;
-        else if ((size_t)len < sizeof(DHCPMessage))
+        if (len < 0) {
+                if (errno == EAGAIN || errno == EINTR)
+                        return 0;
+
+                return -errno;
+        } else if ((size_t)len < sizeof(DHCPMessage))
                 return 0;
 
         CMSG_FOREACH(cmsg, &msg) {
diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c
index 801331d..36d909a 100644
--- a/src/libsystemd-network/sd-dhcp6-client.c
+++ b/src/libsystemd-network/sd-dhcp6-client.c
@@ -895,7 +895,7 @@ static int client_receive_advertise(sd_dhcp6_client *client, DHCP6Message *adver
 static int client_receive_message(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
         sd_dhcp6_client *client = userdata;
         DHCP6_CLIENT_DONT_DESTROY(client);
-        _cleanup_free_ DHCP6Message *message;
+        _cleanup_free_ DHCP6Message *message = NULL;
         int r, buflen, len;
 
         assert(s);
@@ -903,18 +903,26 @@ static int client_receive_message(sd_event_source *s, int fd, uint32_t revents,
         assert(client->event);
 
         r = ioctl(fd, FIONREAD, &buflen);
-        if (r < 0 || buflen <= 0)
-                buflen = DHCP6_MIN_OPTIONS_SIZE;
+        if (r < 0)
+                return -errno;
+        else if (buflen < 0)
+                /* This really should not happen */
+                return -EIO;
 
-        message = malloc0(buflen);
+        message = malloc(buflen);
         if (!message)
                 return -ENOMEM;
 
         len = read(fd, message, buflen);
-        if ((size_t)len < sizeof(DHCP6Message)) {
-                log_dhcp6_client(client, "could not receive message from UDP socket: %m");
+        if (len < 0) {
+                if (errno == EAGAIN || errno == EINTR)
+                        return 0;
+
+                log_dhcp6_client(client, "Could not receive message from UDP socket: %m");
+
+                return -errno;
+        } else if ((size_t)len < sizeof(DHCP6Message))
                 return 0;
-        }
 
         switch(message->type) {
         case DHCP6_SOLICIT: