dhcpcd-discuss

TESTREQ - MSG_TRUNC on Linux 2.6.21 or older

Roy Marples

Thu Jul 15 07:03:35 2010

Hi List

Attached is a patch to address netlink messagses > 256 bytes, which now
happens on new Linux kernels. I don't want to allocate an 8k buffer, so
trying to work out the size using MSG_PEEK | MSG_TRUNC. However, recv(2)
shows this only works on 2.6.22 kernels or newer.

So, can anyone apply this patch to dhcpcd-5.2.6 and test it on a 2.6.21
or older kernel and attach the output of dhcpcd -dB please?

Thanks

Roy
diff --git a/if-linux.c b/if-linux.c
index ab1bbe6..9856204 100644
--- a/if-linux.c
+++ b/if-linux.c
@@ -54,8 +54,6 @@
 #include "dhcp.h"
 #include "net.h"
 
-#define BUFFERLEN 256
-
 static int sock_fd;
 static struct sockaddr_nl sock_nl;
 
@@ -144,14 +142,33 @@ static int
 get_netlink(int fd, int flags,
     int (*callback)(struct nlmsghdr *))
 {
-	char *buffer = NULL;
-	ssize_t bytes;
+	char *buf = NULL, *nbuf;
+	ssize_t buflen = 0, bytes;
 	struct nlmsghdr *nlm;
 	int r = -1;
 
-	buffer = xzalloc(sizeof(char) * BUFFERLEN);
 	for (;;) {
-		bytes = recv(fd, buffer, BUFFERLEN, flags);
+		errno = 0;
+		bytes = recv(fd, NULL, 0,
+		    flags | MSG_PEEK | MSG_DONTWAIT | MSG_TRUNC);
+		printf ("recv test, bytes=%zd errno=%d\n", bytes, errno);
+		if (bytes == -1) {
+			if (errno == EAGAIN) {
+				r = 0;
+				goto eexit;
+			}
+			if (errno == EINTR)
+				continue;
+			goto eexit;
+		}
+		if (buflen < bytes) {
+			buflen = bytes;
+			nbuf = realloc(buf, buflen);
+			if (nbuf == NULL)
+				goto eexit;
+			buf = nbuf;
+		}
+		bytes = recv(fd, buf, buflen, flags);
 		if (bytes == -1) {
 			if (errno == EAGAIN) {
 				r = 0;
@@ -161,7 +178,7 @@ get_netlink(int fd, int flags,
 				continue;
 			goto eexit;
 		}
-		for (nlm = (struct nlmsghdr *)buffer;
+		for (nlm = (struct nlmsghdr *)buf;
 		     NLMSG_OK(nlm, (size_t)bytes);
 		     nlm = NLMSG_NEXT(nlm, bytes))
 		{
@@ -172,7 +189,7 @@ get_netlink(int fd, int flags,
 	}
 
 eexit:
-	free(buffer);
+	free(buf);
 	return r;
 }
 

Archive administrator: postmaster@marples.name