mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-20 23:00:56 -05:00
unit test, testbound, basic udp and tcp tests are working on XP.
ipv6 not supported by OS is a warning (nonfatal). git-svn-id: file:///svn/unbound/trunk@1127 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
7be0e5b814
commit
fc3fc7a1f3
12 changed files with 341 additions and 49 deletions
|
|
@ -131,7 +131,7 @@ tests: all unittest testbound lock-verify pktview signit memstats \
|
|||
asynclook streamtcp perf delayer harvest
|
||||
|
||||
test: tests
|
||||
bash testcode/do-tests.sh
|
||||
if test -x "`which bash`"; then bash testcode/do-tests.sh; else sh testcode/do-tests.sh; fi
|
||||
|
||||
lib: libunbound.la
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,9 @@
|
|||
do not work in ascii-mode on windows. The b does nothing on unix.
|
||||
unittest and testbound tests work on windows (xp too).
|
||||
- ioctlsocket prints nicer error message.
|
||||
- fixed up some TCP porting for winsock.
|
||||
- lack of IPv6 gives a warning, no fatal error.
|
||||
- use WSAGetLastError() on windows instead of errno for some errors.
|
||||
|
||||
17 June 2008: Wouter
|
||||
- outgoing num fds 32 by default on windows ; it supports less
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ verbose_print_addr(struct addrinfo *addr)
|
|||
|
||||
int
|
||||
create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
socklen_t addrlen, int v6only, int* inuse)
|
||||
socklen_t addrlen, int v6only, int* inuse, int* noproto)
|
||||
{
|
||||
int s;
|
||||
# if defined(IPV6_USE_MIN_MTU)
|
||||
|
|
@ -98,8 +98,23 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
|||
(void)v6only;
|
||||
# endif
|
||||
if((s = socket(family, socktype, 0)) == -1) {
|
||||
log_err("can't create socket: %s", strerror(errno));
|
||||
*inuse = 0;
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) {
|
||||
*noproto = 1;
|
||||
return -1;
|
||||
}
|
||||
log_err("can't create socket: %s", strerror(errno));
|
||||
#else
|
||||
if(WSAGetLastError() == WSAEAFNOSUPPORT ||
|
||||
WSAGetLastError() == WSAEPROTONOSUPPORT) {
|
||||
*noproto = 1;
|
||||
return -1;
|
||||
}
|
||||
log_err("can't create socket: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
*noproto = 0;
|
||||
return -1;
|
||||
}
|
||||
if(family == AF_INET6) {
|
||||
|
|
@ -111,6 +126,7 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
|||
log_err("setsockopt(..., IPV6_V6ONLY"
|
||||
", ...) failed: %s", strerror(errno));
|
||||
close(s);
|
||||
*noproto = 0;
|
||||
*inuse = 0;
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -130,12 +146,14 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
|||
log_err("setsockopt(..., IPV6_USE_MIN_MTU, "
|
||||
"...) failed: %s", strerror(errno));
|
||||
close(s);
|
||||
*noproto = 0;
|
||||
*inuse = 0;
|
||||
return -1;
|
||||
}
|
||||
# endif
|
||||
}
|
||||
if(bind(s, (struct sockaddr*)addr, addrlen) != 0) {
|
||||
*noproto = 0;
|
||||
#ifdef EADDRINUSE
|
||||
*inuse = (errno == EADDRINUSE);
|
||||
if(errno != EADDRINUSE)
|
||||
|
|
@ -145,6 +163,7 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
|||
return -1;
|
||||
}
|
||||
if(!fd_set_nonblock(s)) {
|
||||
*noproto = 0;
|
||||
*inuse = 0;
|
||||
close(s);
|
||||
return -1;
|
||||
|
|
@ -156,18 +175,34 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
|||
* Create and bind TCP listening socket
|
||||
* @param addr: address info ready to make socket.
|
||||
* @param v6only: enable ip6 only flag on ip6 sockets.
|
||||
* @param noproto: if error caused by lack of protocol support.
|
||||
* @return: the socket. -1 on error.
|
||||
*/
|
||||
static int
|
||||
create_tcp_accept_sock(struct addrinfo *addr, int v6only)
|
||||
create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto)
|
||||
{
|
||||
int s;
|
||||
#if defined(SO_REUSEADDR) || defined(IPV6_V6ONLY)
|
||||
int on = 1;
|
||||
#endif /* SO_REUSEADDR || IPV6_V6ONLY */
|
||||
verbose_print_addr(addr);
|
||||
*noproto = 0;
|
||||
if((s = socket(addr->ai_family, addr->ai_socktype, 0)) == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno == EAFNOSUPPORT || errno == EPROTONOSUPPORT) {
|
||||
*noproto = 1;
|
||||
return -1;
|
||||
}
|
||||
log_err("can't create socket: %s", strerror(errno));
|
||||
#else
|
||||
if(WSAGetLastError() == WSAEAFNOSUPPORT ||
|
||||
WSAGetLastError() == WSAEPROTONOSUPPORT) {
|
||||
*noproto = 1;
|
||||
return -1;
|
||||
}
|
||||
log_err("can't create socket: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
#ifdef SO_REUSEADDR
|
||||
|
|
@ -209,11 +244,12 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only)
|
|||
*/
|
||||
static int
|
||||
make_sock(int stype, const char* ifname, const char* port,
|
||||
struct addrinfo *hints, int v6only)
|
||||
struct addrinfo *hints, int v6only, int* noip6)
|
||||
{
|
||||
struct addrinfo *res = NULL;
|
||||
int r, s, inuse;
|
||||
int r, s, inuse, noproto;
|
||||
hints->ai_socktype = stype;
|
||||
*noip6 = 0;
|
||||
if((r=getaddrinfo(ifname, port, hints, &res)) != 0 || !res) {
|
||||
log_err("node %s:%s getaddrinfo: %s %s",
|
||||
ifname?ifname:"default", port, gai_strerror(r),
|
||||
|
|
@ -229,11 +265,18 @@ make_sock(int stype, const char* ifname, const char* port,
|
|||
verbose_print_addr(res);
|
||||
s = create_udp_sock(res->ai_family, res->ai_socktype,
|
||||
(struct sockaddr*)res->ai_addr,
|
||||
res->ai_addrlen, v6only, &inuse);
|
||||
res->ai_addrlen, v6only, &inuse, &noproto);
|
||||
if(s == -1 && inuse) {
|
||||
log_err("bind: address already in use");
|
||||
} else if(s == -1 && noproto && hints->ai_family == AF_INET6){
|
||||
*noip6 = 1;
|
||||
}
|
||||
} else s = create_tcp_accept_sock(res, v6only);
|
||||
} else {
|
||||
s = create_tcp_accept_sock(res, v6only, &noproto);
|
||||
if(s == -1 && noproto && hints->ai_family == AF_INET6){
|
||||
*noip6 = 1;
|
||||
}
|
||||
}
|
||||
freeaddrinfo(res);
|
||||
return s;
|
||||
}
|
||||
|
|
@ -330,12 +373,18 @@ static int
|
|||
ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
||||
struct addrinfo *hints, const char* port, struct listen_port** list)
|
||||
{
|
||||
int s;
|
||||
int s, noip6=0;
|
||||
if(!do_udp && !do_tcp)
|
||||
return 0;
|
||||
if(do_auto) {
|
||||
if((s = make_sock(SOCK_DGRAM, ifname, port, hints, 1)) == -1)
|
||||
if((s = make_sock(SOCK_DGRAM, ifname, port, hints, 1,
|
||||
&noip6)) == -1) {
|
||||
if(noip6) {
|
||||
log_warn("IPv6 protocol not available");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* getting source addr packet info is highly non-portable */
|
||||
if(!set_recvpktinfo(s, hints->ai_family))
|
||||
return 0;
|
||||
|
|
@ -345,15 +394,26 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp,
|
|||
}
|
||||
} else if(do_udp) {
|
||||
/* regular udp socket */
|
||||
if((s = make_sock(SOCK_DGRAM, ifname, port, hints, 1)) == -1)
|
||||
if((s = make_sock(SOCK_DGRAM, ifname, port, hints, 1,
|
||||
&noip6)) == -1) {
|
||||
if(noip6) {
|
||||
log_warn("IPv6 protocol not available");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if(!port_insert(list, s, listen_type_udp)) {
|
||||
close(s);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if(do_tcp) {
|
||||
if((s = make_sock(SOCK_STREAM, ifname, port, hints, 1)) == -1) {
|
||||
if((s = make_sock(SOCK_STREAM, ifname, port, hints, 1,
|
||||
&noip6)) == -1) {
|
||||
if(noip6) {
|
||||
/*log_warn("IPv6 protocol not available");*/
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if(!port_insert(list, s, listen_type_tcp)) {
|
||||
|
|
|
|||
|
|
@ -171,9 +171,11 @@ size_t listen_get_mem(struct listen_dnsport* listen);
|
|||
* @param v6only: if enabled, IP6 sockets get IP6ONLY option set.
|
||||
* if enabled with value 2 IP6ONLY option is disabled.
|
||||
* @param inuse: on error, this is set true if the port was in use.
|
||||
* @param noproto: on error, this is set true if cause is that the
|
||||
IPv6 proto (family) is not available.
|
||||
* @return: the socket. -1 on error.
|
||||
*/
|
||||
int create_udp_sock(int family, int socktype, struct sockaddr* addr,
|
||||
socklen_t addrlen, int v6only, int* inuse);
|
||||
socklen_t addrlen, int v6only, int* inuse, int* noproto);
|
||||
|
||||
#endif /* LISTEN_DNSPORT_H */
|
||||
|
|
|
|||
|
|
@ -144,20 +144,28 @@ outnet_tcp_take_into_use(struct waiting_tcp* w, uint8_t* pkt, size_t pkt_len)
|
|||
#endif
|
||||
s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if(s == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err("outgoing tcp: socket: %s", strerror(errno));
|
||||
#else
|
||||
log_err("outgoing tcp: socket: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
log_addr(0, "failed address", &w->addr, w->addrlen);
|
||||
return 0;
|
||||
}
|
||||
fd_set_nonblock(s);
|
||||
if(connect(s, (struct sockaddr*)&w->addr, w->addrlen) == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
#ifdef EINPROGRESS
|
||||
if(errno != EINPROGRESS) {
|
||||
#elif defined(WSAEWOULDBLOCK)
|
||||
if(errno != WSAEWOULDBLOCK) {
|
||||
#else
|
||||
if(1) {
|
||||
#endif
|
||||
log_err("outgoing tcp: connect: %s", strerror(errno));
|
||||
#else /* USE_WINSOCK */
|
||||
if(WSAGetLastError() != WSAEINPROGRESS &&
|
||||
WSAGetLastError() != WSAEWOULDBLOCK) {
|
||||
#endif
|
||||
log_addr(0, "failed address", &w->addr, w->addrlen);
|
||||
close(s);
|
||||
return 0;
|
||||
|
|
@ -682,17 +690,17 @@ static int
|
|||
udp_sockport(struct sockaddr_storage* addr, socklen_t addrlen, int port,
|
||||
int* inuse)
|
||||
{
|
||||
int fd;
|
||||
int fd, noproto;
|
||||
if(addr_is_ip6(addr, addrlen)) {
|
||||
struct sockaddr_in6* sa = (struct sockaddr_in6*)addr;
|
||||
sa->sin6_port = (in_port_t)htons((uint16_t)port);
|
||||
fd = create_udp_sock(AF_INET6, SOCK_DGRAM,
|
||||
(struct sockaddr*)addr, addrlen, 1, inuse);
|
||||
(struct sockaddr*)addr, addrlen, 1, inuse, &noproto);
|
||||
} else {
|
||||
struct sockaddr_in* sa = (struct sockaddr_in*)addr;
|
||||
sa->sin_port = (in_port_t)htons((uint16_t)port);
|
||||
fd = create_udp_sock(AF_INET, SOCK_DGRAM,
|
||||
(struct sockaddr*)addr, addrlen, 1, inuse);
|
||||
(struct sockaddr*)addr, addrlen, 1, inuse, &noproto);
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -364,7 +364,11 @@ service_send(struct ringbuf* ring, struct timeval* now, ldns_buffer* pkt,
|
|||
ldns_buffer_limit(pkt), 0,
|
||||
(struct sockaddr*)srv_addr, srv_len);
|
||||
if(sent == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err("sendto: %s", strerror(errno));
|
||||
#else
|
||||
log_err("sendto: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
} else if(sent != (ssize_t)ldns_buffer_limit(pkt)) {
|
||||
log_err("sendto: partial send");
|
||||
}
|
||||
|
|
@ -383,9 +387,16 @@ do_proxy(struct proxy* p, int retsock, ldns_buffer* pkt)
|
|||
r = recv(p->s, ldns_buffer_begin(pkt),
|
||||
ldns_buffer_capacity(pkt), 0);
|
||||
if(r == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno == EAGAIN || errno == EINTR)
|
||||
return;
|
||||
log_err("recv: %s", strerror(errno));
|
||||
#else
|
||||
if(WSAGetLastError() == WSAEINPROGRESS ||
|
||||
WSAGetLastError() == WSAEWOULDBLOCK)
|
||||
return;
|
||||
log_err("recv: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
ldns_buffer_set_limit(pkt, (size_t)r);
|
||||
|
|
@ -395,7 +406,11 @@ do_proxy(struct proxy* p, int retsock, ldns_buffer* pkt)
|
|||
r = sendto(retsock, ldns_buffer_begin(pkt), (size_t)r, 0,
|
||||
(struct sockaddr*)&p->addr, p->addr_len);
|
||||
if(r == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err("sendto: %s", strerror(errno));
|
||||
#else
|
||||
log_err("sendto: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -445,7 +460,13 @@ find_create_proxy(struct sockaddr_storage* from, socklen_t from_len,
|
|||
p = (struct proxy*)calloc(1, sizeof(*p));
|
||||
if(!p) fatal_exit("out of memory");
|
||||
p->s = socket(serv_ip6?AF_INET6:AF_INET, SOCK_DGRAM, 0);
|
||||
if(p->s == -1) fatal_exit("socket: %s", strerror(errno));
|
||||
if(p->s == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
fatal_exit("socket: %s", strerror(errno));
|
||||
#else
|
||||
fatal_exit("socket: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
fd_set_nonblock(p->s);
|
||||
memmove(&p->addr, from, from_len);
|
||||
p->addr_len = from_len;
|
||||
|
|
@ -475,9 +496,17 @@ service_recv(int s, struct ringbuf* ring, ldns_buffer* pkt,
|
|||
ldns_buffer_capacity(pkt), 0,
|
||||
(struct sockaddr*)&from, &from_len);
|
||||
if(len < 0) {
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno == EAGAIN || errno == EINTR)
|
||||
return;
|
||||
fatal_exit("recvfrom: %s", strerror(errno));
|
||||
#else
|
||||
if(WSAGetLastError() == WSAEWOULDBLOCK ||
|
||||
WSAGetLastError() == WSAEINPROGRESS)
|
||||
return;
|
||||
fatal_exit("recvfrom: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
ldns_buffer_set_limit(pkt, (size_t)len);
|
||||
/* find its proxy element */
|
||||
|
|
@ -531,9 +560,17 @@ service_tcp_listen(int s, fd_set* rorig, int* max, struct tcp_proxy** proxies,
|
|||
socklen_t addr_len;
|
||||
newfd = accept(s, (struct sockaddr*)&addr, &addr_len);
|
||||
if(newfd == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno == EAGAIN || errno == EINTR)
|
||||
return;
|
||||
fatal_exit("accept: %s", strerror(errno));
|
||||
#else
|
||||
if(WSAGetLastError() == WSAEWOULDBLOCK ||
|
||||
WSAGetLastError() == WSAEINPROGRESS ||
|
||||
WSAGetLastError() == WSAECONNRESET)
|
||||
return;
|
||||
fatal_exit("accept: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
p = (struct tcp_proxy*)calloc(1, sizeof(*p));
|
||||
if(!p) fatal_exit("out of memory");
|
||||
|
|
@ -543,17 +580,24 @@ service_tcp_listen(int s, fd_set* rorig, int* max, struct tcp_proxy** proxies,
|
|||
p->client_s = newfd;
|
||||
p->server_s = socket(addr_is_ip6(srv_addr, srv_len)?AF_INET6:AF_INET,
|
||||
SOCK_STREAM, 0);
|
||||
if(p->server_s == -1)
|
||||
if(p->server_s == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
fatal_exit("tcp socket: %s", strerror(errno));
|
||||
#else
|
||||
fatal_exit("tcp socket: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
fd_set_nonblock(p->client_s);
|
||||
fd_set_nonblock(p->server_s);
|
||||
if(connect(p->server_s, (struct sockaddr*)srv_addr, srv_len) == -1) {
|
||||
#ifdef EINPROGRESS
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno != EINPROGRESS) {
|
||||
log_err("tcp connect: %s", strerror(errno));
|
||||
#else
|
||||
if(WSAGetLastError() != WSAEWOULDBLOCK) {
|
||||
log_err("tcp connect: %d", WSAGetLastError());
|
||||
if(WSAGetLastError() != WSAEWOULDBLOCK &&
|
||||
WSAGetLastError() != WSAEINPROGRESS) {
|
||||
log_err("tcp connect: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
close(p->server_s);
|
||||
close(p->client_s);
|
||||
|
|
@ -584,11 +628,19 @@ tcp_relay_read(int s, struct tcp_send_list** first,
|
|||
struct timeval* delay, ldns_buffer* pkt)
|
||||
{
|
||||
struct tcp_send_list* item;
|
||||
ssize_t r = read(s, ldns_buffer_begin(pkt), ldns_buffer_capacity(pkt));
|
||||
ssize_t r = recv(s, ldns_buffer_begin(pkt),
|
||||
ldns_buffer_capacity(pkt), 0);
|
||||
if(r == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno == EINTR || errno == EAGAIN)
|
||||
return 1;
|
||||
log_err("tcp read: %s", strerror(errno));
|
||||
#else
|
||||
if(WSAGetLastError() == WSAEINPROGRESS ||
|
||||
WSAGetLastError() == WSAEWOULDBLOCK)
|
||||
return 1;
|
||||
log_err("tcp read: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
return 0;
|
||||
} else if(r == 0) {
|
||||
/* connection closed */
|
||||
|
|
@ -635,11 +687,19 @@ tcp_relay_write(int s, struct tcp_send_list** first,
|
|||
if(!dl_tv_smaller(&p->wait, now))
|
||||
return 1;
|
||||
/* write it */
|
||||
r = write(s, p->item + p->done, p->len - p->done);
|
||||
r = send(s, (void*)(p->item + p->done), p->len - p->done, 0);
|
||||
if(r == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno == EAGAIN || errno == EINTR)
|
||||
return 1;
|
||||
log_err("tcp write: %s", strerror(errno));
|
||||
#else
|
||||
if(WSAGetLastError() == WSAEWOULDBLOCK ||
|
||||
WSAGetLastError() == WSAEINPROGRESS)
|
||||
return 1;
|
||||
log_err("tcp write: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
return 0;
|
||||
} else if(r == 0) {
|
||||
/* closed */
|
||||
|
|
@ -947,8 +1007,13 @@ service(char* bind_str, int bindport, char* serv_str, size_t memsize,
|
|||
fatal_exit("could not bind to signal");
|
||||
/* bind UDP port */
|
||||
if((s = socket(str_is_ip6(bind_str)?AF_INET6:AF_INET,
|
||||
SOCK_DGRAM, 0)) == -1)
|
||||
SOCK_DGRAM, 0)) == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
fatal_exit("socket: %s", strerror(errno));
|
||||
#else
|
||||
fatal_exit("socket: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
i=0;
|
||||
if(bindport == 0) {
|
||||
bindport = 1024 + random()%64000;
|
||||
|
|
@ -969,8 +1034,13 @@ service(char* bind_str, int bindport, char* serv_str, size_t memsize,
|
|||
fd_set_nonblock(s);
|
||||
/* and TCP port */
|
||||
if((listen_s = socket(str_is_ip6(bind_str)?AF_INET6:AF_INET,
|
||||
SOCK_STREAM, 0)) == -1)
|
||||
SOCK_STREAM, 0)) == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
fatal_exit("tcp socket: %s", strerror(errno));
|
||||
#else
|
||||
fatal_exit("tcp socket: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
#ifdef SO_REUSEADDR
|
||||
if(1) {
|
||||
int on = 1;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ NEED_LDNS_TESTNS='fwd_no_edns.tpkg fwd_tcp_tc.tpkg fwd_tcp.tpkg fwd_three_servic
|
|||
NEED_XXD='fwd_compress_c00c.tpkg'
|
||||
NEED_NC='fwd_compress_c00c.tpkg'
|
||||
NEED_CURL='06-ianaports.tpkg'
|
||||
NEED_WHOAMI='07-confroot.tpkg'
|
||||
|
||||
cd testdata;
|
||||
sh ../testcode/mini_tpkg.sh clean
|
||||
|
|
@ -42,6 +43,11 @@ for test in `ls *.tpkg`; do
|
|||
SKIP=1;
|
||||
fi
|
||||
fi
|
||||
if echo $NEED_WHOAMI | grep $test >/dev/null; then
|
||||
if test ! -x "`which whoami`"; then
|
||||
SKIP=1;
|
||||
fi
|
||||
fi
|
||||
if test $SKIP -eq 0; then
|
||||
echo $test
|
||||
sh ../testcode/mini_tpkg.sh -a ../.. exe $test
|
||||
|
|
|
|||
|
|
@ -225,8 +225,14 @@ perfsetup(struct perfinfo* info)
|
|||
info->io[i].fd = socket(
|
||||
addr_is_ip6(&info->dest, info->destlen)?
|
||||
AF_INET6:AF_INET, SOCK_DGRAM, 0);
|
||||
if(info->io[i].fd == -1)
|
||||
if(info->io[i].fd == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
fatal_exit("socket: %s", strerror(errno));
|
||||
#else
|
||||
fatal_exit("socket: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
}
|
||||
if(info->io[i].fd > info->maxfd)
|
||||
info->maxfd = info->io[i].fd;
|
||||
#ifndef S_SPLINT_S
|
||||
|
|
@ -267,9 +273,13 @@ perfsend(struct perfinfo* info, size_t n, struct timeval* now)
|
|||
(struct sockaddr*)&info->dest, info->destlen);
|
||||
/*log_hex("send", info->qlist_data[info->qlist_idx],
|
||||
info->qlist_len[info->qlist_idx]);*/
|
||||
if(r == -1)
|
||||
if(r == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err("sendto: %s", strerror(errno));
|
||||
else if(r != (ssize_t)info->qlist_len[info->qlist_idx]) {
|
||||
#else
|
||||
log_err("sendto: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
} else if(r != (ssize_t)info->qlist_len[info->qlist_idx]) {
|
||||
log_err("partial sendto");
|
||||
}
|
||||
info->qlist_idx = (info->qlist_idx+1) % info->qlist_size;
|
||||
|
|
@ -288,7 +298,11 @@ perfreply(struct perfinfo* info, size_t n, struct timeval* now)
|
|||
r = recv(info->io[n].fd, ldns_buffer_begin(info->buf),
|
||||
ldns_buffer_capacity(info->buf), 0);
|
||||
if(r == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
log_err("recv: %s", strerror(errno));
|
||||
#else
|
||||
log_err("recv: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
} else {
|
||||
info->by_rcode[LDNS_RCODE_WIRE(ldns_buffer_begin(
|
||||
info->buf))]++;
|
||||
|
|
@ -559,6 +573,10 @@ int main(int argc, char* argv[])
|
|||
char* nm = argv[0];
|
||||
int c;
|
||||
struct perfinfo info;
|
||||
#ifdef USE_WINSOCK
|
||||
int r;
|
||||
WSADATA wsa_data;
|
||||
#endif
|
||||
|
||||
/* defaults */
|
||||
memset(&info, 0, sizeof(info));
|
||||
|
|
@ -567,6 +585,10 @@ int main(int argc, char* argv[])
|
|||
log_init(NULL, 0, NULL);
|
||||
log_ident_set("perf");
|
||||
checklock_start();
|
||||
#ifdef USE_WINSOCK
|
||||
if((r = WSAStartup(MAKEWORD(2,2), &wsa_data)) != 0)
|
||||
fatal_exit("WSAStartup failed: %s", wsa_strerror(r));
|
||||
#endif
|
||||
|
||||
info.buf = ldns_buffer_new(65553);
|
||||
if(!info.buf) fatal_exit("out of memory");
|
||||
|
|
@ -616,6 +638,9 @@ int main(int argc, char* argv[])
|
|||
perfmain(&info);
|
||||
|
||||
ldns_buffer_free(info.buf);
|
||||
#ifdef USE_WINSOCK
|
||||
WSACleanup();
|
||||
#endif
|
||||
checklock_stop();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,11 +73,19 @@ open_svr(char* svr)
|
|||
fd = socket(addr_is_ip6(&addr, addrlen)?PF_INET6:PF_INET,
|
||||
SOCK_STREAM, 0);
|
||||
if(fd == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
perror("socket() error");
|
||||
#else
|
||||
printf("socket: %s\n", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
if(connect(fd, (struct sockaddr*)&addr, addrlen) < 0) {
|
||||
#ifndef USE_WINSOCK
|
||||
perror("connect() error");
|
||||
#else
|
||||
printf("connect: %s\n", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
return fd;
|
||||
|
|
@ -115,13 +123,21 @@ write_q(int fd, ldns_buffer* buf, int id,
|
|||
/* send it */
|
||||
len = (uint16_t)ldns_buffer_limit(buf);
|
||||
len = htons(len);
|
||||
if(write(fd, &len, sizeof(len)) < (ssize_t)sizeof(len)) {
|
||||
perror("write() len failed");
|
||||
if(send(fd, (void*)&len, sizeof(len), 0) < (ssize_t)sizeof(len)) {
|
||||
#ifndef USE_WINSOCK
|
||||
perror("send() len failed");
|
||||
#else
|
||||
printf("send len: %s\n", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
if(write(fd, ldns_buffer_begin(buf), ldns_buffer_limit(buf)) <
|
||||
if(send(fd, ldns_buffer_begin(buf), ldns_buffer_limit(buf), 0) <
|
||||
(ssize_t)ldns_buffer_limit(buf)) {
|
||||
perror("write() data failed");
|
||||
#ifndef USE_WINSOCK
|
||||
perror("send() data failed");
|
||||
#else
|
||||
printf("send data: %s\n", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
@ -135,15 +151,23 @@ recv_one(int fd, ldns_buffer* buf)
|
|||
uint16_t len;
|
||||
ldns_pkt* pkt;
|
||||
ldns_status status;
|
||||
if(read(fd, &len, sizeof(len)) < (ssize_t)sizeof(len)) {
|
||||
if(recv(fd, (void*)&len, sizeof(len), 0) < (ssize_t)sizeof(len)) {
|
||||
#ifndef USE_WINSOCK
|
||||
perror("read() len failed");
|
||||
#else
|
||||
printf("read len: %s\n", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
len = ntohs(len);
|
||||
ldns_buffer_clear(buf);
|
||||
ldns_buffer_set_limit(buf, len);
|
||||
if(read(fd, ldns_buffer_begin(buf), len) < (ssize_t)len) {
|
||||
if(recv(fd, ldns_buffer_begin(buf), len, 0) < (ssize_t)len) {
|
||||
#ifndef USE_WINSOCK
|
||||
perror("read() data failed");
|
||||
#else
|
||||
printf("read data: %s\n", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
printf("\nnext received packet\n");
|
||||
|
|
@ -203,6 +227,13 @@ int main(int argc, char** argv)
|
|||
{
|
||||
int c;
|
||||
char* svr = "127.0.0.1";
|
||||
#ifdef USE_WINSOCK
|
||||
WSADATA wsa_data;
|
||||
if(WSAStartup(MAKEWORD(2,2), &wsa_data) != 0) {
|
||||
printf("WSAStartup failed\n");
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* lock debug start (if any) */
|
||||
log_init(0, 0, 0);
|
||||
|
|
@ -239,5 +270,8 @@ int main(int argc, char** argv)
|
|||
}
|
||||
send_em(svr, argc, argv);
|
||||
checklock_stop();
|
||||
#ifdef USE_WINSOCK
|
||||
WSACleanup();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -222,7 +222,12 @@ comm_point_send_udp_msg(struct comm_point *c, ldns_buffer* packet,
|
|||
ldns_buffer_remaining(packet), 0,
|
||||
addr, addrlen);
|
||||
if(sent == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
verbose(VERB_OPS, "sendto failed: %s", strerror(errno));
|
||||
#else
|
||||
verbose(VERB_OPS, "sendto failed: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
log_addr(VERB_OPS, "remote address is",
|
||||
(struct sockaddr_storage*)addr, addrlen);
|
||||
return 0;
|
||||
|
|
@ -491,9 +496,16 @@ comm_point_udp_callback(int fd, short event, void* arg)
|
|||
ldns_buffer_remaining(rep.c->buffer), 0,
|
||||
(struct sockaddr*)&rep.addr, &rep.addrlen);
|
||||
if(recv == -1) {
|
||||
if(errno != EAGAIN && errno != EINTR) {
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno != EAGAIN && errno != EINTR)
|
||||
log_err("recvfrom failed: %s", strerror(errno));
|
||||
}
|
||||
#else
|
||||
if(WSAGetLastError() != WSAEINPROGRESS &&
|
||||
WSAGetLastError() != WSAECONNRESET &&
|
||||
WSAGetLastError()!= WSAEWOULDBLOCK)
|
||||
log_err("recvfrom failed: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
ldns_buffer_skip(rep.c->buffer, recv);
|
||||
|
|
@ -545,6 +557,7 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg)
|
|||
new_fd = accept(fd, (struct sockaddr*)&c_hdl->repinfo.addr,
|
||||
&c_hdl->repinfo.addrlen);
|
||||
if(new_fd == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
/* EINTR is signal interrupt. others are closed connection. */
|
||||
if( errno != EINTR
|
||||
#ifdef EWOULDBLOCK
|
||||
|
|
@ -559,6 +572,13 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg)
|
|||
)
|
||||
return;
|
||||
log_err("accept failed: %s", strerror(errno));
|
||||
#else /* USE_WINSOCK */
|
||||
if(WSAGetLastError() == WSAEINPROGRESS ||
|
||||
WSAGetLastError() == WSAEWOULDBLOCK ||
|
||||
WSAGetLastError() == WSAECONNRESET)
|
||||
return;
|
||||
log_err("accept failed: %s", wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
log_addr(0, "remote address is", &c_hdl->repinfo.addr,
|
||||
c_hdl->repinfo.addrlen);
|
||||
return;
|
||||
|
|
@ -637,11 +657,12 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok)
|
|||
log_assert(fd != -1);
|
||||
if(c->tcp_byte_count < sizeof(uint16_t)) {
|
||||
/* read length bytes */
|
||||
r = read(fd, ldns_buffer_at(c->buffer, c->tcp_byte_count),
|
||||
sizeof(uint16_t)-c->tcp_byte_count);
|
||||
r = recv(fd, ldns_buffer_at(c->buffer, c->tcp_byte_count),
|
||||
sizeof(uint16_t)-c->tcp_byte_count, 0);
|
||||
if(r == 0)
|
||||
return 0;
|
||||
else if(r == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno == EINTR || errno == EAGAIN)
|
||||
return 1;
|
||||
#ifdef ECONNRESET
|
||||
|
|
@ -649,6 +670,14 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok)
|
|||
return 0; /* silence reset by peer */
|
||||
#endif
|
||||
log_err("read (in tcp s): %s", strerror(errno));
|
||||
#else /* USE_WINSOCK */
|
||||
if(WSAGetLastError() == WSAEINPROGRESS ||
|
||||
WSAGetLastError() == WSAECONNRESET ||
|
||||
WSAGetLastError() == WSAEWOULDBLOCK)
|
||||
return 1;
|
||||
log_err("read (in tcp s): %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
log_addr(0, "remote address is", &c->repinfo.addr,
|
||||
c->repinfo.addrlen);
|
||||
return 0;
|
||||
|
|
@ -673,14 +702,23 @@ comm_point_tcp_handle_read(int fd, struct comm_point* c, int short_ok)
|
|||
}
|
||||
|
||||
log_assert(ldns_buffer_remaining(c->buffer) > 0);
|
||||
r = read(fd, ldns_buffer_current(c->buffer),
|
||||
ldns_buffer_remaining(c->buffer));
|
||||
r = recv(fd, ldns_buffer_current(c->buffer),
|
||||
ldns_buffer_remaining(c->buffer), 0);
|
||||
if(r == 0) {
|
||||
return 0;
|
||||
} else if(r == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno == EINTR || errno == EAGAIN)
|
||||
return 1;
|
||||
log_err("read (in tcp r): %s", strerror(errno));
|
||||
#else /* USE_WINSOCK */
|
||||
if(WSAGetLastError() == WSAEINPROGRESS ||
|
||||
WSAGetLastError() == WSAECONNRESET ||
|
||||
WSAGetLastError() == WSAEWOULDBLOCK)
|
||||
return 1;
|
||||
log_err("read (in tcp r): %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
log_addr(0, "remote address is", &c->repinfo.addr,
|
||||
c->repinfo.addrlen);
|
||||
return 0;
|
||||
|
|
@ -747,12 +785,20 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
|
|||
log_assert(iov[1].iov_len > 0);
|
||||
r = writev(fd, iov, 2);
|
||||
#else /* HAVE_WRITEV */
|
||||
r = write(fd, &len, sizeof(uint16_t));
|
||||
r = send(fd, (void*)&len, sizeof(uint16_t), 0);
|
||||
#endif /* HAVE_WRITEV */
|
||||
if(r == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno == EINTR || errno == EAGAIN)
|
||||
return 1;
|
||||
log_err("tcp writev: %s", strerror(errno));
|
||||
#else
|
||||
if(WSAGetLastError() == WSAEINPROGRESS ||
|
||||
WSAGetLastError() == WSAEWOULDBLOCK)
|
||||
return 1;
|
||||
log_err("tcp send s: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
log_addr(0, "remote address is", &c->repinfo.addr,
|
||||
c->repinfo.addrlen);
|
||||
return 0;
|
||||
|
|
@ -764,16 +810,24 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
|
|||
sizeof(uint16_t));
|
||||
if(ldns_buffer_remaining(c->buffer) == 0) {
|
||||
tcp_callback_writer(c);
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
log_assert(ldns_buffer_remaining(c->buffer) > 0);
|
||||
r = write(fd, ldns_buffer_current(c->buffer),
|
||||
ldns_buffer_remaining(c->buffer));
|
||||
r = send(fd, ldns_buffer_current(c->buffer),
|
||||
ldns_buffer_remaining(c->buffer), 0);
|
||||
if(r == -1) {
|
||||
#ifndef USE_WINSOCK
|
||||
if(errno == EINTR || errno == EAGAIN)
|
||||
return 1;
|
||||
log_err("tcp write: %s", strerror(errno));
|
||||
log_err("tcp send r: %s", strerror(errno));
|
||||
#else
|
||||
if(WSAGetLastError() == WSAEINPROGRESS ||
|
||||
WSAGetLastError() == WSAEWOULDBLOCK)
|
||||
return 1;
|
||||
log_err("tcp send r: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
#endif
|
||||
log_addr(0, "remote address is", &c->repinfo.addr,
|
||||
c->repinfo.addrlen);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -239,8 +239,8 @@ static int handle_select(struct event_base* base, struct timeval* wait)
|
|||
short bits = 0;
|
||||
/* eventlist[i] fired */
|
||||
if(WSAEnumNetworkEvents(eventlist[i]->ev_fd,
|
||||
/*waitfor[i],*/ /* reset the event handle */
|
||||
NULL, /* do not reset the event handle */
|
||||
waitfor[i], /* reset the event handle */
|
||||
/*NULL,*/ /* do not reset the event handle */
|
||||
&netev) != 0) {
|
||||
log_err("WSAEnumNetworkEvents failed: %s",
|
||||
wsa_strerror(WSAGetLastError()));
|
||||
|
|
@ -279,6 +279,20 @@ static int handle_select(struct event_base* base, struct timeval* wait)
|
|||
bits |= EV_WRITE;
|
||||
}
|
||||
if(bits) {
|
||||
verbose(VERB_ALGO, "winsock event callback %p fd=%d "
|
||||
"%s%s%s%s%s ; %s%s%s",
|
||||
eventlist[i], eventlist[i]->ev_fd,
|
||||
(netev.lNetworkEvents&FD_READ)?" FD_READ":"",
|
||||
(netev.lNetworkEvents&FD_WRITE)?" FD_WRITE":"",
|
||||
(netev.lNetworkEvents&FD_CONNECT)?
|
||||
" FD_CONNECT":"",
|
||||
(netev.lNetworkEvents&FD_ACCEPT)?
|
||||
" FD_ACCEPT":"",
|
||||
(netev.lNetworkEvents&FD_CLOSE)?" FD_CLOSE":"",
|
||||
(bits&EV_READ)?" EV_READ":"",
|
||||
(bits&EV_WRITE)?" EV_WRITE":"",
|
||||
(bits&EV_TIMEOUT)?" EV_TIMEOUT":"");
|
||||
|
||||
fptr_ok(fptr_whitelist_event(
|
||||
eventlist[i]->ev_callback));
|
||||
(*eventlist[i]->ev_callback)(eventlist[i]->ev_fd,
|
||||
|
|
@ -350,6 +364,12 @@ int event_base_set(struct event_base *base, struct event *ev)
|
|||
|
||||
int event_add(struct event *ev, struct timeval *tv)
|
||||
{
|
||||
verbose(VERB_ALGO, "event_add %p added=%d fd=%d tv=%d %s%s%s",
|
||||
ev, ev->added, ev->ev_fd,
|
||||
(tv?(int)tv->tv_sec*1000+(int)tv->tv_usec/1000:-1),
|
||||
(ev->ev_events&EV_READ)?" EV_READ":"",
|
||||
(ev->ev_events&EV_WRITE)?" EV_WRITE":"",
|
||||
(ev->ev_events&EV_TIMEOUT)?" EV_TIMEOUT":"");
|
||||
if(ev->added)
|
||||
event_del(ev);
|
||||
log_assert(ev->ev_fd==-1 || find_fd(ev->ev_base, ev->ev_fd) == -1);
|
||||
|
|
@ -414,6 +434,13 @@ int event_add(struct event *ev, struct timeval *tv)
|
|||
|
||||
int event_del(struct event *ev)
|
||||
{
|
||||
verbose(VERB_ALGO, "event_del %p added=%d fd=%d tv=%d %s%s%s",
|
||||
ev, ev->added, ev->ev_fd,
|
||||
(ev->ev_events&EV_TIMEOUT)?(int)ev->ev_timeout.tv_sec*1000+
|
||||
(int)ev->ev_timeout.tv_usec/1000:-1,
|
||||
(ev->ev_events&EV_READ)?" EV_READ":"",
|
||||
(ev->ev_events&EV_WRITE)?" EV_WRITE":"",
|
||||
(ev->ev_events&EV_TIMEOUT)?" EV_TIMEOUT":"");
|
||||
if(!ev->added)
|
||||
return 0;
|
||||
log_assert(ev->added && ev->ev_base->max > 0)
|
||||
|
|
|
|||
|
|
@ -66,6 +66,9 @@
|
|||
*
|
||||
* Socket numbers are not starting small, they can be any number (say 33060).
|
||||
* Therefore, bitmaps are not used, but arrays.
|
||||
*
|
||||
* on winsock, you must use recv() and send() for TCP reads and writes,
|
||||
* not read() and write(), those work only on files.
|
||||
*/
|
||||
|
||||
#ifndef UTIL_WINSOCK_EVENT_H
|
||||
|
|
|
|||
Loading…
Reference in a new issue