From 2f4516ba69e49b93de2f844c5e772112ff58a31e Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Mon, 10 Sep 2012 19:51:39 +0200 Subject: [PATCH] devip: fix addrlen in connect() and bind() On some systems, the third argument of connect() and bind() is expected to be the length of the address family instead of the length of the sockaddr structure. R=rsc http://codereview.appspot.com/6492074 --- kern/devip-posix.c | 18 +++++++++++++++--- kern/devip-win32.c | 18 +++++++++++++++--- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/kern/devip-posix.c b/kern/devip-posix.c index f16b230..cd78c6b 100644 --- a/kern/devip-posix.c +++ b/kern/devip-posix.c @@ -26,6 +26,18 @@ family(unsigned char *addr) return AF_INET6; } +static int +addrlen(struct sockaddr_storage *ss) +{ + switch(ss->ss_family){ + case AF_INET: + return sizeof(struct sockaddr_in); + case AF_INET6: + return sizeof(struct sockaddr_in6); + } + return 0; +} + void osipinit(void) { @@ -84,7 +96,7 @@ so_connect(int fd, unsigned char *raddr, unsigned short rport) break; } - if(connect(fd, (struct sockaddr*)&ss, sizeof(ss)) < 0) + if(connect(fd, (struct sockaddr*)&ss, addrlen(&ss)) < 0) oserror(); } @@ -172,7 +184,7 @@ so_bind(int fd, int su, unsigned short port, unsigned char *addr) break; } - if(bind(fd, (struct sockaddr*)&ss, sizeof(ss)) >= 0) + if(bind(fd, (struct sockaddr*)&ss, addrlen(&ss)) >= 0) return; } oserror(); @@ -190,7 +202,7 @@ so_bind(int fd, int su, unsigned short port, unsigned char *addr) break; } - if(bind(fd, (struct sockaddr*)&ss, sizeof(ss)) < 0) + if(bind(fd, (struct sockaddr*)&ss, addrlen(&ss)) < 0) oserror(); } diff --git a/kern/devip-win32.c b/kern/devip-win32.c index be97054..784b253 100644 --- a/kern/devip-win32.c +++ b/kern/devip-win32.c @@ -25,6 +25,18 @@ family(unsigned char *addr) return AF_INET6; } +static int +addrlen(struct sockaddr_storage *ss) +{ + switch(ss->ss_family){ + case AF_INET: + return sizeof(struct sockaddr_in); + case AF_INET6: + return sizeof(struct sockaddr_in6); + } + return 0; +} + void osipinit(void) { @@ -88,7 +100,7 @@ so_connect(int fd, unsigned char *raddr, unsigned short rport) break; } - if(connect(fd, (struct sockaddr*)&ss, sizeof(ss)) < 0) + if(connect(fd, (struct sockaddr*)&ss, addrlen(&ss)) < 0) oserror(); } @@ -176,7 +188,7 @@ so_bind(int fd, int su, unsigned short port, unsigned char *addr) break; } - if(bind(fd, (struct sockaddr*)&ss, sizeof(ss)) >= 0) + if(bind(fd, (struct sockaddr*)&ss, addrlen(&ss)) >= 0) return; } oserror(); @@ -194,7 +206,7 @@ so_bind(int fd, int su, unsigned short port, unsigned char *addr) break; } - if(bind(fd, (struct sockaddr*)&ss, sizeof(ss)) < 0) + if(bind(fd, (struct sockaddr*)&ss, addrlen(&ss)) < 0) oserror(); }