cf->conn->sock[cf->sockindex] = CURL_SOCKET_BAD;
socket_close(data, cf->conn, !ctx->accepted, ctx->sock);
ctx->sock = CURL_SOCKET_BAD;
- if(ctx->active && cf->sockindex == FIRSTSOCKET)
- cf->conn->remote_addr = NULL;
ctx->active = FALSE;
memset(&ctx->started_at, 0, sizeof(ctx->started_at));
memset(&ctx->connected_at, 0, sizeof(ctx->connected_at));
#if defined(MSG_FASTOPEN) && !defined(TCP_FASTOPEN_CONNECT) /* Linux */
if(cf->conn->bits.tcp_fastopen) {
nwritten = sendto(ctx->sock, buf, len, MSG_FASTOPEN,
- &cf->conn->remote_addr->curl_sa_addr,
- cf->conn->remote_addr->addrlen);
+ &ctx->addr.curl_sa_addr, ctx->addr.addrlen);
cf->conn->bits.tcp_fastopen = FALSE;
}
else
set_local_ip(cf, data);
if(cf->sockindex == FIRSTSOCKET) {
cf->conn->primary = ctx->ip;
- cf->conn->remote_addr = &ctx->addr;
#ifdef USE_IPV6
cf->conn->bits.ipv6 = (ctx->addr.family == AF_INET6);
#endif
DEBUGASSERT(pres2);
*((curl_socket_t *)pres2) = ctx->sock;
return CURLE_OK;
+ case CF_QUERY_REMOTE_ADDR:
+ DEBUGASSERT(pres2);
+ *((const struct Curl_sockaddr_ex **)pres2) = cf->connected ?
+ &ctx->addr : NULL;
+ return CURLE_OK;
case CF_QUERY_CONNECT_REPLY_MS:
if(ctx->got_first_byte) {
timediff_t ms = curlx_timediff(ctx->first_byte_at, ctx->started_at);
return CURL_SOCKET_BAD;
}
+static const struct Curl_sockaddr_ex *
+cf_get_remote_addr(struct Curl_cfilter *cf, struct Curl_easy *data)
+{
+ const struct Curl_sockaddr_ex *remote_addr = NULL;
+ if(cf &&
+ !cf->cft->query(cf, data, CF_QUERY_REMOTE_ADDR, NULL,
+ CURL_UNCONST(&remote_addr)))
+ return remote_addr;
+ return NULL;
+}
+
CURLcode Curl_conn_cf_get_ip_info(struct Curl_cfilter *cf,
struct Curl_easy *data,
int *is_ipv6, struct ip_quadruple *ipquad)
return data->conn ? data->conn->sock[sockindex] : CURL_SOCKET_BAD;
}
+const struct Curl_sockaddr_ex *
+Curl_conn_get_remote_addr(struct Curl_easy *data, int sockindex)
+{
+ struct Curl_cfilter *cf = data->conn ? data->conn->cfilter[sockindex] : NULL;
+ return cf ? cf_get_remote_addr(cf, data) : NULL;
+}
+
void Curl_conn_forget_socket(struct Curl_easy *data, int sockindex)
{
if(data->conn) {
#define CF_QUERY_NEED_FLUSH 7 /* TRUE/FALSE - */
#define CF_QUERY_IP_INFO 8 /* TRUE/FALSE struct ip_quadruple */
#define CF_QUERY_HTTP_VERSION 9 /* number (10/11/20/30) - */
+/* pass in a `const struct Curl_sockaddr_ex **` as `pres2`. Gets set
+ * to NULL when not connected. */
+#define CF_QUERY_REMOTE_ADDR 10 /* - `Curl_sockaddr_ex *` */
/**
* Query the cfilter for properties. Filters ignorant of a query will
*/
curl_socket_t Curl_conn_get_socket(struct Curl_easy *data, int sockindex);
+/* Return a pointer to the connected socket address or NULL. */
+const struct Curl_sockaddr_ex *
+Curl_conn_get_remote_addr(struct Curl_easy *data, int sockindex);
+
/**
* Tell filters to forget about the socket at sockindex.
*/
port_min = port_max = 0;
if(addrlen) {
+ const struct Curl_sockaddr_ex *remote_addr =
+ Curl_conn_get_remote_addr(data, FIRSTSOCKET);
+
+ DEBUGASSERT(remote_addr);
+ if(!remote_addr)
+ goto out;
DEBUGASSERT(addr);
if(addrlen >= sizeof(ipstr))
goto out;
ipstr[addrlen] = 0;
/* attempt to get the address of the given interface name */
- switch(Curl_if2ip(conn->remote_addr->family,
+ switch(Curl_if2ip(remote_addr->family,
#ifdef USE_IPV6
- Curl_ipv6_scope(&conn->remote_addr->curl_sa_addr),
+ Curl_ipv6_scope(&remote_addr->curl_sa_addr),
conn->scope_id,
#endif
ipstr, hbuf, sizeof(hbuf))) {
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 *)CURL_UNCONST(&conn->remote_addr->curl_sa_addr);
+ const struct Curl_sockaddr_ex *remote_addr =
+ Curl_conn_get_remote_addr(data, FIRSTSOCKET);
+ struct sockaddr_in *remote_in_addr = remote_addr ?
+ (struct sockaddr_in *)CURL_UNCONST(&remote_addr->curl_sa_addr) : NULL;
char *stringp;
struct ftp_conn *ftpc = Curl_conn_meta_get(conn, CURL_META_FTP_CONN);
- if(!ftpc)
+ if(!ftpc || !remote_in_addr)
return -2;
if(getsockname(conn->sock[FIRSTSOCKET],
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_in_addr->sin_addr.s_addr;
chan.application_data.length = 0;
chan.application_data.value = NULL;
#include "urldata.h"
#include <curl/curl.h>
+#include "cfilters.h"
#include "cf-socket.h"
#include "transfer.h"
#include "sendf.h"
const char *mode = "octet";
char *filename;
struct Curl_easy *data = state->data;
+ const struct Curl_sockaddr_ex *remote_addr = NULL;
CURLcode result = CURLE_OK;
/* Set ASCII mode if -B flag was used */
#else
#define CURL_SENDTO_ARG5(x) (x)
#endif
+ remote_addr = Curl_conn_get_remote_addr(data, FIRSTSOCKET);
+ if(!remote_addr)
+ return CURLE_FAILED_INIT;
+
senddata = sendto(state->sockfd, (void *)state->spacket.data,
(SEND_TYPE_ARG3)sbytes, 0,
- CURL_SENDTO_ARG5(&data->conn->remote_addr->curl_sa_addr),
- (curl_socklen_t)data->conn->remote_addr->addrlen);
+ CURL_SENDTO_ARG5(&remote_addr->curl_sa_addr),
+ (curl_socklen_t)remote_addr->addrlen);
if(senddata != (ssize_t)sbytes) {
char buffer[STRERROR_LEN];
failf(data, "%s", Curl_strerror(SOCKERRNO, buffer, sizeof(buffer)));
int blksize;
int need_blksize;
struct connectdata *conn = data->conn;
+ const struct Curl_sockaddr_ex *remote_addr = NULL;
blksize = TFTP_BLKSIZE_DEFAULT;
state->blksize = TFTP_BLKSIZE_DEFAULT; /* Unless updated by OACK response */
state->requested_blksize = blksize;
+ remote_addr = Curl_conn_get_remote_addr(data, FIRSTSOCKET);
+ DEBUGASSERT(remote_addr);
+ if(!remote_addr)
+ return CURLE_FAILED_INIT;
+
((struct sockaddr *)&state->local_addr)->sa_family =
- (CURL_SA_FAMILY_T)(conn->remote_addr->family);
+ (CURL_SA_FAMILY_T)(remote_addr->family);
tftp_set_timeouts(state);
* IPv4 and IPv6...
*/
int rc = bind(state->sockfd, (struct sockaddr *)&state->local_addr,
- (curl_socklen_t)conn->remote_addr->addrlen);
+ (curl_socklen_t)remote_addr->addrlen);
if(rc) {
char buffer[STRERROR_LEN];
failf(data, "bind() failed; %s",
* the connection is cleaned up (see Curl_hash_add2()).*/
struct Curl_hash meta_hash;
- /* '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; /* hostname to resolve to address, allocated */
char *secondaryhostname; /* secondary socket hostname (ftp) */
"conn->sock[], discarding", (int)ctx->sock[SP_LOCAL]);
ctx->sock[SP_LOCAL] = CURL_SOCKET_BAD;
}
- if(cf->sockindex == FIRSTSOCKET)
- cf->conn->remote_addr = NULL;
}
if(ctx->sock[SP_LOCAL] != CURL_SOCKET_BAD) {
sclose(ctx->sock[SP_LOCAL]);