Based on Job's work lets introduce conn_info() which prints the URI /
host plus the IP address. This may be helpful to better understand errors.

With this ip_info() becomes much simpler. I also decided to not check
snprintf returns because the buffer is big enough and afaik encoding
errors can't happen with %s.

In http_connect() when hitting the error case after the for () loop needs
a to set conn->res to the last valid res used else it will print (unknown)
for the IP (since conn->res is NULL at that time).

With this the errors will show up like this:
rpki-client: Error retrieving https://rpki.luys.cloud/rrdp/notification.xml 
(54.254.122.29): 504 Gateway Time-out
rpki-client: https://rpki.sailx.co/rrdp/notification.xml (208.82.103.214): TLS 
handshake: certificate verification failed: certificate has expired
rpki-client: https://chloe.sobornost.net/rpki/news-public.xml (127.0.0.2): 
connect: Network is unreachable
rpki-client: https://rpki1.terratransit.de/rrdp/notification.xml 
(2a01:6f0:101:17::1): connect timeout
rpki-client: https://rpki1.terratransit.de/rrdp/notification.xml 
(77.237.224.23): connect timeout

-- 
:wq Claudio

Index: http.c
===================================================================
RCS file: /cvs/src/usr.sbin/rpki-client/http.c,v
retrieving revision 1.72
diff -u -p -r1.72 http.c
--- http.c      2 Nov 2022 11:44:19 -0000       1.72
+++ http.c      2 Nov 2022 14:20:31 -0000
@@ -215,23 +215,30 @@ http_info(const char *uri)
 static const char *
 ip_info(const struct http_connection *conn)
 {
-       static char     buf[NI_MAXHOST + 3];
-       char            ipbuf[NI_MAXHOST];
-       int             ret;
-
-       assert(conn->state == STATE_CONNECT);
+       static char     ipbuf[NI_MAXHOST];
 
        if (conn->res == NULL)
-               return (" (unknown)");
+               return "unknown";
 
        if (getnameinfo(conn->res->ai_addr, conn->res->ai_addrlen, ipbuf,
            sizeof(ipbuf), NULL, 0, NI_NUMERICHOST) != 0)
-               return (" (unknown)");
+               return "unknown";
 
-       ret = snprintf(buf, sizeof(buf), " (%s)", ipbuf);
-       if (ret < 0 || (size_t)ret >= sizeof(buf))
-               err(1, NULL);
+       return ipbuf;
+}
 
+static const char *
+conn_info(const struct http_connection *conn)
+{
+       static char      buf[100 + NI_MAXHOST];
+       const char      *uri;
+
+       if (conn->req == NULL)
+               uri = conn->host;
+       else
+               uri = conn->req->uri;
+
+       snprintf(buf, sizeof(buf), "%s (%s)", http_info(uri), ip_info(conn));
        return buf;
 }
 
@@ -818,7 +825,7 @@ http_do(struct http_connection *conn, en
                break;
        default:
                errx(1, "%s: unexpected function return",
-                   http_info(conn->host));
+                   conn_info(conn));
        }
 }
 
