diff options
author | June McEnroe <june@causal.agency> | 2018-09-16 13:25:31 -0400 |
---|---|---|
committer | June McEnroe <june@causal.agency> | 2018-09-16 13:25:31 -0400 |
commit | 75203b2e54ac16e6afd9e1293f0d53194e9f6260 (patch) | |
tree | f7a6f5008b70f5693d75110090d96db5b0d07f34 | |
parent | Race parallel connects (diff) | |
download | test-75203b2e54ac16e6afd9e1293f0d53194e9f6260.tar.gz test-75203b2e54ac16e6afd9e1293f0d53194e9f6260.zip |
Revert "Race parallel connects"
This reverts commit e3e2b36ecf6a1340f1dc2542233bafe0862447fa. Apparently racing *all* of the connections is not something you should do, and I can't be bothered with all the extra logic to do this "correctly" according to RFC 8305. Provide an API, you cowards. What I did want to do was give IPv6 any chance at all of being used, but I'm just going to leave that up to the order getaddrinfo returns. It's someone else's fault.
-rw-r--r-- | irc.c | 79 |
1 files changed, 22 insertions, 57 deletions
diff --git a/irc.c b/irc.c index 0bd8ca6..6754e16 100644 --- a/irc.c +++ b/irc.c @@ -15,11 +15,9 @@ */ #include <err.h> -#include <errno.h> #include <fcntl.h> #include <netdb.h> #include <netinet/in.h> -#include <poll.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> @@ -31,60 +29,6 @@ #include "chat.h" -static int connectRace(const char *host, const char *port) { - int error; - struct addrinfo *head; - struct addrinfo hints = { - .ai_family = AF_UNSPEC, - .ai_socktype = SOCK_STREAM, - .ai_protocol = IPPROTO_TCP, - }; - error = getaddrinfo(host, port, &hints, &head); - if (error) errx(EX_NOHOST, "getaddrinfo: %s", gai_strerror(error)); - - nfds_t len = 0; - enum { SocksLen = 16 }; - struct pollfd socks[SocksLen]; - for (struct addrinfo *ai = head; ai; ai = ai->ai_next) { - if (len == SocksLen) break; - - socks[len].events = POLLOUT; - socks[len].fd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); - if (socks[len].fd < 0) err(EX_OSERR, "socket"); - - error = fcntl(socks[len].fd, F_SETFL, O_NONBLOCK); - if (error) err(EX_OSERR, "fcntl"); - - error = connect(socks[len].fd, ai->ai_addr, ai->ai_addrlen); - if (error && errno != EINPROGRESS && errno != EINTR) { - close(socks[len].fd); - continue; - } - - len++; - } - if (!len) err(EX_UNAVAILABLE, "connect"); - freeaddrinfo(head); - - int ready = poll(socks, len, -1); - if (ready < 0) err(EX_IOERR, "poll"); - - int sock = -1; - for (nfds_t i = 0; i < len; ++i) { - if ((socks[i].revents & POLLOUT) && sock < 0) { - sock = socks[i].fd; - } else { - close(socks[i].fd); - } - } - if (sock < 0) errx(EX_UNAVAILABLE, "no socket became writable"); - - error = fcntl(sock, F_SETFL, 0); - if (error) err(EX_IOERR, "fcntl"); - - return sock; -} - static struct tls *client; static void webirc(const char *pass) { @@ -115,7 +59,28 @@ int ircConnect( if (error) errx(EX_SOFTWARE, "tls_configure"); tls_config_free(config); - int sock = connectRace(host, port); + struct addrinfo *head; + struct addrinfo hints = { + .ai_family = AF_UNSPEC, + .ai_socktype = SOCK_STREAM, + .ai_protocol = IPPROTO_TCP, + }; + error = getaddrinfo(host, port, &hints, &head); + if (error) errx(EX_NOHOST, "getaddrinfo: %s", gai_strerror(error)); + + int sock = -1; + for (struct addrinfo *ai = head; ai; ai = ai->ai_next) { + sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (sock < 0) err(EX_OSERR, "socket"); + + error = connect(sock, ai->ai_addr, ai->ai_addrlen); + if (!error) break; + + close(sock); + sock = -1; + } + if (sock < 0) err(EX_UNAVAILABLE, "connect"); + freeaddrinfo(head); error = fcntl(sock, F_SETFD, FD_CLOEXEC); if (error) err(EX_IOERR, "fcntl"); |