From 5114d70be6c52e2fb793b2f5ee4fe5871276804c Mon Sep 17 00:00:00 2001 From: Giel van Schijndel Date: Wed, 9 Jul 2014 22:15:57 +0200 Subject: [PATCH] unix connect/bind: compute addr size the same regardless of extra fields I.e. taking a Unix sockaddr's maximum size, subtracting the one variable field's max size and adding the size of that field's content gets us the actual size anytime. This gives us less duplication and only a single piece of code used across all Unices: i.e. the same code gets tested on all. In particular the current makefile, when used on FreeBSD (which *does* have the sun_len field, but appears to ignore its contents) the addr-length passed to connect() and bind() is one to small because the sun_len field's space is neglected in the previous size computation. This change removes the unnecessary dependency on the build system for the correctness of the addr length computation. Signed-off-by: Giel van Schijndel --- src/unix.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/src/unix.c b/src/unix.c index 91aaaf8..76104fb 100644 --- a/src/unix.c +++ b/src/unix.c @@ -191,20 +191,17 @@ static int meth_accept(lua_State *L) { static const char *unix_trybind(p_unix un, const char *path) { struct sockaddr_un local; size_t len = strlen(path); + size_t addrlen; int err; if (len >= sizeof(local.sun_path)) return "path too long"; memset(&local, 0, sizeof(local)); strcpy(local.sun_path, path); local.sun_family = AF_UNIX; + addrlen = sizeof(local) - sizeof(local.sun_path) + len; #ifdef UNIX_HAS_SUN_LEN - local.sun_len = sizeof(local.sun_family) + sizeof(local.sun_len) - + len + 1; - err = socket_bind(&un->sock, (SA *) &local, local.sun_len); - -#else - err = socket_bind(&un->sock, (SA *) &local, - sizeof(local.sun_family) + len); + local.sun_len = addrlen + 1; #endif + err = socket_bind(&un->sock, (SA *) &local, addrlen); if (err != IO_DONE) socket_destroy(&un->sock); return socket_strerror(err); } @@ -229,20 +226,18 @@ static const char *unix_tryconnect(p_unix un, const char *path) { struct sockaddr_un remote; int err; + size_t addrlen; size_t len = strlen(path); if (len >= sizeof(remote.sun_path)) return "path too long"; memset(&remote, 0, sizeof(remote)); strcpy(remote.sun_path, path); remote.sun_family = AF_UNIX; timeout_markstart(&un->tm); + addrlen = sizeof(remote) - sizeof(remote.sun_path) + len; #ifdef UNIX_HAS_SUN_LEN - remote.sun_len = sizeof(remote.sun_family) + sizeof(remote.sun_len) - + len + 1; - err = socket_connect(&un->sock, (SA *) &remote, remote.sun_len, &un->tm); -#else - err = socket_connect(&un->sock, (SA *) &remote, - sizeof(remote.sun_family) + len, &un->tm); + remote.sun_len = addrlen + 1; #endif + err = socket_connect(&un->sock, (SA *) &remote, addrlen, &un->tm); if (err != IO_DONE) socket_destroy(&un->sock); return socket_strerror(err); }