Here is a bit more cleanup of the http.c code. - Move http_fail() out of http_free() and more to the places where the failure should be reported. This needs further work but one step at a time.
- Change http_connect() to be more like the example in getaddrinfo() with the big difference that this uses non-blocking sockets and so the connect() is most probably delayed. Because of this fact do not warn if cause is not set since most probably the last connection attempt failed and there are no more options. The failure was already reported so there is no need for an additional error message here. - Reshuffle some code in the poll loop and remove some unused global variables. -- :wq Claudio Index: http.c =================================================================== RCS file: /cvs/src/usr.sbin/rpki-client/http.c,v retrieving revision 1.15 diff -u -p -r1.15 http.c --- http.c 2 Apr 2021 17:10:12 -0000 1.15 +++ http.c 6 Apr 2021 11:09:12 -0000 @@ -124,10 +124,6 @@ struct tls_config *tls_config; uint8_t *tls_ca_mem; size_t tls_ca_size; -char *resp_buf[MAX_CONNECTIONS]; -size_t resp_bsz[MAX_CONNECTIONS]; -size_t resp_idx; - /* * Return a string that can be used in error message to identify the * connection. @@ -295,9 +291,6 @@ http_fail(size_t id) static void http_free(struct http_connection *conn) { - if (conn->state != STATE_DONE) - http_fail(conn->id); - free(conn->url); free(conn->host); free(conn->port); @@ -423,6 +416,7 @@ http_new(size_t id, char *uri, char *mod /* TODO proxy support (overload of host and port) */ if (http_resolv(conn, host, port) == -1) { + http_fail(conn->id); http_free(conn); return NULL; } @@ -473,7 +467,7 @@ http_redirect(struct http_connection *co static int http_connect(struct http_connection *conn) { - char *cause = "unknown"; + const char *cause = NULL; if (conn->fd != -1) { close(conn->fd); @@ -487,7 +481,7 @@ http_connect(struct http_connection *con conn->res = conn->res->ai_next; for (; conn->res != NULL; conn->res = conn->res->ai_next) { struct addrinfo *res = conn->res; - int fd, error, save_errno; + int fd, save_errno; fd = socket(res->ai_family, res->ai_socktype | SOCK_NONBLOCK, res->ai_protocol); @@ -503,10 +497,9 @@ http_connect(struct http_connection *con warn("%s: bind", http_info(conn->url)); } - error = connect(conn->fd, res->ai_addr, res->ai_addrlen); - if (error == -1) { + if (connect(conn->fd, res->ai_addr, res->ai_addrlen) == -1) { if (errno == EINPROGRESS) { - /* waiting for connect to finish. */ + /* wait for async connect to finish. */ return WANT_POLLOUT; } else { save_errno = errno; @@ -518,15 +511,20 @@ http_connect(struct http_connection *con } } - break; + break; /* okay we got one */ } - freeaddrinfo(conn->res0); - conn->res0 = NULL; + if (conn->fd == -1) { - warn("%s: %s", http_info(conn->url), cause); + if (cause != NULL) + warn("%s: %s", http_info(conn->url), cause); + freeaddrinfo(conn->res0); + conn->res0 = NULL; return -1; } + freeaddrinfo(conn->res0); + conn->res0 = NULL; + #if 0 /* TODO proxy connect */ if (proxyenv) @@ -1107,6 +1105,8 @@ http_do(struct http_connection *conn) switch (http_handle(conn)) { case -1: /* connection failure */ + if (conn->state != STATE_DONE) + http_fail(conn->id); http_free(conn); return -1; case 0: @@ -1118,6 +1118,8 @@ http_do(struct http_connection *conn) conn->events = POLLOUT; break; case -1: + if (conn->state != STATE_DONE) + http_fail(conn->id); http_free(conn); return -1; } @@ -1191,7 +1193,14 @@ proc_http(char *bind_addr, int fd) if (pfds[MAX_CONNECTIONS].revents & POLLHUP) break; - + if (pfds[MAX_CONNECTIONS].revents & POLLOUT) { + switch (msgbuf_write(&msgq)) { + case 0: + errx(1, "write: connection closed"); + case -1: + err(1, "write"); + } + } if (pfds[MAX_CONNECTIONS].revents & POLLIN) { struct http_connection *h; size_t id; @@ -1213,14 +1222,6 @@ proc_http(char *bind_addr, int fd) http_conns[i] = NULL; break; } - } - } - if (pfds[MAX_CONNECTIONS].revents & POLLOUT) { - switch (msgbuf_write(&msgq)) { - case 0: - errx(1, "write: connection closed"); - case -1: - err(1, "write"); } } for (i = 0; i < MAX_CONNECTIONS; i++) {