Browse Source

cf-socket: keep sockaddr local in the socket filters

- copy `struct Curl_addrinfo` on filter setup into context
- remove `struct Curl_addrinfoi *` with `struct Curl_sockaddr_ex *` in
  connectdata that is set and NULLed by the socket filter
- this means we have no reference to the resolver info in connectdata or
  its filters
- trigger the CF_CTRL_CONN_INFO_UPDATE event when the complete filter
  chain reaches connected status
- update easy handle connection information on CF_CTRL_DATA_SETUP event.

Closes #10213
Stefan Eissing 1 year ago
parent
commit
6a8d7ef981
8 changed files with 174 additions and 140 deletions
  1. 154 122
      lib/cf-socket.c
  2. 5 1
      lib/cfilters.c
  3. 2 2
      lib/ftp.c
  4. 4 3
      lib/krb5.c
  5. 1 1
      lib/sendf.c
  6. 5 4
      lib/tftp.c
  7. 0 3
      lib/url.c
  8. 3 4
      lib/urldata.h

+ 154 - 122
lib/cf-socket.c

@@ -203,28 +203,10 @@ tcpkeepalive(struct Curl_easy *data,
   }
 }
 
-/*
- * Create a socket based on info from 'conn' and 'ai'.
- *
- * 'addr' should be a pointer to the correct struct to get data back, or NULL.
- * 'sockfd' must be a pointer to a socket descriptor.
- *
- * If the open socket callback is set, used that!
- *
- */
-CURLcode Curl_socket_open(struct Curl_easy *data,
-                            const struct Curl_addrinfo *ai,
-                            struct Curl_sockaddr_ex *addr,
-                            int transport,
-                            curl_socket_t *sockfd)
+static void assign_sockaddr_ex(struct Curl_sockaddr_ex *dest,
+                               const struct Curl_addrinfo *ai,
+                               int transport)
 {
-  struct connectdata *conn = data->conn;
-  struct Curl_sockaddr_ex dummy;
-
-  if(!addr)
-    /* if the caller doesn't want info back, use a local temp copy */
-    addr = &dummy;
-
   /*
    * The Curl_sockaddr_ex structure is basically libcurl's external API
    * curl_sockaddr structure with enough space available to directly hold
@@ -232,28 +214,34 @@ CURLcode Curl_socket_open(struct Curl_easy *data,
    * will be used to pass / receive data to/from the fopensocket callback
    * if this has been set, before that, it is initialized from parameters.
    */
-
-  addr->family = ai->ai_family;
+  dest->family = ai->ai_family;
   switch(transport) {
   case TRNSPRT_TCP:
-    addr->socktype = SOCK_STREAM;
-    addr->protocol = IPPROTO_TCP;
+    dest->socktype = SOCK_STREAM;
+    dest->protocol = IPPROTO_TCP;
     break;
   case TRNSPRT_UNIX:
-    addr->socktype = SOCK_STREAM;
-    addr->protocol = IPPROTO_IP;
+    dest->socktype = SOCK_STREAM;
+    dest->protocol = IPPROTO_IP;
     break;
   default: /* UDP and QUIC */
-    addr->socktype = SOCK_DGRAM;
-    addr->protocol = IPPROTO_UDP;
+    dest->socktype = SOCK_DGRAM;
+    dest->protocol = IPPROTO_UDP;
     break;
   }
-  addr->addrlen = ai->ai_addrlen;
+  dest->addrlen = ai->ai_addrlen;
 
-  if(addr->addrlen > sizeof(struct Curl_sockaddr_storage))
-     addr->addrlen = sizeof(struct Curl_sockaddr_storage);
-  memcpy(&addr->sa_addr, ai->ai_addr, addr->addrlen);
+  if(dest->addrlen > sizeof(struct Curl_sockaddr_storage))
+     dest->addrlen = sizeof(struct Curl_sockaddr_storage);
+  memcpy(&dest->sa_addr, ai->ai_addr, dest->addrlen);
+}
 
