From 46e3df937b05fa291470e975cd836c5435aa0ecc Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Wed, 11 May 2011 08:40:58 +0200 Subject: Implement accept4 system call. Signed-off-by: Thierry Reding Signed-off-by: Bernhard Reutner-Fischer --- libc/inet/accept.c | 1 + libc/inet/socketcalls.c | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) (limited to 'libc/inet') diff --git a/libc/inet/accept.c b/libc/inet/accept.c index 0217a6876..b0fd2b2c6 100644 --- a/libc/inet/accept.c +++ b/libc/inet/accept.c @@ -5,4 +5,5 @@ */ #define L_accept +#define L_accept4 #include "socketcalls.c" diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c index 42a5a563f..ff5fdaa30 100644 --- a/libc/inet/socketcalls.c +++ b/libc/inet/socketcalls.c @@ -31,6 +31,7 @@ extern int __socketcall(int call, unsigned long *args) attribute_hidden; #define SYS_GETSOCKOPT 15 #define SYS_SENDMSG 16 #define SYS_RECVMSG 17 +#define SYS_ACCEPT4 18 #endif #ifdef __UCLIBC_HAS_THREADS_NATIVE__ @@ -560,3 +561,20 @@ int socketpair(int family, int type, int protocol, int sockvec[2]) } #endif #endif + +#ifdef L_accept4 +#ifdef __NR_accept4 +_syscall4(int, accept4, int, sockfd, struct sockaddr *, addr, socklen_t *, addrlen, int, flags) +#elif defined(__NR_socketcall) +int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) +{ + unsigned long args[4]; + + args[0] = sockfd; + args[1] = (unsigned long) addr; + args[2] = (unsigned long) addrlen; + args[3] = flags; + return __socketcall(SYS_ACCEPT4, args); +} +#endif +#endif -- cgit v1.2.3 From 74a2c71153b910ee4773866ee30be84730a4d5b8 Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Wed, 11 May 2011 11:31:45 +0200 Subject: accept4: Implement cancellation .. and add proper prototype, move it into it's own obj and other such cleanups. Signed-off-by: Bernhard Reutner-Fischer --- libc/inet/Makefile.in | 6 ++++-- libc/inet/accept.c | 1 - libc/inet/accept4.c | 8 +++++++ libc/inet/socketcalls.c | 56 +++++++++++++++++++++++++++++++++++-------------- 4 files changed, 52 insertions(+), 19 deletions(-) create mode 100644 libc/inet/accept4.c (limited to 'libc/inet') diff --git a/libc/inet/Makefile.in b/libc/inet/Makefile.in index abcf2f7d7..c490adf7e 100644 --- a/libc/inet/Makefile.in +++ b/libc/inet/Makefile.in @@ -44,11 +44,13 @@ CSRC-$(findstring y,$(UCLIBC_HAS_IPV4)$(UCLIBC_HAS_IPV6)) += \ ## CSRC-y += encodep.c decodep.c formquery.c # multi source socketcalls.c -socketcalls_CSRC += \ +socketcalls_CSRC-y += \ accept.c bind.c connect.c getpeername.c getsockname.c \ getsockopt.c listen.c recv.c recvfrom.c recvmsg.c send.c sendmsg.c \ sendto.c setsockopt.c shutdown.c socket.c socketpair.c -CSRC-$(UCLIBC_HAS_SOCKET) += $(socketcalls_CSRC) opensock.c +# FIXME: GNU / linux specific +socketcalls_CSRC-y += accept4.c +CSRC-$(UCLIBC_HAS_SOCKET) += $(socketcalls_CSRC-y) opensock.c CSRC-$(findstring y,$(UCLIBC_HAS_SOCKET)$(UCLIBC_HAS_IPV4)$(UCLIBC_HAS_IPV6)) += ethers.c ether_addr.c diff --git a/libc/inet/accept.c b/libc/inet/accept.c index b0fd2b2c6..0217a6876 100644 --- a/libc/inet/accept.c +++ b/libc/inet/accept.c @@ -5,5 +5,4 @@ */ #define L_accept -#define L_accept4 #include "socketcalls.c" diff --git a/libc/inet/accept4.c b/libc/inet/accept4.c new file mode 100644 index 000000000..e2fdd6c2f --- /dev/null +++ b/libc/inet/accept4.c @@ -0,0 +1,8 @@ +/* + * Copyright (C) 2000-2006 Erik Andersen + * + * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + */ + +#define L_accept4 +#include "socketcalls.c" diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c index ff5fdaa30..aae7e93bf 100644 --- a/libc/inet/socketcalls.c +++ b/libc/inet/socketcalls.c @@ -83,6 +83,46 @@ weak_alias(__libc_accept,accept) libc_hidden_weak(accept) #endif +#ifdef L_accept4 +#ifdef __NR_accept4 +# define __NR___sys_accept4 __NR_accept4 +static _syscall4(int, __sys_accept4, int, fd, struct sockaddr *, addr, socklen_t *, addrlen, int, flags) +int accept4(int fd, struct sockaddr *addr, socklen_t * addrlen, int flags) +{ + if (SINGLE_THREAD_P) + return __sys_accept4(fd, addr, addrlen, flags); +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ + else { + int oldtype = LIBC_CANCEL_ASYNC (); + int result = __sys_accept4(fd, addr, addrlen, flags); + LIBC_CANCEL_RESET (oldtype); + return result; + } +#endif +} +#elif defined(__NR_socketcall) +int accept4(int fd, struct sockaddr *addr, socklen_t *addrlen, int flags) +{ + unsigned long args[4]; + + args[0] = fd; + args[1] = (unsigned long) addr; + args[2] = (unsigned long) addrlen; + args[3] = flags; + if (SINGLE_THREAD_P) + return __socketcall(SYS_ACCEPT4, args); +#ifdef __UCLIBC_HAS_THREADS_NATIVE__ + else { + int oldtype = LIBC_CANCEL_ASYNC (); + int result = __socketcall(SYS_ACCEPT4, args); + LIBC_CANCEL_RESET (oldtype); + return result; + } +#endif +} +#endif +#endif + #ifdef L_bind #ifdef __NR_bind _syscall3(int, bind, int, sockfd, const struct sockaddr *, myaddr, socklen_t, addrlen) @@ -562,19 +602,3 @@ int socketpair(int family, int type, int protocol, int sockvec[2]) #endif #endif -#ifdef L_accept4 -#ifdef __NR_accept4 -_syscall4(int, accept4, int, sockfd, struct sockaddr *, addr, socklen_t *, addrlen, int, flags) -#elif defined(__NR_socketcall) -int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) -{ - unsigned long args[4]; - - args[0] = sockfd; - args[1] = (unsigned long) addr; - args[2] = (unsigned long) addrlen; - args[3] = flags; - return __socketcall(SYS_ACCEPT4, args); -} -#endif -#endif -- cgit v1.2.3 From 44100dac1138c480deabb72ee8e180544005dfd9 Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Thu, 12 May 2011 10:37:36 +0200 Subject: linux_specific: handle accept4 and pipe2 Signed-off-by: Bernhard Reutner-Fischer --- libc/inet/Makefile.in | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'libc/inet') diff --git a/libc/inet/Makefile.in b/libc/inet/Makefile.in index c490adf7e..d58822074 100644 --- a/libc/inet/Makefile.in +++ b/libc/inet/Makefile.in @@ -48,8 +48,7 @@ socketcalls_CSRC-y += \ accept.c bind.c connect.c getpeername.c getsockname.c \ getsockopt.c listen.c recv.c recvfrom.c recvmsg.c send.c sendmsg.c \ sendto.c setsockopt.c shutdown.c socket.c socketpair.c -# FIXME: GNU / linux specific -socketcalls_CSRC-y += accept4.c +socketcalls_CSRC-$(UCLIBC_LINUX_SPECIFIC) += accept4.c CSRC-$(UCLIBC_HAS_SOCKET) += $(socketcalls_CSRC-y) opensock.c CSRC-$(findstring y,$(UCLIBC_HAS_SOCKET)$(UCLIBC_HAS_IPV4)$(UCLIBC_HAS_IPV6)) += ethers.c ether_addr.c -- cgit v1.2.3 From bc3be18145e4d57e7268506f123c0f0f373a15e2 Mon Sep 17 00:00:00 2001 From: Natanael Copa Date: Sun, 12 Jun 2011 12:09:04 +0000 Subject: getaddrinfo: allow numeric service without any hints This appears to correspond to what glibc does and this fixes an issue with iptables-1.4.11 with udp and raw port numbers. (see http://bugzilla.netfilter.org/show_bug.cgi?id=721) This fixes #3841 https://bugs.busybox.net/show_bug.cgi?id=3841 Signed-off-by: Natanael Copa Signed-off-by: Bernhard Reutner-Fischer --- libc/inet/getaddrinfo.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'libc/inet') diff --git a/libc/inet/getaddrinfo.c b/libc/inet/getaddrinfo.c index 1a77c5199..e7511f6c4 100644 --- a/libc/inet/getaddrinfo.c +++ b/libc/inet/getaddrinfo.c @@ -820,13 +820,6 @@ getaddrinfo(const char *name, const char *service, if (hints->ai_flags & AI_NUMERICSERV) return EAI_NONAME; gaih_service.num = -1; - } else { - /* - * Can't specify a numerical socket unless a protocol - * family was given. - */ - if (hints->ai_socktype == 0 && hints->ai_protocol == 0) - return EAI_SERVICE; } pservice = &gaih_service; } else -- cgit v1.2.3 From 0100056707c0ca5c51bb0b8d88612a407be09ef1 Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Tue, 14 Jun 2011 16:31:00 +0200 Subject: resolv: try next server on SERVFAIL in bug 3637 Andrey Kovalev aka pxe.ru writes: getaddrinfo does NOT add domain to query when receive SERVFAIL RFC1035 7.2 suggests that - If a resolver gets a server error or other bizarre response from a name server, it should remove it from SLIST, and may wish to schedule an immediate transmission to the next candidate server address. So let's try the next server upon SERVFAIL even if it's not strictly required. Signed-off-by: Bernhard Reutner-Fischer --- libc/inet/resolv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libc/inet') diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c index 021d5bf5d..e8b7f2bad 100644 --- a/libc/inet/resolv.c +++ b/libc/inet/resolv.c @@ -1461,7 +1461,7 @@ int attribute_hidden __dns_lookup(const char *name, /* bug 660 says we treat negative response as an error * and retry, which is, eh, an error. :) * We were incurring long delays because of this. */ - if (h.rcode == NXDOMAIN) { + if (h.rcode == NXDOMAIN || h.rcode == SERVFAIL) { /* if possible, try next search domain */ if (!ends_with_dot) { DPRINTF("variant:%d sdomains:%d\n", variant, sdomains); -- cgit v1.2.3 From e8dc8eca8d312a717dc94f9783af212aed388c11 Mon Sep 17 00:00:00 2001 From: Bernhard Reutner-Fischer Date: Fri, 17 Jun 2011 20:27:51 +0200 Subject: resolv: fix bug in res_init with ipv6 nameservers Thanks to Christian Krause for finding and fixing this! Signed-off-by: Bernhard Reutner-Fischer --- libc/inet/resolv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'libc/inet') diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c index e8b7f2bad..dc8a752fa 100644 --- a/libc/inet/resolv.c +++ b/libc/inet/resolv.c @@ -2964,7 +2964,7 @@ int res_init(void) if (__nameserver[i].sa.sa_family == AF_INET6 && m < ARRAY_SIZE(rp->_u._ext.nsaddrs) ) { - struct sockaddr_in6 *sa6 = malloc(sizeof(sa6)); + struct sockaddr_in6 *sa6 = malloc(sizeof(*sa6)); if (sa6) { *sa6 = __nameserver[i].sa6; /* struct copy */ rp->_u._ext.nsaddrs[m] = sa6; @@ -2981,7 +2981,7 @@ int res_init(void) #else /* IPv6 only */ while (m < ARRAY_SIZE(rp->_u._ext.nsaddrs) && i < __nameservers) { - struct sockaddr_in6 *sa6 = malloc(sizeof(sa6)); + struct sockaddr_in6 *sa6 = malloc(sizeof(*sa6)); if (sa6) { *sa6 = __nameserver[i].sa6; /* struct copy */ rp->_u._ext.nsaddrs[m] = sa6; -- cgit v1.2.3