#include #include #include #include #include #include #include #include int main(int argc, char **argv) { struct addrinfo *ai0, *ai, hints; int error; if (argc != 3) errx(1, "Usage: %s ", argv[0]); memset(&hints, 0, sizeof(hints)); hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(argv[1], argv[2], &hints, &ai0); if (error) errx(1, "getaddrinfo: %s", gai_strerror(error)); for (ai = ai0; ai != NULL; ai = ai->ai_next) { int fd; struct sockaddr_storage ss; socklen_t namelen; socklen_t optlen; socklen_t i; fd = socket(ai->ai_family, ai->ai_socktype|SOCK_NONBLOCK, ai->ai_protocol); if (fd == -1) { warn("socket"); continue; } if (connect(fd, ai->ai_addr, ai->ai_addrlen) != -1) { warnx("connect succeeded"); (void)close(fd); continue; } if (errno != EINPROGRESS) err(1, "connect failed unexpectedly"); warn("first connect"); if (connect(fd, ai->ai_addr, ai->ai_addrlen) == -1) warn("second connect"); else warnx("second connect succeeded!"); if (getsockname(fd, (struct sockaddr *)&ss, &namelen) == -1) { warn("getsockname"); } else { for (i = 0; i < namelen; i++) { fprintf(stderr, "%02hhx", ((const char *)&ss)[i]); } fprintf(stderr, "\n"); } optlen = sizeof(error); if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &optlen) == -1) err(1, "getsockopt(SO_ERROR)"); errno = error; warn("connect SO_ERROR"); if (connect(fd, ai->ai_addr, ai->ai_addrlen) == -1) warn("third connect"); else warnx("third connect succeeded!"); return 0; } errx(1, "no addresses"); }