+static CURLcode socket_open(struct Curl_easy *data,
+                            struct Curl_sockaddr_ex *addr,
+                            curl_socket_t *sockfd)
+{
+  DEBUGASSERT(data);
+  DEBUGASSERT(data->conn);
   if(data->set.fopensocket) {
    /*
     * If the opensocket callback is set, all the destination address
@@ -278,17 +266,40 @@ CURLcode Curl_socket_open(struct Curl_easy *data,
     /* no socket, no connection */
     return CURLE_COULDNT_CONNECT;
 
-  (void)conn;
 #if defined(ENABLE_IPV6) && defined(HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID)
-  if(conn->scope_id && (addr->family == AF_INET6)) {
+  if(data->conn->scope_id && (addr->family == AF_INET6)) {
     struct sockaddr_in6 * const sa6 = (void *)&addr->sa_addr;
-    sa6->sin6_scope_id = conn->scope_id;
+    sa6->sin6_scope_id = data->conn->scope_id;
   }
 #endif
-
   return CURLE_OK;
 }
 
+/*
+ * Create a socket based on info from 'conn' and 'ai'.
+ *
+ * 'addr' should be a pointer to the correct struct to get data back, or NULL.
+ * 'sockfd' must be a pointer to a socket descriptor.
+ *
+ * If the open socket callback is set, used that!
+ *
+ */
+CURLcode Curl_socket_open(struct Curl_easy *data,
+                            const struct Curl_addrinfo *ai,
+                            struct Curl_sockaddr_ex *addr,
+                            int transport,
+                            curl_socket_t *sockfd)
+{
+  struct Curl_sockaddr_ex dummy;
+
+  if(!addr)
+    /* if the caller doesn't want info back, use a local temp copy */
+    addr = &dummy;
+
+  assign_sockaddr_ex(addr, ai, transport);
+  return socket_open(data, addr, sockfd);
+}
+
 static int socket_close(struct Curl_easy *data, struct connectdata *conn,
                         int use_callback, curl_socket_t sock)
 {
@@ -744,11 +755,12 @@ CURLcode Curl_socket_connect_result(struct Curl_easy *data,
 
 struct cf_socket_ctx {
   int transport;
-  const struct Curl_addrinfo *ai;
+  struct Curl_sockaddr_ex addr;      /* address to connect to */
   curl_socket_t sock;                /* current attempt socket */
-  struct Curl_sockaddr_ex r_addr;    /* remote address sock is trying */
   char r_ip[MAX_IPADR_LEN];          /* remote IP as string */
   int r_port;                        /* remote port number */
+  char l_ip[MAX_IPADR_LEN];          /* local IP as string */
+  int l_port;                        /* local port number */
   int error;                         /* errno of last failure or 0 */
   BIT(accepted);                     /* socket was accepted, not connected */
   BIT(active);
@@ -785,6 +797,8 @@ static void cf_socket_close(struct Curl_cfilter *cf, struct Curl_easy *data)
     ctx->active = FALSE;
   }
 
+  if(cf->sockindex == FIRSTSOCKET)
+    cf->conn->remote_addr = NULL;
   cf->connected = FALSE;
 }
 
@@ -797,6 +811,56 @@ static void cf_socket_destroy(struct Curl_cfilter *cf, struct Curl_easy *data)
   cf->ctx = NULL;
 }
 
+static CURLcode set_local_ip(struct Curl_cfilter *cf,
+                             struct Curl_easy *data)
+{
+  struct cf_socket_ctx *ctx = cf->ctx;
+
+#ifdef HAVE_GETSOCKNAME
+  char buffer[STRERROR_LEN];
+  struct Curl_sockaddr_storage ssloc;
+  curl_socklen_t slen = sizeof(struct Curl_sockaddr_storage);
+
+  memset(&ssloc, 0, sizeof(ssloc));
+  if(getsockname(ctx->sock, (struct sockaddr*) &ssloc, &slen)) {
+    int error = SOCKERRNO;
+    failf(data, "getsockname() failed with errno %d: %s",
+          error, Curl_strerror(error, buffer, sizeof(buffer)));
+    return CURLE_FAILED_INIT;
+  }
+  if(!Curl_addr2string((struct sockaddr*)&ssloc, slen,
+                       ctx->l_ip, &ctx->l_port)) {
+    failf(data, "ssloc inet_ntop() failed with errno %d: %s",
+          errno, Curl_strerror(errno, buffer, sizeof(buffer)));
+    return CURLE_FAILED_INIT;
+  }
+#else
+  (void)data;
+  ctx->l_ip[0] = 0;
+  ctx->l_port = -1;
+#endif
+  return CURLE_OK;
+}
+
+static CURLcode set_remote_ip(struct Curl_cfilter *cf,
+                              struct Curl_easy *data)
+{
+  struct cf_socket_ctx *ctx = cf->ctx;
+
+  /* store remote address and port used in this connection attempt */
+  if(!Curl_addr2string(&ctx->addr.sa_addr, ctx->addr.addrlen,
+                       ctx->r_ip, &ctx->r_port)) {
+    char buffer[STRERROR_LEN];
+
+    ctx->error = errno;
+    /* malformed address or bug in inet_ntop, try next address */
+    failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
+          errno, Curl_strerror(errno, buffer, sizeof(buffer)));
+    return CURLE_FAILED_INIT;
+  }
+  return CURLE_OK;
+}
+
 static CURLcode cf_socket_open(struct Curl_cfilter *cf,
                               struct Curl_easy *data)
 {
@@ -809,25 +873,16 @@ static CURLcode cf_socket_open(struct Curl_cfilter *cf,
 
   (void)data;
   ctx->sock = CURL_SOCKET_BAD;
-  result = Curl_socket_open(data, ctx->ai, &ctx->r_addr,
-                              ctx->transport, &ctx->sock);
+  result = socket_open(data, &ctx->addr, &ctx->sock);
   if(result)
     goto out;
 
-  /* store remote address and port used in this connection attempt */
-  if(!Curl_addr2string(&ctx->r_addr.sa_addr, ctx->r_addr.addrlen,
-                       ctx->r_ip, &ctx->r_port)) {
-    char buffer[STRERROR_LEN];
-
-    ctx->error = errno;
-    /* malformed address or bug in inet_ntop, try next address */
-    failf(data, "sa_addr inet_ntop() failed with errno %d: %s",
-          errno, Curl_strerror(errno, buffer, sizeof(buffer)));
-    result = CURLE_FAILED_INIT;
+  result = set_remote_ip(cf, data);
+  if(result)
     goto out;
-  }
+
 #ifdef ENABLE_IPV6
-  if(ctx->r_addr.family == AF_INET6)
+  if(ctx->addr.family == AF_INET6)
     ipmsg = "  Trying [%s]:%d...";
   else
 #endif
@@ -835,12 +890,12 @@ static CURLcode cf_socket_open(struct Curl_cfilter *cf,
   infof(data, ipmsg, ctx->r_ip, ctx->r_port);
 
 #ifdef ENABLE_IPV6
-  is_tcp = (ctx->r_addr.family == AF_INET
-            || ctx->r_addr.family == AF_INET6) &&
-           ctx->r_addr.socktype == SOCK_STREAM;
+  is_tcp = (ctx->addr.family == AF_INET
+            || ctx->addr.family == AF_INET6) &&
+           ctx->addr.socktype == SOCK_STREAM;
 #else
-  is_tcp = (ctx->r_addr.family == AF_INET) &&
-           ctx->r_addr.socktype == SOCK_STREAM;
+  is_tcp = (ctx->addr.family == AF_INET) &&
+           ctx->addr.socktype == SOCK_STREAM;
 #endif
   if(is_tcp && data->set.tcp_nodelay)
     tcpnodelay(data, ctx->sock);
@@ -869,13 +924,13 @@ static CURLcode cf_socket_open(struct Curl_cfilter *cf,
   }
 
   /* possibly bind the local end to an IP, interface or port */
-  if(ctx->r_addr.family == AF_INET
+  if(ctx->addr.family == AF_INET
 #ifdef ENABLE_IPV6
-     || ctx->r_addr.family == AF_INET6
+     || ctx->addr.family == AF_INET6
 #endif
     ) {
-    result = bindlocal(data, cf->conn, ctx->sock, ctx->r_addr.family,
-                       Curl_ipv6_scope(&ctx->r_addr.sa_addr));
+    result = bindlocal(data, cf->conn, ctx->sock, ctx->addr.family,
+                       Curl_ipv6_scope(&ctx->addr.sa_addr));
     if(result) {
       if(result == CURLE_UNSUPPORTED_PROTOCOL) {
         /* The address family is not supported on this interface.
@@ -897,6 +952,7 @@ out:
     }
   }
   else if(isconnected) {
+    set_local_ip(cf, data);
     cf->connected = TRUE;
   }
   return result;
@@ -922,34 +978,34 @@ static int do_connect(struct Curl_cfilter *cf, struct Curl_easy *data)
       endpoints.sae_srcif = 0;
       endpoints.sae_srcaddr = NULL;
       endpoints.sae_srcaddrlen = 0;
-      endpoints.sae_dstaddr = &ctx->r_addr.sa_addr;
-      endpoints.sae_dstaddrlen = ctx->r_addr.addrlen;
+      endpoints.sae_dstaddr = &ctx->addr.sa_addr;
+      endpoints.sae_dstaddrlen = ctx->addr.addrlen;
 
       rc = connectx(ctx->sock, &endpoints, SAE_ASSOCID_ANY,
                     CONNECT_RESUME_ON_READ_WRITE | CONNECT_DATA_IDEMPOTENT,
                     NULL, 0, NULL, NULL);
     }
     else {
-      rc = connect(ctx->sock, &ctx->r_addr.sa_addr, ctx->r_addr.addrlen);
+      rc = connect(ctx->sock, &ctx->addr.sa_addr, ctx->addr.addrlen);
     }
 #  else
-    rc = connect(ctx->sock, &ctx->r_addr.sa_addr, ctx->r_addr.addrlen);
+    rc = connect(ctx->sock, &ctx->addr.sa_addr, ctx->addr.addrlen);
 #  endif /* HAVE_BUILTIN_AVAILABLE */
 #elif defined(TCP_FASTOPEN_CONNECT) /* Linux >= 4.11 */
     if(setsockopt(ctx->sock, IPPROTO_TCP, TCP_FASTOPEN_CONNECT,
                   (void *)&optval, sizeof(optval)) < 0)
       infof(data, "Failed to enable TCP Fast Open on fd %d", ctx->sock);
 
-    rc = connect(ctx->sock, &ctx->r_addr.sa_addr, ctx->r_addr.addrlen);
+    rc = connect(ctx->sock, &ctx->addr.sa_addr, ctx->addr.addrlen);
 #elif defined(MSG_FASTOPEN) /* old Linux */
     if(cf->conn->given->flags & PROTOPT_SSL)
-      rc = connect(ctx->sock, &ctx->r_addr.sa_addr, ctx->r_addr.addrlen);
+      rc = connect(ctx->sock, &ctx->addr.sa_addr, ctx->addr.addrlen);
     else
       rc = 0; /* Do nothing */
 #endif
   }
   else {
-    rc = connect(ctx->sock, &ctx->r_addr.sa_addr, ctx->r_addr.addrlen);
+    rc = connect(ctx->sock, &ctx->addr.sa_addr, ctx->addr.addrlen);
   }
   return rc;
 }
@@ -1005,6 +1061,7 @@ static CURLcode cf_tcp_connect(struct Curl_cfilter *cf,
   else if(rc == CURL_CSELECT_OUT || cf->conn->bits.tcp_fastopen) {
     if(verifyconnect(ctx->sock, &ctx->error)) {
       /* we are connected with TCP, awesome! */
+      set_local_ip(cf, data);
       *done = TRUE;
       cf->connected = TRUE;
       return CURLE_OK;
@@ -1101,62 +1158,32 @@ static ssize_t cf_socket_recv(struct Curl_cfilter *cf, struct Curl_easy *data,
   return nread;
 }
 
-/* retrieves the start/end point information of a socket of an established
-   connection */
-static void conninfo_local(struct Curl_easy *data, curl_socket_t sockfd,
-                           char *local_ip, int *local_port)
-{
-#ifdef HAVE_GETSOCKNAME
-  char buffer[STRERROR_LEN];
-  struct Curl_sockaddr_storage ssloc;
-  curl_socklen_t slen = sizeof(struct Curl_sockaddr_storage);
-
-  memset(&ssloc, 0, sizeof(ssloc));
-  if(getsockname(sockfd, (struct sockaddr*) &ssloc, &slen)) {
-    int error = SOCKERRNO;
-    failf(data, "getsockname() failed with errno %d: %s",
-          error, Curl_strerror(error, buffer, sizeof(buffer)));
-    return;
-  }
-  if(!Curl_addr2string((struct sockaddr*)&ssloc, slen,
-                       local_ip, local_port)) {
-    failf(data, "ssloc inet_ntop() failed with errno %d: %s",
-          errno, Curl_strerror(errno, buffer, sizeof(buffer)));
-    return;
-  }
-#else
-  (void)data;
-  (void)sockfd;
-  (void)local_ip;
-  (void)local_port;
-#endif
-}
-
-/* retrieves the start/end point information of a socket of an established
-   connection */
-static void conninfo_remote(struct Curl_easy *data,
-                            struct connectdata *conn, curl_socket_t sockfd)
+static void conn_set_primary_ip(struct Curl_cfilter *cf,
+                                struct Curl_easy *data)
 {
+  struct cf_socket_ctx *ctx = cf->ctx;
 #ifdef HAVE_GETPEERNAME
   char buffer[STRERROR_LEN];
   struct Curl_sockaddr_storage ssrem;
   curl_socklen_t plen;
   int port;
-  plen = sizeof(struct Curl_sockaddr_storage);
-  memset(&ssrem, 0, sizeof(ssrem));
-  if(getpeername(sockfd, (struct sockaddr*) &ssrem, &plen)) {
+
+  plen = sizeof(ssrem);
+  memset(&ssrem, 0, plen);
+  if(getpeername(ctx->sock, (struct sockaddr*) &ssrem, &plen)) {
     int error = SOCKERRNO;
     failf(data, "getpeername() failed with errno %d: %s",
           error, Curl_strerror(error, buffer, sizeof(buffer)));
     return;
   }
   if(!Curl_addr2string((struct sockaddr*)&ssrem, plen,
-                       conn->primary_ip, &port)) {
+                       cf->conn->primary_ip, &port)) {
     failf(data, "ssrem inet_ntop() failed with errno %d: %s",
           errno, Curl_strerror(errno, buffer, sizeof(buffer)));
     return;
   }
 #else
+  cf->conn->primary_ip[0] = 0;
   (void)data;
   (void)conn;
   (void)sockfd;
@@ -1166,22 +1193,17 @@ static void conninfo_remote(struct Curl_easy *data,
 static void cf_socket_active(struct Curl_cfilter *cf, struct Curl_easy *data)
 {
   struct cf_socket_ctx *ctx = cf->ctx;
-  char local_ip[MAX_IPADR_LEN] = "";
-  int local_port = -1;
 
   /* use this socket from now on */
-  DEBUGASSERT(ctx);
-  DEBUGASSERT(cf->conn);
   cf->conn->sock[cf->sockindex] = ctx->sock;
-
+  /* the first socket info gets set at conn and data */
   if(cf->sockindex == FIRSTSOCKET) {
-    cf->conn->ip_addr = ctx->ai;
+    cf->conn->remote_addr = &ctx->addr;
   #ifdef ENABLE_IPV6
-    cf->conn->bits.ipv6 = (ctx->ai->ai_family == AF_INET6)? TRUE : FALSE;
+    cf->conn->bits.ipv6 = (ctx->addr.family == AF_INET6)? TRUE : FALSE;
   #endif
-    conninfo_remote(data, cf->conn, ctx->sock);
-    conninfo_local(data, ctx->sock, local_ip, &local_port);
-    Curl_persistconninfo(data, cf->conn, local_ip, local_port);
+    conn_set_primary_ip(cf, data);
+    Curl_persistconninfo(data, cf->conn, ctx->l_ip, ctx->l_port);
   }
   ctx->active = TRUE;
 }
@@ -1190,12 +1212,17 @@ static CURLcode cf_socket_cntrl(struct Curl_cfilter *cf,
                                 struct Curl_easy *data,
                                 int event, int arg1, void *arg2)
 {
+  struct cf_socket_ctx *ctx = cf->ctx;
+
   (void)arg1;
   (void)arg2;
   switch(event) {
   case CF_CTRL_CONN_INFO_UPDATE:
     cf_socket_active(cf, data);
     break;
+  case CF_CTRL_DATA_SETUP:
+    Curl_persistconninfo(data, cf->conn, ctx->l_ip, ctx->l_port);
+    break;
   }
   return CURLE_OK;
 }
@@ -1270,7 +1297,7 @@ CURLcode Curl_cf_tcp_create(struct Curl_cfilter **pcf,
     goto out;
   }
   ctx->transport = TRNSPRT_TCP;
-  ctx->ai = ai;
+  assign_sockaddr_ex(&ctx->addr, ai, ctx->transport);
   ctx->sock = CURL_SOCKET_BAD;
 
   result = Curl_cf_create(&cf, &cft_tcp, ctx);
@@ -1307,6 +1334,7 @@ static CURLcode cf_udp_connect(struct Curl_cfilter *cf,
       }
     }
     else {
+      set_local_ip(cf, data);
       *done = TRUE;
       cf->connected = TRUE;
     }
@@ -1348,7 +1376,7 @@ CURLcode Curl_cf_udp_create(struct Curl_cfilter **pcf,
     goto out;
   }
   ctx->transport = TRNSPRT_UDP;
-  ctx->ai = ai;
+  assign_sockaddr_ex(&ctx->addr, ai, ctx->transport);
   ctx->sock = CURL_SOCKET_BAD;
 
   result = Curl_cf_create(&cf, &cft_udp, ctx);
@@ -1398,7 +1426,7 @@ CURLcode Curl_cf_unix_create(struct Curl_cfilter **pcf,
     goto out;
   }
   ctx->transport = TRNSPRT_UNIX;
-  ctx->ai = ai;
+  assign_sockaddr_ex(&ctx->addr, ai, ctx->transport);
   ctx->sock = CURL_SOCKET_BAD;
 
   result = Curl_cf_create(&cf, &cft_unix, ctx);
@@ -1470,6 +1498,8 @@ CURLcode Curl_conn_tcp_listen_set(struct Curl_easy *data,
   Curl_conn_cf_add(data, conn, sockindex, cf);
 
   conn->sock[sockindex] = ctx->sock;
+  set_remote_ip(cf, data);
+  set_local_ip(cf, data);
   ctx->active = TRUE;
   cf->connected = TRUE;
   CF_DEBUGF(infof(data, CFMSG(cf, "Curl_conn_tcp_listen_set(%d)"),
@@ -1499,6 +1529,8 @@ CURLcode Curl_conn_tcp_accepted_set(struct Curl_easy *data,
   socket_close(data, conn, TRUE, ctx->sock);
   ctx->sock = *s;
   conn->sock[sockindex] = ctx->sock;
+  set_remote_ip(cf, data);
+  set_local_ip(cf, data);
   ctx->active = TRUE;
   ctx->accepted = TRUE;
   cf->connected = TRUE;
@@ -1524,7 +1556,7 @@ CURLcode Curl_cf_socket_peek(struct Curl_cfilter *cf,
     struct cf_socket_ctx *ctx = cf->ctx;
 
     *psock = ctx->sock;
-    *paddr = &ctx->r_addr;
+    *paddr = &ctx->addr;
     *premote_ip_str = ctx->r_ip;
     *premote_port = ctx->r_port;
     return CURLE_OK;

+ 5 - 1
lib/cfilters.c

@@ -369,10 +369,14 @@ CURLcode Curl_conn_connect(struct Curl_easy *data,
 
   cf = data->conn->cfilter[sockindex];
   DEBUGASSERT(cf);
+  if(!cf)
+    return CURLE_FAILED_INIT;
+
   *done = cf->connected;
   if(!*done) {
-    result = cf->cft->connect (cf, data, blocking, done);
+    result = cf->cft->connect(cf, data, blocking, done);
     if(!result && *done) {
+      Curl_conn_ev_update_info(data, data->conn);
       data->conn->keepalive = Curl_now();
     }
   }

+ 2 - 2
lib/ftp.c

@@ -1010,9 +1010,9 @@ static CURLcode ftp_state_use_port(struct Curl_easy *data,
 
     if(*addr != '\0') {
       /* attempt to get the address of the given interface name */
-      switch(Curl_if2ip(conn->ip_addr->ai_family,
+      switch(Curl_if2ip(conn->remote_addr->family,
 #ifdef ENABLE_IPV6
-                        Curl_ipv6_scope(conn->ip_addr->ai_addr),
+                        Curl_ipv6_scope(&conn->remote_addr->sa_addr),
                         conn->scope_id,
 #endif
                         addr, hbuf, sizeof(hbuf))) {

+ 4 - 3
lib/krb5.c

@@ -46,6 +46,7 @@
 #endif
 
 #include "urldata.h"
+#include "cf-socket.h"
 #include "curl_base64.h"
 #include "ftp.h"
 #include "curl_gssapi.h"
@@ -207,8 +208,8 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn)
   gss_ctx_id_t *context = app_data;
   struct gss_channel_bindings_struct chan;
   size_t base64_sz = 0;
-  struct sockaddr_in **remote_addr =
-    (struct sockaddr_in **)&conn->ip_addr->ai_addr;
+  struct sockaddr_in *remote_addr =
+    (struct sockaddr_in *)&conn->remote_addr->sa_addr;
   char *stringp;
 
   if(getsockname(conn->sock[FIRSTSOCKET],
@@ -220,7 +221,7 @@ krb5_auth(void *app_data, struct Curl_easy *data, struct connectdata *conn)
   chan.initiator_address.value = &conn->local_addr.sin_addr.s_addr;
   chan.acceptor_addrtype = GSS_C_AF_INET;
   chan.acceptor_address.length = l - 4;
-  chan.acceptor_address.value = &(*remote_addr)->sin_addr.s_addr;
+  chan.acceptor_address.value = &remote_addr->sin_addr.s_addr;
   chan.application_data.length = 0;
   chan.application_data.value = NULL;
 

+ 1 - 1
lib/sendf.c

@@ -363,7 +363,7 @@ ssize_t Curl_send_plain(struct Curl_easy *data, int num,
 #if defined(MSG_FASTOPEN) && !defined(TCP_FASTOPEN_CONNECT) /* Linux */
   if(conn->bits.tcp_fastopen) {
     bytes_written = sendto(sockfd, mem, len, MSG_FASTOPEN,
-                           conn->ip_addr->ai_addr, conn->ip_addr->ai_addrlen);
+                           conn->remote_addr.addr, conn->remote_addr.addrlen);
     conn->bits.tcp_fastopen = FALSE;
   }
   else

+ 5 - 4
lib/tftp.c

@@ -48,6 +48,7 @@
 
 #include "urldata.h"
 #include <curl/curl.h>
+#include "cf-socket.h"
 #include "transfer.h"
 #include "sendf.h"
 #include "tftp.h"
@@ -529,8 +530,8 @@ static CURLcode tftp_send_first(struct tftp_state_data *state,
        not have a size_t argument, like older unixes that want an 'int' */
     senddata = sendto(state->sockfd, (void *)state->spacket.data,
                       (SEND_TYPE_ARG3)sbytes, 0,
-                      data->conn->ip_addr->ai_addr,
-                      data->conn->ip_addr->ai_addrlen);
+                      &data->conn->remote_addr->sa_addr,
+                      data->conn->remote_addr->addrlen);
     if(senddata != (ssize_t)sbytes) {
       char buffer[STRERROR_LEN];
       failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
@@ -1014,7 +1015,7 @@ static CURLcode tftp_connect(struct Curl_easy *data, bool *done)
   state->requested_blksize = blksize;
 
   ((struct sockaddr *)&state->local_addr)->sa_family =
-    (CURL_SA_FAMILY_T)(conn->ip_addr->ai_family);
+    (CURL_SA_FAMILY_T)(conn->remote_addr->family);
 
   tftp_set_timeouts(state);
 
@@ -1033,7 +1034,7 @@ static CURLcode tftp_connect(struct Curl_easy *data, bool *done)
      * IPv4 and IPv6...
      */
     int rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr,
-                  conn->ip_addr->ai_addrlen);
+                  conn->remote_addr->addrlen);
     if(rc) {
       char buffer[STRERROR_LEN];
       failf(data, "bind() failed; %s",

+ 0 - 3
lib/url.c

@@ -3381,9 +3381,6 @@ static void reuse_conn(struct Curl_easy *data,
   existing->hostname_resolve = temp->hostname_resolve;
   temp->hostname_resolve = NULL;
 
-  /* persist existing connection info in data */
-  Curl_conn_ev_update_info(data, existing);
-
   conn_reset_all_postponed_data(temp); /* free buffers */
 
   /* re-use init */

+ 3 - 4
lib/urldata.h

@@ -907,10 +907,9 @@ struct connectdata {
      there is no name resolve done. */
   struct Curl_dns_entry *dns_entry;
 
-  /* 'ip_addr' is the particular IP we connected to. It points to a struct
-     within the DNS cache, so this pointer is only valid as long as the DNS
-     cache entry remains locked. It gets unlocked in multi_done() */
-  const struct Curl_addrinfo *ip_addr;
+  /* 'remote_addr' is the particular IP we connected to. it is owned, set
+   * and NULLed by the connected socket filter (if there is one). */
+  const struct Curl_sockaddr_ex *remote_addr;
 
   struct hostname host;
   char *hostname_resolve; /* host name to resolve to address, allocated */