Unverified Commit 880cd5dd authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

strerror: make the strerror function use local buffers

Instead of using a fixed 256 byte buffer in the connectdata struct.

In my build, this reduces the size of the connectdata struct by 11.8%,
from 2160 to 1904 bytes with no functionality or performance loss.

This also fixes a bug in schannel's Curl_verify_certificate where it
called Curl_sspi_strerror when it should have called Curl_strerror for
string from GetLastError. the only effect would have been no text or the
wrong text being shown for the error.

Co-authored-by: Jay Satiro

Closes #3612
parent 8eddb8f4
Loading
Loading
Loading
Loading
+28 −17
Original line number Diff line number Diff line
@@ -446,9 +446,10 @@ static CURLcode bindlocal(struct connectdata *conn,
      curl_socklen_t size = sizeof(add);
      memset(&add, 0, sizeof(struct Curl_sockaddr_storage));
      if(getsockname(sockfd, (struct sockaddr *) &add, &size) < 0) {
        char buffer[STRERROR_LEN];
        data->state.os_errno = error = SOCKERRNO;
        failf(data, "getsockname() failed with errno %d: %s",
              error, Curl_strerror(conn, error));
              error, Curl_strerror(error, buffer, sizeof(buffer)));
        return CURLE_INTERFACE_FAILED;
      }
      infof(data, "Local port: %hu\n", port);
@@ -470,10 +471,12 @@ static CURLcode bindlocal(struct connectdata *conn,
    else
      break;
  }

  {
    char buffer[STRERROR_LEN];
    data->state.os_errno = error = SOCKERRNO;
    failf(data, "bind failed with errno %d: %s",
        error, Curl_strerror(conn, error));
          error, Curl_strerror(error, buffer, sizeof(buffer)));
  }

  return CURLE_INTERFACE_FAILED;
}
@@ -686,11 +689,12 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
    return;

  if(!conn->bits.reuse && !conn->bits.tcp_fastopen) {
    char buffer[STRERROR_LEN];
    len = sizeof(struct Curl_sockaddr_storage);
    if(getpeername(sockfd, (struct sockaddr*) &ssrem, &len)) {
      int error = SOCKERRNO;
      failf(data, "getpeername() failed with errno %d: %s",
            error, Curl_strerror(conn, error));
            error, Curl_strerror(error, buffer, sizeof(buffer)));
      return;
    }

@@ -699,14 +703,14 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
    if(getsockname(sockfd, (struct sockaddr*) &ssloc, &len)) {
      int error = SOCKERRNO;
      failf(data, "getsockname() failed with errno %d: %s",
            error, Curl_strerror(conn, error));
            error, Curl_strerror(error, buffer, sizeof(buffer)));
      return;
    }

    if(!getaddressinfo((struct sockaddr*)&ssrem,
                       conn->primary_ip, &conn->primary_port)) {
      failf(data, "ssrem inet_ntop() failed with errno %d: %s",
            errno, Curl_strerror(conn, errno));
            errno, Curl_strerror(errno, buffer, sizeof(buffer)));
      return;
    }
    memcpy(conn->ip_addr_str, conn->primary_ip, MAX_IPADR_LEN);
@@ -714,7 +718,7 @@ void Curl_updateconninfo(struct connectdata *conn, curl_socket_t sockfd)
    if(!getaddressinfo((struct sockaddr*)&ssloc,
                       conn->local_ip, &conn->local_port)) {
      failf(data, "ssloc inet_ntop() failed with errno %d: %s",
            errno, Curl_strerror(conn, errno));
            errno, Curl_strerror(errno, buffer, sizeof(buffer)));
      return;
    }

