- fixup fwd_ancil test typos.
- Fix for newegg lameness : ok for qtype=A, but lame for others.
- fixup unit test for infra cache, test lame merging.
+ - porting to mingw, bind, listen, getsockopt and setsockopt error
+ handling.
24 June 2008: Wouter
- removed testcode/checklocks from production code compilation path.
o add/del static preload data to change the domain redirections.
o and maybe also start, stop, reload.
+
+o on windows version, libunbound uses a NamedPipe, examine security status
+ make sure the OS makes it safe like on unix.
+o on windows version, implement that OS ancillary data capabilities for
+ interface-automatic. IPPKTINFO, IP6PKTINFO for WSARecvMsg, WSASendMsg.
errno = e;
return NULL;
}
+#ifndef USE_WINSOCK
if(!fd_set_nonblock(ctx->rrpipe[0]) ||
!fd_set_nonblock(ctx->rrpipe[1]) ||
!fd_set_nonblock(ctx->qqpipe[0]) ||
errno = e;
return NULL;
}
+#endif /* !USE_WINSOCK - it is a pipe(nonsocket) on windows) */
lock_basic_init(&ctx->qqpipe_lock);
lock_basic_init(&ctx->rrpipe_lock);
lock_basic_init(&ctx->cfglock);
int val=(v6only==2)?0:1;
if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
(void*)&val, (socklen_t)sizeof(val)) < 0) {
+#ifndef USE_WINSOCK
log_err("setsockopt(..., IPV6_V6ONLY"
", ...) failed: %s", strerror(errno));
+#else
+ log_err("setsockopt(..., IPV6_V6ONLY"
+ ", ...) failed: %s",
+ wsa_strerror(WSAGetLastError()));
+#endif
close(s);
*noproto = 0;
*inuse = 0;
*/
if (setsockopt(s, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
(void*)&on, (socklen_t)sizeof(on)) < 0) {
+#ifndef USE_WINSOCK
log_err("setsockopt(..., IPV6_USE_MIN_MTU, "
"...) failed: %s", strerror(errno));
+#else
+ log_err("setsockopt(..., IPV6_USE_MIN_MTU, "
+ "...) failed: %s",
+ wsa_strerror(WSAGetLastError()));
+#endif
close(s);
*noproto = 0;
*inuse = 0;
}
if(bind(s, (struct sockaddr*)addr, addrlen) != 0) {
*noproto = 0;
+#ifndef USE_WINSOCK
#ifdef EADDRINUSE
*inuse = (errno == EADDRINUSE);
if(errno != EADDRINUSE)
-#endif
log_err("can't bind socket: %s", strerror(errno));
+#endif
+#else /* USE_WINSOCK */
+ if(WSAGetLastError() != WSAEADDRINUSE &&
+ WSAGetLastError() != WSAEADDRNOTAVAIL)
+#endif
+ log_err("can't bind socket: %s",
+ wsa_strerror(WSAGetLastError()));
close(s);
return -1;
}
#ifdef SO_REUSEADDR
if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&on,
(socklen_t)sizeof(on)) < 0) {
+#ifndef USE_WINSOCK
log_err("setsockopt(.. SO_REUSEADDR ..) failed: %s",
strerror(errno));
+#else
+ log_err("setsockopt(.. SO_REUSEADDR ..) failed: %s",
+ wsa_strerror(WSAGetLastError()));
+#endif
return -1;
}
#endif /* SO_REUSEADDR */
if(addr->ai_family == AF_INET6 && v6only) {
if(setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
(void*)&on, (socklen_t)sizeof(on)) < 0) {
+#ifndef USE_WINSOCK
log_err("setsockopt(..., IPV6_V6ONLY, ...) failed: %s",
strerror(errno));
+#else
+ log_err("setsockopt(..., IPV6_V6ONLY, ...) failed: %s",
+ wsa_strerror(WSAGetLastError()));
+#endif
return -1;
}
}
(void)v6only;
#endif /* IPV6_V6ONLY */
if(bind(s, addr->ai_addr, addr->ai_addrlen) != 0) {
+#ifndef USE_WINSOCK
log_err("can't bind socket: %s", strerror(errno));
+#else
+ log_err("can't bind socket: %s",
+ wsa_strerror(WSAGetLastError()));
+#endif
return -1;
}
if(!fd_set_nonblock(s)) {
return -1;
}
if(listen(s, TCP_BACKLOG) == -1) {
+#ifndef USE_WINSOCK
log_err("can't listen: %s", strerror(errno));
+#else
+ log_err("can't listen: %s", wsa_strerror(WSAGetLastError()));
+#endif
return -1;
}
return s;
exit(1);
}
if(bind(s, (struct sockaddr*)&bind_addr, bind_len) == -1) {
+#ifndef USE_WINSOCK
log_err("bind: %s", strerror(errno));
+#else
+ log_err("bind: %s", wsa_strerror(WSAGetLastError()));
+#endif
if(i--==0)
fatal_exit("cannot bind any port");
bindport = 1024 + random()%64000;
int on = 1;
if(setsockopt(listen_s, SOL_SOCKET, SO_REUSEADDR, (void*)&on,
(socklen_t)sizeof(on)) < 0)
+#ifndef USE_WINSOCK
fatal_exit("setsockopt(.. SO_REUSEADDR ..) failed: %s",
strerror(errno));
+#else
+ fatal_exit("setsockopt(.. SO_REUSEADDR ..) failed: %s",
+ wsa_strerror(WSAGetLastError()));
+#endif
}
#endif
- if(bind(listen_s, (struct sockaddr*)&bind_addr, bind_len) == -1)
+ if(bind(listen_s, (struct sockaddr*)&bind_addr, bind_len) == -1) {
+#ifndef USE_WINSOCK
fatal_exit("tcp bind: %s", strerror(errno));
- if(listen(listen_s, 5) == -1)
+#else
+ fatal_exit("tcp bind: %s", wsa_strerror(WSAGetLastError()));
+#endif
+ }
+ if(listen(listen_s, 5) == -1) {
+#ifndef USE_WINSOCK
fatal_exit("tcp listen: %s", strerror(errno));
+#else
+ fatal_exit("tcp listen: %s", wsa_strerror(WSAGetLastError()));
+#endif
+ }
fd_set_nonblock(listen_s);
printf("listening on port: %d\n", bindport);
#ifndef USE_WINSOCK
cfg->outgoing_num_ports = 256;
#else
- cfg->outgoing_num_ports = 32; /* windows is limited in num fds */
+ cfg->outgoing_num_ports = 16; /* windows is limited in num fds */
#endif
cfg->outgoing_num_tcp = 10;
cfg->incoming_num_tcp = 10;
socklen_t len = (socklen_t)sizeof(error);
if(getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&error,
&len) < 0){
+#ifndef USE_WINSOCK
error = errno; /* on solaris errno is error */
+#else /* USE_WINSOCK */
+ error = WSAGetLastError();
+#endif
}
+#ifndef USE_WINSOCK
#if defined(EINPROGRESS) && defined(EWOULDBLOCK)
if(error == EINPROGRESS || error == EWOULDBLOCK)
return 1; /* try again later */
#endif
else if(error != 0) {
log_err("tcp connect: %s", strerror(error));
+#else /* USE_WINSOCK */
+ /* examine error */
+ if(error == WSAEINPROGRESS)
+ return 1;
+ else if(error == WSAEWOULDBLOCK) {
+ winsock_tcp_wouldblock(&c->ev->ev, EV_WRITE);
+ return 1;
+ } else if(error == WSAECONNREFUSED || error == WSAEHOSTUNREACH)
+ return 0;
+ else if(error != 0) {
+ log_err("tcp connect: %s", wsa_strerror(error));
+#endif /* USE_WINSOCK */
log_addr(0, "remote address is", &c->repinfo.addr,
c->repinfo.addrlen);
return 0;
* not read() and write(), those work only on files.
*
* Also fseek and fseeko do not work if a FILE is not fopen-ed in binary mode.
+ *
+ * When under a high load windows gives out lots of errors, from recvfrom
+ * on udp sockets for example (WSAECONNRESET). Even though the udp socket
+ * has no connection per se.
*/
#ifndef UTIL_WINSOCK_EVENT_H