Revert "Race parallel connects"

This reverts commit e3e2b36ecf.

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.
master
Curtis McEnroe 2018-09-16 13:25:31 -04:00
parent e3e2b36ecf
commit 75203b2e54
No known key found for this signature in database
GPG Key ID: CEA2F97ADCFCD77C
1 changed files with 22 additions and 57 deletions

79
irc.c
View File

@ -15,11 +15,9 @@
*/ */
#include <err.h> #include <err.h>
#include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <netdb.h> #include <netdb.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <poll.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -31,60 +29,6 @@
#include "chat.h" #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 struct tls *client;
static void webirc(const char *pass) { static void webirc(const char *pass) {
@ -115,7 +59,28 @@ int ircConnect(
if (error) errx(EX_SOFTWARE, "tls_configure"); if (error) errx(EX_SOFTWARE, "tls_configure");
tls_config_free(config); 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); error = fcntl(sock, F_SETFD, FD_CLOEXEC);
if (error) err(EX_IOERR, "fcntl"); if (error) err(EX_IOERR, "fcntl");