From 26382e1637ee28ae7b4d96b4c7c20f2a58f04f19 Mon Sep 17 00:00:00 2001 From: Tobias Girstmair Date: Wed, 29 May 2024 18:23:17 +0200 Subject: [PATCH] implement setup timeout our current handling of only a specific set of error numerics makes us vulnerable to hangs, when an unexpected code was received. we should really respect a response timeout here (which must be quite large due to ident!) note that connect timeout is not handled by this (but by setsockopt); it's a bit unfortunate that when that triggers, errno is EINPROGRESS ("Operation now in progress"), as that's a bit confusing. --- ircpipe.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/ircpipe.c b/ircpipe.c index 034c2fb..59a2c63 100644 --- a/ircpipe.c +++ b/ircpipe.c @@ -20,6 +20,7 @@ #define POLL_TIMEOUT 100 /*ms*/ #define PING_INTERVAL 120000 /*ms*/ #define PONG_TIMEOUT 2000 /*ms*/ +#define SETUP_TIMEOUT 15000 /*ms*/ #define STR_(x) #x #define STR(x) STR_(x) @@ -128,7 +129,6 @@ int irc_answer(const sock_t sock, char *buf, const unsigned int command) { while (*line && *line++ != ' '); /* look for command responses or relevant error numerics: */ - /* TODO: our current handling of only a specific set of error numerics makes us vulnerable to hangs, when an unexpected code was received. we should really respect a response timeout here (during setup this must be quite large, because of ident and port scanning!) */ switch (command) { case PING: seen |= PING * (strncmp(line, "PONG ", 5)==0); break; case JOIN: seen |= JOIN * (strncmp(line, "JOIN ", 5)==0); @@ -189,8 +189,15 @@ int irc_base64(char *buf, int n) { return l; } +long irc_time(void) { + struct timespec t; + clock_gettime(CLOCK_MONOTONIC, &t) OR_DIE; + return t.tv_sec*1000 + t.tv_nsec / 1000000; /* milliseconds */ +} + int irc_wait(const sock_t sock, const int outfd, int cmd, char* buf) { int n; + long start = irc_time(); struct pollfd fds[1]; fds[0].fd = sock.fd; fds[0].events = POLLIN; @@ -202,7 +209,10 @@ int irc_wait(const sock_t sock, const int outfd, int cmd, char* buf) { write(outfd, buf, n); n = irc_answer(sock, buf, cmd); if (n & cmd) return 0; - else if (n & ERRS) return -1; + if (irc_time() - start > SETUP_TIMEOUT) { + fprintf(stderr, "IRC setup timeout\n"); + exit(1); + } } } } @@ -253,12 +263,6 @@ int irc_setup(const sock_t sock, const int outfd, const char *nick, const char * return 0; } -long irc_time() { - struct timespec t; - clock_gettime(CLOCK_MONOTONIC, &t) OR_DIE; - return t.tv_sec*1000 + t.tv_nsec / 1000000; /* milliseconds */ -} - int irc_poll(const sock_t sock, const int infd, const int outfd) { int n; char buf[BUFSIZ]; -- 2.39.3