@@ -840,6 +847,7 @@ static enum res
 http_connect(struct http_connection *conn)
 {
        const char *cause = NULL;
+       struct addrinfo *res;
 
        assert(conn->fd == -1);
        conn->state = STATE_CONNECT;
@@ -850,9 +858,9 @@ http_connect(struct http_connection *con
        else
                conn->res = conn->res->ai_next;
        for (; conn->res != NULL; conn->res = conn->res->ai_next) {
-               struct addrinfo *res = conn->res;
                int fd, save_errno;
 
+               res = conn->res;
                fd = socket(res->ai_family,
                    res->ai_socktype | SOCK_NONBLOCK, res->ai_protocol);
                if (fd == -1) {
@@ -891,8 +899,10 @@ http_connect(struct http_connection *con
        }
 
        if (conn->fd == -1) {
-               if (cause != NULL)
-                       warn("%s: %s", http_info(conn->req->uri), cause);
+               if (cause != NULL) {
+                       conn->res = res;
+                       warn("%s: %s", conn_info(conn), cause);
+               }
                return http_failed(conn);
        }
 
@@ -910,12 +920,12 @@ http_finish_connect(struct http_connecti
 
        len = sizeof(error);
        if (getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, &error, &len) == -1) {
-               warn("%s: getsockopt SO_ERROR", http_info(conn->req->uri));
+               warn("%s: getsockopt SO_ERROR", conn_info(conn));
                return http_connect_failed(conn);
        }
        if (error != 0) {
                errno = error;
-               warn("%s: connect", http_info(conn->req->uri));
+               warn("%s: connect", conn_info(conn));
                return http_connect_failed(conn);
        }
 
@@ -936,12 +946,12 @@ http_tls_connect(struct http_connection 
                return http_failed(conn);
        }
        if (tls_configure(conn->tls, tls_config) == -1) {
-               warnx("%s: TLS configuration: %s\n", http_info(conn->req->uri),
+               warnx("%s: TLS configuration: %s\n", conn_info(conn),
                    tls_error(conn->tls));
                return http_failed(conn);
        }
        if (tls_connect_socket(conn->tls, conn->fd, conn->host) == -1) {
-               warnx("%s: TLS connect: %s\n", http_info(conn->req->uri),
+               warnx("%s: TLS connect: %s\n", conn_info(conn),
                    tls_error(conn->tls));
                return http_failed(conn);
        }
@@ -957,7 +967,7 @@ http_tls_handshake(struct http_connectio
 {
        switch (tls_handshake(conn->tls)) {
        case -1:
-               warnx("%s: TLS handshake: %s", http_info(conn->req->uri),
+               warnx("%s: TLS handshake: %s", conn_info(conn),
                    tls_error(conn->tls));
                return http_failed(conn);
        case TLS_WANT_POLLIN:
@@ -1089,7 +1099,7 @@ http_parse_status(struct http_connection
 
        cp = strchr(buf, ' ');
        if (cp == NULL) {
-               warnx("Improper response from %s", http_info(conn->host));
+               warnx("Improper response from %s", conn_info(conn));
                return -1;
        } else
                cp++;
@@ -1098,7 +1108,7 @@ http_parse_status(struct http_connection
        status = strtonum(ststr, 100, 599, &errstr);
        if (errstr != NULL) {
                strnvis(gerror, cp, sizeof gerror, VIS_SAFE);
-               warnx("Error retrieving %s: %s", http_info(conn->host),
+               warnx("Error retrieving %s: %s", conn_info(conn),
                    gerror);
                return -1;
        }
@@ -1111,7 +1121,7 @@ http_parse_status(struct http_connection
        case 308:       /* Redirect: permanent redirect */
                if (conn->req->redirect_loop++ > 10) {
                        warnx("%s: Too many redirections requested",
-                           http_info(conn->host));
+                           conn_info(conn));
                        return -1;
                }
                /* FALLTHROUGH */
@@ -1125,7 +1135,7 @@ http_parse_status(struct http_connection
                break;
        default:
                strnvis(gerror, cp, sizeof gerror, VIS_SAFE);
-               warnx("Error retrieving %s: %s", http_info(conn->host),
+               warnx("Error retrieving %s: %s", conn_info(conn),
                    gerror);
                return -1;
        }
@@ -1202,7 +1212,7 @@ http_parse_header(struct http_connection
                conn->iosz = strtonum(cp, 0, MAX_CONTENTLEN, &errstr);
                if (errstr != NULL) {
                        warnx("Content-Length of %s is %s",
-                           http_info(conn->req->uri), errstr);
+                           conn_info(conn), errstr);
                        return -1;
                }
        } else if (http_isredirect(conn) &&
@@ -1344,7 +1354,7 @@ read_more:
        s = tls_read(conn->tls, conn->buf + conn->bufpos,
            conn->bufsz - conn->bufpos);
        if (s == -1) {
-               warnx("%s: TLS read: %s", http_info(conn->host),
+               warnx("%s: TLS read: %s", conn_info(conn),
                    tls_error(conn->tls));
                return http_failed(conn);
        } else if (s == TLS_WANT_POLLIN) {
@@ -1356,7 +1366,7 @@ read_more:
        if (s == 0) {
                if (conn->req)
                        warnx("%s: short read, connection closed",
-                           http_info(conn->req->uri));
+                           conn_info(conn));
                return http_failed(conn);
        }
 
@@ -1474,7 +1484,7 @@ again:
                if (buf == NULL)
                        goto read_more;
                if (http_parse_chunked(conn, buf) != 0) {
-                       warnx("%s: bad chunk encoding", http_info(conn->host));
+                       warnx("%s: bad chunk encoding", conn_info(conn));
                        free(buf);
                        return http_failed(conn);
                }
@@ -1495,7 +1505,7 @@ again:
                        goto read_more;
                /* expect empty line to finish a chunk of data */
                if (*buf != '\0') {
-                       warnx("%s: bad chunk encoding", http_info(conn->host));
+                       warnx("%s: bad chunk encoding", conn_info(conn));
                        free(buf);
                        return http_failed(conn);
                }
@@ -1533,7 +1543,7 @@ http_write(struct http_connection *conn)
                s = tls_write(conn->tls, conn->buf + conn->bufpos,
                    conn->bufsz - conn->bufpos);
                if (s == -1) {
-                       warnx("%s: TLS write: %s", http_info(conn->host),
+                       warnx("%s: TLS write: %s", conn_info(conn),
                            tls_error(conn->tls));
                        return http_failed(conn);
                } else if (s == TLS_WANT_POLLIN) {
@@ -1568,14 +1578,14 @@ proxy_read(struct http_connection *conn)
        s = read(conn->fd, conn->buf + conn->bufpos,
            conn->bufsz - conn->bufpos);
        if (s == -1) {
-               warn("%s: read", http_info(conn->host));
+               warn("%s: read", conn_info(conn));
                return http_failed(conn);
        }
 
        if (s == 0) {
                if (conn->req)
                        warnx("%s: short read, connection closed",
-                           http_info(conn->host));
+                           conn_info(conn));
                return http_failed(conn);
        }
 
@@ -1629,7 +1639,7 @@ proxy_write(struct http_connection *conn
        s = write(conn->fd, conn->buf + conn->bufpos,
            conn->bufsz - conn->bufpos);
        if (s == -1) {
-               warn("%s: write", http_info(conn->host));
+               warn("%s: write", conn_info(conn));
                return http_failed(conn);
        }
        conn->bufpos += s;
@@ -1692,13 +1702,13 @@ data_write(struct http_connection *conn)
 
        s = write(conn->req->outfd, conn->buf, bsz);
        if (s == -1) {
-               warn("%s: data write", http_info(conn->req->uri));
+               warn("%s: data write", conn_info(conn));
                return http_failed(conn);
        }
 
        conn->totalsz += s;
        if (conn->totalsz > MAX_CONTENTLEN) {
-               warn("%s: too much data offered", http_info(conn->req->uri));
+               warn("%s: too much data offered", conn_info(conn));
                return http_failed(conn);
        }
 
@@ -1946,13 +1956,12 @@ proc_http(char *bind_addr, int fd)
                                http_do(conn, http_handle);
                        else if (conn->io_time <= now) {
                                if (conn->state == STATE_CONNECT) {
-                                       warnx("%s%s: connect timeout",
-                                           ip_info(conn),
-                                           http_info(conn->host));
+                                       warnx("%s: connect timeout",
+                                           conn_info(conn));
                                        http_do(conn, http_connect_failed);
                                } else {
                                        warnx("%s: timeout, connection closed",
-                                           http_info(conn->host));
+                                           conn_info(conn));
                                        http_do(conn, http_failed);
                                }
                        }

Reply via email to