1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

swrap: Add support for bindresvport().

Signed-off-by: Andreas Schneider <asn@samba.org>
Reviewed-by: Michael Adam <obnox@samba.org>
This commit is contained in:
Andreas Schneider 2014-06-03 15:10:19 +02:00 committed by Michael Adam
parent 1b949b5d6c
commit 6e6c817fd0
2 changed files with 88 additions and 0 deletions

View File

@ -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
@ -2752,6 +2759,86 @@ int bind(int s, const struct sockaddr *myaddr, socklen_t addrlen)
return swrap_bind(s, myaddr, 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
***************************************************************************/

View File

@ -60,6 +60,7 @@ def configure(conf):
conf.CHECK_FUNCS('getaddrinfo')
conf.CHECK_FUNCS('signalfd eventfd timerfd_create')
conf.CHECK_FUNCS('bindresvport')
conf.CHECK_FUNCS_IN('bind',
'socket',