]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
unit test, testbound, basic udp and tcp tests are working on XP.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 18 Jun 2008 14:27:30 +0000 (14:27 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Wed, 18 Jun 2008 14:27:30 +0000 (14:27 +0000)
ipv6 not supported by OS is a warning (nonfatal).

git-svn-id: file:///svn/unbound/trunk@1127 be551aaa-1e26-0410-a405-d3ace91eadb9

12 files changed:
Makefile.in
doc/Changelog
services/listen_dnsport.c
services/listen_dnsport.h
services/outside_network.c
testcode/delayer.c
testcode/do-tests.sh
testcode/perf.c
testcode/streamtcp.c
util/netevent.c
util/winsock_event.c
util/winsock_event.h

index 5b6ed9b37516344ee8f4c8fb565d580369a910ba..26505c57b56faa87b8ef3dd131cf26a9b6f5e14d 100644 (file)
@@ -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
 
index 6701995e82242b4144144c7f202a64523428bf26..6b236714f0d2ff42504006a7db94f41013a952ea 100644 (file)
@@ -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
index 915b57b91c6f5acd49f9213d3598c3b02e412650..c054c268cb2a3248504e215decce8fae59b15887 100644 (file)
@@ -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)) {
index eed71fc2c22bc7a1aea800054a98d1dbaec92c5f..a35ae0a4dde4a798b400b34733482179e224c129 100644 (file)
@@ -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 */
index 59a3f6e55a9c7c95f4b96b13869a3a91aea02d7d..9b1cf8159b3b6b5703cbd42e274c2933bfef8ed3 100644 (file)
@@ -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;
 }
index 37240a5204227e6dc3c3233731437820c84e140d..f6e089571123ed566e83dc18b60f644cc27dfd96 100644 (file)
@@ -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;
index 16828e284ab35d3f6b380950a8ceea4b49e938b6..a50299e9e4ad41385e930425be6407f69bd2afe4 100755 (executable)
@@ -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
index 3f8b331ec1fb3cbf1d81eebdd8ce526eca978b1f..feb2b4ba6e0d9b24a15663052a2e204ff47630f3 100644 (file)
@@ -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;
 }
index 9fa7ddc4ca80cd4d033691cdfa671906ee271a7f..f646cb5192b9268e6ff8d6c27a5cd94f6d377be4 100644 (file)
@@ -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;
 }
index 13aedee700c333e336bdb39583bc372bc040340c..9cf71b5f94758c2e903d48c2bb92ccc254d561d8 100644 (file)
@@ -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;
index 07ac22430dd525409f9b7e54daad589d2bd44305..c1ccb5aad4b0e689b20846fbef55a01a49c874f6 100644 (file)
@@ -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)
index 37ce3f915faecc03486964886587af5030591b78..6dec399dafa8320697772283e9d1f28d87cf79e2 100644 (file)
@@ -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