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++) {

Reply via email to