@@ -839,9 +843,11 @@ CURLcode Curl_is_connected(struct connectdata *conn,
      if(conn->tempaddr[i]) {
        CURLcode status;
        char ipaddress[MAX_IPADR_LEN];
        char buffer[STRERROR_LEN];
        Curl_printable_address(conn->tempaddr[i], ipaddress, MAX_IPADR_LEN);
        infof(data, "connect to %s port %ld failed: %s\n",
              ipaddress, conn->port, Curl_strerror(conn, error));
              ipaddress, conn->port,
              Curl_strerror(error, buffer, sizeof(buffer)));

        conn->timeoutms_per_addr = conn->tempaddr[i]->ai_next == NULL ?
                                   allow : allow / 2;
@@ -857,8 +863,8 @@ CURLcode Curl_is_connected(struct connectdata *conn,

  if(result) {
    /* no more addresses to try */

    const char *hostname;
    char buffer[STRERROR_LEN];

    /* if the first address family runs out of addresses to try before
       the happy eyeball timeout, go ahead and try the next family now */
@@ -878,7 +884,8 @@ CURLcode Curl_is_connected(struct connectdata *conn,
      hostname = conn->host.name;

    failf(data, "Failed to connect to %s port %ld: %s",
        hostname, conn->port, Curl_strerror(conn, error));
          hostname, conn->port,
          Curl_strerror(error, buffer, sizeof(buffer)));
  }

  return result;
@@ -892,6 +899,7 @@ static void tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
#endif
  curl_socklen_t onoff = (curl_socklen_t) 1;
  int level = IPPROTO_TCP;
  char buffer[STRERROR_LEN];

#if defined(CURL_DISABLE_VERBOSE_STRINGS)
  (void) conn;
@@ -900,7 +908,7 @@ static void tcpnodelay(struct connectdata *conn, curl_socket_t sockfd)
  if(setsockopt(sockfd, level, TCP_NODELAY, (void *)&onoff,
                sizeof(onoff)) < 0)
    infof(data, "Could not set TCP_NODELAY: %s\n",
          Curl_strerror(conn, SOCKERRNO));
          Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
  else
    infof(data, "TCP_NODELAY set\n");
#else
@@ -920,9 +928,11 @@ static void nosigpipe(struct connectdata *conn,
  struct Curl_easy *data = conn->data;
  int onoff = 1;
  if(setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, (void *)&onoff,
                sizeof(onoff)) < 0)
                sizeof(onoff)) < 0) {
    char buffer[STRERROR_LEN];
    infof(data, "Could not set SO_NOSIGPIPE: %s\n",
          Curl_strerror(conn, SOCKERRNO));
          Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
  }
}
#else
#define nosigpipe(x,y) Curl_nop_stmt
@@ -998,6 +1008,7 @@ static CURLcode singleipconnect(struct connectdata *conn,
#ifdef TCP_FASTOPEN_CONNECT
  int optval = 1;
#endif
  char buffer[STRERROR_LEN];

  *sockp = CURL_SOCKET_BAD;

@@ -1013,7 +1024,7 @@ static CURLcode singleipconnect(struct connectdata *conn,
                     ipaddress, &port)) {
    /* malformed address or bug in inet_ntop, try next address */
    failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
          errno, Curl_strerror(conn, errno));
          errno, Curl_strerror(errno, buffer, sizeof(buffer)));
    Curl_closesocket(conn, sockfd);
    return CURLE_OK;
  }
@@ -1149,7 +1160,7 @@ static CURLcode singleipconnect(struct connectdata *conn,
    default:
      /* unknown error, fallthrough and try another address! */
      infof(data, "Immediate connect fail for %s: %s\n",
            ipaddress, Curl_strerror(conn, error));
            ipaddress, Curl_strerror(error, buffer, sizeof(buffer)));
      data->state.os_errno = error;

      /* connect failed */
+8 −7
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
 * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
@@ -124,6 +124,7 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
  struct passwd pw, *pw_res;
  char pwbuf[1024];
#endif
  char buffer[STRERROR_LEN];

  /* Return if communication with ntlm_auth already set up */
  if(conn->ntlm_auth_hlpr_socket != CURL_SOCKET_BAD ||
@@ -179,13 +180,13 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)

  if(access(ntlm_auth, X_OK) != 0) {
    failf(conn->data, "Could not access ntlm_auth: %s errno %d: %s",
          ntlm_auth, errno, Curl_strerror(conn, errno));
          ntlm_auth, errno, Curl_strerror(errno, buffer, sizeof(buffer)));
    goto done;
  }

  if(socketpair(AF_UNIX, SOCK_STREAM, 0, sockfds)) {
    failf(conn->data, "Could not open socket pair. errno %d: %s",
          errno, Curl_strerror(conn, errno));
          errno, Curl_strerror(errno, buffer, sizeof(buffer)));
    goto done;
  }

@@ -194,7 +195,7 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
    sclose(sockfds[0]);
    sclose(sockfds[1]);
    failf(conn->data, "Could not fork. errno %d: %s",
          errno, Curl_strerror(conn, errno));
          errno, Curl_strerror(errno, buffer, sizeof(buffer)));
    goto done;
  }
  else if(!child_pid) {
@@ -206,13 +207,13 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
    sclose_nolog(sockfds[0]);
    if(dup2(sockfds[1], STDIN_FILENO) == -1) {
      failf(conn->data, "Could not redirect child stdin. errno %d: %s",
            errno, Curl_strerror(conn, errno));
            errno, Curl_strerror(errno, buffer, sizeof(buffer)));
      exit(1);
    }

    if(dup2(sockfds[1], STDOUT_FILENO) == -1) {
      failf(conn->data, "Could not redirect child stdout. errno %d: %s",
            errno, Curl_strerror(conn, errno));
            errno, Curl_strerror(errno, buffer, sizeof(buffer)));
      exit(1);
    }

