+int connectnonblocking(int s, const struct sockaddr *addr, socklen_t addrlen, struct timeval *timeout) {
+ int origflags, error = 0, r = -1;
+ fd_set writefds;
+ socklen_t len;
+
+ origflags = fcntl(s, F_GETFL, 0);
+ fcntl(s, F_SETFL, origflags | O_NONBLOCK);
+ if (!connect(s, addr, addrlen)) {
+ r = 0;
+ goto exit;
+ }
+ if (errno != EINPROGRESS)
+ goto exit;
+
+ FD_ZERO(&writefds);
+ FD_SET(s, &writefds);
+ if (select(s + 1, NULL, &writefds, NULL, timeout) < 1)
+ goto exit;
+
+ len = sizeof(error);
+ if (!getsockopt(s, SOL_SOCKET, SO_ERROR, (char*)&error, &len) && !error)
+ r = 0;
+
+exit:
+ fcntl(s, F_SETFL, origflags);
+ return r;
+}
+
+int connecttcp(struct addrinfo *addrinfo, struct addrinfo *src, uint16_t timeout) {