From cf447cb62d01137f4cbd1cd14b83b88823542bbf Mon Sep 17 00:00:00 2001 From: Tom Gundersen Date: Sat, 21 May 2016 23:00:32 +0200 Subject: [PATCH] libsystemd-network: use recv(..., 0) instead of read(...) (#3317) According to recv(2) these should be the same, but that is not true. Passing a buffer of length 0 to read is defined to be a noop according to read(2), but passing a buffer of length 0 to recv will discard the pending pacet. We can easily hit this as we allocate our buffer size depending on the size of the incoming packet (using FIONREAD). As pointed out in issue #3299 simply sending an empty UDP packet to the DHCP client port will trigger a busy loop in networkd as we are polling on the socket but never discarding the empty packet. This reverts ad5ae47a0d159ea473c9730d7e0298a3e5d31cf6 but fixes the same issue. --- src/libsystemd-network/sd-dhcp-client.c | 5 +---- src/libsystemd-network/sd-dhcp6-client.c | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 123169832c..ad79c6cc2c 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -1636,14 +1636,11 @@ static int client_receive_message_udp( if (buflen < 0) return buflen; - if (buflen == 0) - buflen = 1; - message = malloc0(buflen); if (!message) return -ENOMEM; - len = read(fd, message, buflen); + len = recv(fd, message, buflen, 0); if (len < 0) { if (errno == EAGAIN || errno == EINTR) return 0; diff --git a/src/libsystemd-network/sd-dhcp6-client.c b/src/libsystemd-network/sd-dhcp6-client.c index 0c296e39fa..05972e01c9 100644 --- a/src/libsystemd-network/sd-dhcp6-client.c +++ b/src/libsystemd-network/sd-dhcp6-client.c @@ -917,7 +917,7 @@ static int client_receive_message(sd_event_source *s, int fd, uint32_t revents, if (!message) return -ENOMEM; - len = read(fd, message, buflen); + len = recv(fd, message, buflen, 0); if (len < 0) { if (errno == EAGAIN || errno == EINTR) return 0;