@@ -232,7 +233,7 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)

    sclose_nolog(sockfds[1]);
    failf(conn->data, "Could not execl(). errno %d: %s",
          errno, Curl_strerror(conn, errno));
          errno, Curl_strerror(errno, buffer, sizeof(buffer)));
    exit(1);
  }

+11 −11
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
 * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
@@ -955,7 +955,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
  unsigned short port_max = 0;
  unsigned short port;
  bool possibly_non_local = TRUE;

  char buffer[STRERROR_LEN];
  char *addr = NULL;

  /* Step 1, figure out what is requested,
@@ -1064,11 +1064,10 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
  if(!host) {
    /* not an interface and not a host name, get default by extracting
       the IP from the control connection */

    sslen = sizeof(ss);
    if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
      failf(data, "getsockname() failed: %s",
          Curl_strerror(conn, SOCKERRNO) );
            Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
      free(addr);
      return CURLE_FTP_PORT_FAILED;
    }
@@ -1121,7 +1120,8 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
    break;
  }
  if(!ai) {
    failf(data, "socket failure: %s", Curl_strerror(conn, error));
    failf(data, "socket failure: %s",
          Curl_strerror(error, buffer, sizeof(buffer)));
    return CURLE_FTP_PORT_FAILED;
  }

@@ -1145,14 +1145,13 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
        /* The requested bind address is not local.  Use the address used for
         * the control connection instead and restart the port loop
         */

        infof(data, "bind(port=%hu) on non-local address failed: %s\n", port,
              Curl_strerror(conn, error) );
              Curl_strerror(error, buffer, sizeof(buffer)));

        sslen = sizeof(ss);
        if(getsockname(conn->sock[FIRSTSOCKET], sa, &sslen)) {
          failf(data, "getsockname() failed: %s",
                Curl_strerror(conn, SOCKERRNO) );
                Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
          Curl_closesocket(conn, portsock);
          return CURLE_FTP_PORT_FAILED;
        }
@@ -1162,7 +1161,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
      }
      if(error != EADDRINUSE && error != EACCES) {
        failf(data, "bind(port=%hu) failed: %s", port,
              Curl_strerror(conn, error) );
              Curl_strerror(error, buffer, sizeof(buffer)));
        Curl_closesocket(conn, portsock);
        return CURLE_FTP_PORT_FAILED;
      }
@@ -1185,7 +1184,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
  sslen = sizeof(ss);
  if(getsockname(portsock, (struct sockaddr *)sa, &sslen)) {
    failf(data, "getsockname() failed: %s",
          Curl_strerror(conn, SOCKERRNO) );
          Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
    Curl_closesocket(conn, portsock);
    return CURLE_FTP_PORT_FAILED;
  }
@@ -1193,7 +1192,8 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
  /* step 4, listen on the socket */

  if(listen(portsock, 1)) {
    failf(data, "socket failure: %s", Curl_strerror(conn, SOCKERRNO));
    failf(data, "socket failure: %s",
          Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
    Curl_closesocket(conn, portsock);
    return CURLE_FTP_PORT_FAILED;
  }
+5 −4
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
 * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
@@ -102,13 +102,14 @@ static void dump_addrinfo(struct connectdata *conn, const Curl_addrinfo *ai)
  printf("dump_addrinfo:\n");
  for(; ai; ai = ai->ai_next) {
    char buf[INET6_ADDRSTRLEN];

    char buffer[STRERROR_LEN];
    printf("    fam %2d, CNAME %s, ",
           ai->ai_family, ai->ai_canonname ? ai->ai_canonname : "<none>");
    if(Curl_printable_address(ai, buf, sizeof(buf)))
      printf("%s\n", buf);
    else
      printf("failed; %s\n", Curl_strerror(conn, SOCKERRNO));
      printf("failed; %s\n",
             Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
  }
}
#else
+5 −3
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2018, Daniel Stenberg, <daniel@haxx.se>, et al.
 * Copyright (C) 1998 - 2019, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
@@ -411,8 +411,9 @@ ssize_t Curl_send_plain(struct connectdata *conn, int num,
      *code = CURLE_AGAIN;
    }
    else {
      char buffer[STRERROR_LEN];
      failf(conn->data, "Send failure: %s",
            Curl_strerror(conn, err));
            Curl_strerror(err, buffer, sizeof(buffer)));
      conn->data->state.os_errno = err;
      *code = CURLE_SEND_ERROR;
    }
@@ -476,8 +477,9 @@ ssize_t Curl_recv_plain(struct connectdata *conn, int num, char *buf,
      *code = CURLE_AGAIN;
    }
    else {
      char buffer[STRERROR_LEN];
      failf(conn->data, "Recv failure: %s",
            Curl_strerror(conn, err));
            Curl_strerror(err, buffer, sizeof(buffer)));
      conn->data->state.os_errno = err;
      *code = CURLE_RECV_ERROR;
    }
Loading