+ if (!rp_v6 && !rp_v4)
+ goto out;
+
+ if (rp_v6) {
+ rp = rp_v6;
+ pfds[0].fd = usock_connect(type | USOCK_NONBLOCK, rp->ai_addr,
+ rp->ai_addrlen, rp->ai_family,
+ socktype, server);
+ if (pfds[0].fd < 0) {
+ rp_v6 = NULL;
+ goto try_v4;
+ }
+
+ if (timeout > 300) {
+ if (poll_restart(pfds, 1, 300) == 1) {
+ rp = rp_v6;
+ sock = pfds[0].fd;
+ goto out;
+ }
+ }
+ timeout -= 300;
+ }
+
+try_v4:
+ if (rp_v4) {
+ rp = rp_v4;
+ pfds[1].fd = usock_connect(type | USOCK_NONBLOCK, rp->ai_addr,
+ rp->ai_addrlen, rp->ai_family,
+ socktype, server);
+ if (pfds[1].fd < 0) {
+ rp_v4 = NULL;
+ if (!rp_v6)
+ goto out;
+ goto wait;
+ }
+ }
+
+wait:
+ poll_restart(pfds + !rp_v6, !!rp_v6 + !!rp_v4, timeout);
+ if (pfds[0].revents & POLLOUT) {
+ rp = rp_v6;
+ sock = pfds[0].fd;
+ goto out;
+ }
+
+ if (pfds[1].revents & POLLOUT) {
+ rp = rp_v4;
+ sock = pfds[1].fd;
+ goto out;
+ }
+
+out:
+ for (i = 0; i < 2; i++) {
+ int fd = pfds[i].fd;
+ if (fd >= 0 && fd != sock)
+ close(fd);
+ }
+
+ if (!(type & USOCK_NONBLOCK))
+ fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) & ~O_NONBLOCK);
+
+ if (addr && sock >= 0)
+ memcpy(addr, rp->ai_addr, rp->ai_addrlen);
+free_addrinfo: