diff options
| author | Andreas Schneider <asn@samba.org> | 2014-05-20 20:04:02 +0200 |
|---|---|---|
| committer | Michael Adam <obnox@samba.org> | 2014-05-31 12:32:09 +0200 |
| commit | ccf4e64fe7bf788c17ca1a41e456e3b9ecdcb85b (patch) | |
| tree | 54c3f33d0aaa03a4b17fff1cd12a9670bbbad838 | |
| parent | b124fcb2dfb6193f198bd47891c3286e527bd530 (diff) | |
| download | socket_wrapper-ccf4e64fe7bf788c17ca1a41e456e3b9ecdcb85b.tar.gz socket_wrapper-ccf4e64fe7bf788c17ca1a41e456e3b9ecdcb85b.tar.xz socket_wrapper-ccf4e64fe7bf788c17ca1a41e456e3b9ecdcb85b.zip | |
swrap: Add support for bindresvport().
Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Michael Adam <obnox@samba.org>
| -rw-r--r-- | ConfigureChecks.cmake | 4 | ||||
| -rw-r--r-- | config.h.cmake | 1 | ||||
| -rw-r--r-- | src/socket_wrapper.c | 87 |
3 files changed, 92 insertions, 0 deletions
diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake index 3a31f50..44914f0 100644 --- a/ConfigureChecks.cmake +++ b/ConfigureChecks.cmake @@ -60,6 +60,10 @@ check_function_exists(snprintf HAVE_SNPRINTF) check_function_exists(signalfd HAVE_SIGNALFD) check_function_exists(eventfd HAVE_EVENTFD) check_function_exists(timerfd_create HAVE_TIMERFD_CREATE) +set(CMAKE_REQUIRED_FLAGS -D_GNU_SOURCE) +check_function_exists(bindresvport HAVE_BINDRESVPORT) +set(CMAKE_REQUIRED_FLAGS) + if (UNIX) if (NOT LINUX) diff --git a/config.h.cmake b/config.h.cmake index 02c016e..b5dd8c9 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -37,6 +37,7 @@ #cmakedefine HAVE_SIGNALFD 1 #cmakedefine HAVE_EVENTFD 1 #cmakedefine HAVE_TIMERFD_CREATE 1 +#cmakedefine HAVE_BINDRESVPORT 1 #cmakedefine HAVE_ACCEPT_PSOCKLEN_T 1 #cmakedefine HAVE_IOCTL_INT 1 diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c index 5bedfa7..bf84dbe 100644 --- a/src/socket_wrapper.c +++ b/src/socket_wrapper.c @@ -111,6 +111,13 @@ enum swrap_dbglvl_e { #define ZERO_STRUCT(x) memset((char *)&(x), 0, sizeof(x)) #endif +#ifndef ZERO_STRUCTP +#define ZERO_STRUCTP(x) do { \ + if ((x) != NULL) \ + memset((char *)(x), 0, sizeof(*(x))); \ + } while(0) +#endif + #ifndef discard_const #define discard_const(ptr) ((void *)((uintptr_t)(ptr))) #endif @@ -2753,6 +2760,86 @@ int bind(int s, const struct sockaddr *myaddr, socklen_t addrlen) } /**************************************************************************** + * BINDRESVPORT + ***************************************************************************/ + +#ifdef HAVE_BINDRESVPORT +static int swrap_getsockname(int s, struct sockaddr *name, socklen_t *addrlen); + +static int swrap_bindresvport_sa(int sd, struct sockaddr *sa) +{ + struct sockaddr_storage myaddr; + socklen_t salen; + static uint16_t port; + uint16_t i; + int rc = -1; + int af; + +#define SWRAP_STARTPORT 600 +#define SWRAP_ENDPORT (IPPORT_RESERVED - 1) +#define SWRAP_NPORTS (SWRAP_ENDPORT - SWRAP_STARTPORT + 1) + + if (port == 0) { + port = (getpid() % SWRAP_NPORTS) + SWRAP_STARTPORT; + } + + if (sa == NULL) { + salen = sizeof(struct sockaddr); + sa = (struct sockaddr *)&myaddr; + + rc = swrap_getsockname(sd, (struct sockaddr *)&myaddr, &salen); + if (rc < 0) { + return -1; + } + + af = sa->sa_family; + memset(&myaddr, 0, salen); + } else { + af = sa->sa_family; + } + + for (i = 0; i < SWRAP_NPORTS; i++, port++) { + switch(af) { + case AF_INET: { + struct sockaddr_in *sinp = (struct sockaddr_in *)sa; + + salen = sizeof(struct sockaddr_in); + sinp->sin_port = htons(port); + break; + } + case AF_INET6: { + struct sockaddr_in6 *sin6p = (struct sockaddr_in6 *)sa; + + salen = sizeof(struct sockaddr_in6); + sin6p->sin6_port = htons(port); + break; + } + default: + errno = EAFNOSUPPORT; + return -1; + } + sa->sa_family = af; + + if (port > SWRAP_ENDPORT) { + port = SWRAP_STARTPORT; + } + + rc = swrap_bind(sd, (struct sockaddr *)sa, salen); + if (rc == 0 || errno != EADDRINUSE) { + break; + } + } + + return rc; +} + +int bindresvport(int sockfd, struct sockaddr_in *sinp) +{ + return swrap_bindresvport_sa(sockfd, (struct sockaddr *)sinp); +} +#endif + +/**************************************************************************** * LISTEN ***************************************************************************/ |
