In order to not get problems with DNS cache pruning, we no longer store
any name resolved data in any curl handle struct. That way, we won't mind if the cache entries are pruned for the next time we need them. We'll just resolve them again instead. This changes the Curl_resolv() proto. It modifies the SessionHandle struct but perhaps most importantly, it'll make the internals somewhat dependent on the DNS cache not being disabled as that will cripple operations somewhat. Especially for persistant connections.
This commit is contained in:
parent
f6525ae200
commit
8927ddec16
@ -207,7 +207,6 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
if (strlen(data->set.device)<255) {
|
||||
struct sockaddr_in sa;
|
||||
Curl_addrinfo *h=NULL;
|
||||
char *hostdataptr=NULL;
|
||||
size_t size;
|
||||
char myhost[256] = "";
|
||||
in_addr_t in;
|
||||
@ -216,7 +215,7 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
/*
|
||||
* We now have the numerical IPv4-style x.y.z.w in the 'myhost' buffer
|
||||
*/
|
||||
h = Curl_resolv(data, myhost, 0, &hostdataptr);
|
||||
h = Curl_resolv(data, myhost, 0);
|
||||
}
|
||||
else {
|
||||
if(strlen(data->set.device)>1) {
|
||||
@ -224,7 +223,7 @@ static CURLcode bindlocal(struct connectdata *conn,
|
||||
* This was not an interface, resolve the name as a host name
|
||||
* or IP number
|
||||
*/
|
||||
h = Curl_resolv(data, data->set.device, 0, &hostdataptr);
|
||||
h = Curl_resolv(data, data->set.device, 0);
|
||||
if(h) {
|
||||
/* we know data->set.device is shorter than the myhost array */
|
||||
strcpy(myhost, data->set.device);
|
||||
@ -354,6 +353,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
int rc;
|
||||
int sockfd=-1;
|
||||
int aliasindex=0;
|
||||
char *hostname;
|
||||
|
||||
struct timeval after;
|
||||
struct timeval before = Curl_tvnow();
|
||||
@ -394,8 +394,8 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
}
|
||||
}
|
||||
|
||||
infof(data, "About to connect() to %s:%d\n",
|
||||
data->change.proxy?conn->proxyhost:conn->hostname, port);
|
||||
hostname = data->change.proxy?conn->proxyhost:conn->hostname;
|
||||
infof(data, "About to connect() to %s:%d\n", hostname, port);
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
/*
|
||||
@ -444,7 +444,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
case ECONNREFUSED: /* no one listening */
|
||||
default:
|
||||
/* unknown error, fallthrough and try another address! */
|
||||
failf(data, "Failed to connect: %d", error);
|
||||
failf(data, "Failed connect to %s: %d", hostname, error);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -474,10 +474,8 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
before = after;
|
||||
continue;
|
||||
}
|
||||
if (sockfd < 0) {
|
||||
failf(data, "connect() failed");
|
||||
if (sockfd < 0)
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
/* leave the socket in non-blocking mode */
|
||||
|
||||
@ -549,8 +547,8 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
break;
|
||||
default:
|
||||
/* unknown error, fallthrough and try another address! */
|
||||
failf(data, "Failed to connect to IP number %d: %d",
|
||||
aliasindex+1, error);
|
||||
failf(data, "Failed to connect to %s IP number %d: %d",
|
||||
hostname, aliasindex+1, error);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -582,7 +580,6 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
|
||||
/* no good connect was made */
|
||||
sclose(sockfd);
|
||||
*sockconn = -1;
|
||||
failf(data, "Couldn't connect to host");
|
||||
return CURLE_COULDNT_CONNECT;
|
||||
}
|
||||
|
||||
|
12
lib/ftp.c
12
lib/ftp.c
@ -1360,7 +1360,6 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
|
||||
int modeoff;
|
||||
unsigned short connectport; /* the local port connect() should use! */
|
||||
unsigned short newport; /* remote port, not necessary the local one */
|
||||
char *hostdataptr=NULL;
|
||||
|
||||
/* newhost must be able to hold a full IP-style address in ASCII, which
|
||||
in the IPv6 case means 5*8-1 = 39 letters */
|
||||
@ -1450,16 +1449,19 @@ CURLcode ftp_use_pasv(struct connectdata *conn)
|
||||
if(data->change.proxy) {
|
||||
/*
|
||||
* This is a tunnel through a http proxy and we need to connect to the
|
||||
* proxy again here. We already have the name info for it since the
|
||||
* previous lookup.
|
||||
* proxy again here.
|
||||
*
|
||||
* We don't want to rely on a former host lookup that might've expired
|
||||
* now, instead we remake the lookup here and now!
|
||||
*/
|
||||
addr = conn->hostaddr;
|
||||
addr = Curl_resolv(data, conn->proxyhost, conn->port);
|
||||
connectport =
|
||||
(unsigned short)conn->port; /* we connect to the proxy's port */
|
||||
|
||||
}
|
||||
else {
|
||||
/* normal, direct, ftp connection */
|
||||
addr = Curl_resolv(data, newhostp, newport, &hostdataptr);
|
||||
addr = Curl_resolv(data, newhostp, newport);
|
||||
if(!addr) {
|
||||
failf(data, "Can't resolve new host %s:%d", newhostp, newport);
|
||||
return CURLE_FTP_CANT_GET_HOST;
|
||||
|
10
lib/hostip.c
10
lib/hostip.c
@ -193,18 +193,18 @@ _curl_hostcache_prune(curl_hash *hostcache, int cache_timeout, int now)
|
||||
|
||||
Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
|
||||
char *hostname,
|
||||
int port,
|
||||
char **bufp)
|
||||
int port)
|
||||
{
|
||||
char *entry_id = NULL;
|
||||
struct curl_dns_cache_entry *p = NULL;
|
||||
ssize_t entry_len;
|
||||
time_t now;
|
||||
char *bufp;
|
||||
|
||||
/* If the host cache timeout is 0, we don't do DNS cach'ing
|
||||
so fall through */
|
||||
if (data->set.dns_cache_timeout == 0) {
|
||||
return Curl_getaddrinfo(data, hostname, port, bufp);
|
||||
return Curl_getaddrinfo(data, hostname, port, &bufp);
|
||||
}
|
||||
|
||||
time(&now);
|
||||
@ -220,7 +220,7 @@ Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
|
||||
/* If we can't create the entry id, don't cache, just fall-through
|
||||
to the plain Curl_getaddrinfo() */
|
||||
if (!entry_id) {
|
||||
return Curl_getaddrinfo(data, hostname, port, bufp);
|
||||
return Curl_getaddrinfo(data, hostname, port, &bufp);
|
||||
}
|
||||
|
||||
/* See if its already in our dns cache */
|
||||
@ -236,7 +236,7 @@ Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
|
||||
_hostcache_return(NULL);
|
||||
}
|
||||
|
||||
p->addr = Curl_getaddrinfo(data, hostname, port, bufp);
|
||||
p->addr = Curl_getaddrinfo(data, hostname, port, &bufp);
|
||||
if (!p->addr) {
|
||||
free(p);
|
||||
_hostcache_return(NULL);
|
||||
|
@ -37,8 +37,7 @@ curl_hash *Curl_global_host_cache_get(void);
|
||||
|
||||
Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
|
||||
char *hostname,
|
||||
int port,
|
||||
char **bufp);
|
||||
int port);
|
||||
|
||||
/* Get name info */
|
||||
Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
|
||||
|
40
lib/url.c
40
lib/url.c
@ -1241,7 +1241,8 @@ ConnectionStore(struct SessionHandle *data,
|
||||
return i;
|
||||
}
|
||||
|
||||
static CURLcode ConnectPlease(struct connectdata *conn)
|
||||
static CURLcode ConnectPlease(struct connectdata *conn,
|
||||
Curl_addrinfo *hostaddr)
|
||||
{
|
||||
CURLcode result;
|
||||
Curl_ipconnect *addr;
|
||||
@ -1250,7 +1251,7 @@ static CURLcode ConnectPlease(struct connectdata *conn)
|
||||
* Connect to server/proxy
|
||||
*************************************************************/
|
||||
result= Curl_connecthost(conn,
|
||||
conn->hostaddr,
|
||||
hostaddr,
|
||||
conn->port,
|
||||
&conn->firstsocket,
|
||||
&addr);
|
||||
@ -1264,7 +1265,7 @@ static CURLcode ConnectPlease(struct connectdata *conn)
|
||||
memset((char *) &conn->serv_addr, '\0', sizeof(conn->serv_addr));
|
||||
memcpy((char *)&(conn->serv_addr.sin_addr),
|
||||
(struct in_addr *)addr, sizeof(struct in_addr));
|
||||
conn->serv_addr.sin_family = conn->hostaddr->h_addrtype;
|
||||
conn->serv_addr.sin_family = hostaddr->h_addrtype;
|
||||
conn->serv_addr.sin_port = htons(conn->port);
|
||||
#endif
|
||||
}
|
||||
@ -1272,7 +1273,8 @@ static CURLcode ConnectPlease(struct connectdata *conn)
|
||||
return result;
|
||||
}
|
||||
|
||||
static void verboseconnect(struct connectdata *conn)
|
||||
static void verboseconnect(struct connectdata *conn,
|
||||
Curl_addrinfo *hostaddr)
|
||||
{
|
||||
#ifdef HAVE_INET_NTOA_R
|
||||
char ntoa_buf[64];
|
||||
@ -1281,6 +1283,7 @@ static void verboseconnect(struct connectdata *conn)
|
||||
|
||||
/* Figure out the ip-number and display the first host name it shows: */
|
||||
#ifdef ENABLE_IPV6
|
||||
(void)hostaddr; /* not used in the IPv6 enabled version */
|
||||
{
|
||||
char hbuf[NI_MAXHOST];
|
||||
#ifdef NI_WITHSCOPEID
|
||||
@ -1305,7 +1308,7 @@ static void verboseconnect(struct connectdata *conn)
|
||||
{
|
||||
struct in_addr in;
|
||||
(void) memcpy(&in.s_addr, &conn->serv_addr.sin_addr, sizeof (in.s_addr));
|
||||
infof(data, "Connected to %s (%s) port %d\n", conn->hostaddr->h_name,
|
||||
infof(data, "Connected to %s (%s) port %d\n", hostaddr->h_name,
|
||||
#if defined(HAVE_INET_NTOA_R)
|
||||
inet_ntoa_r(in, ntoa_buf, sizeof(ntoa_buf)),
|
||||
#else
|
||||
@ -1327,6 +1330,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
struct connectdata *conn_temp;
|
||||
char endbracket;
|
||||
int urllen;
|
||||
Curl_addrinfo *hostaddr;
|
||||
#ifdef HAVE_ALARM
|
||||
unsigned int prev_alarm;
|
||||
#endif
|
||||
@ -2178,27 +2182,21 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
conn->port = conn->remote_port; /* it is the same port */
|
||||
|
||||
/* Resolve target host right on */
|
||||
if(!conn->hostaddr) {
|
||||
/* it might already be set if reusing a connection */
|
||||
conn->hostaddr = Curl_resolv(data, conn->name, conn->port,
|
||||
&conn->hostent_buf);
|
||||
}
|
||||
if(!conn->hostaddr) {
|
||||
hostaddr = Curl_resolv(data, conn->name, conn->port);
|
||||
|
||||
if(!hostaddr) {
|
||||
failf(data, "Couldn't resolve host '%s'", conn->name);
|
||||
result = CURLE_COULDNT_RESOLVE_HOST;
|
||||
/* don't return yet, we need to clean up the timeout first */
|
||||
}
|
||||
}
|
||||
else if(!conn->hostaddr) {
|
||||
/* This is a proxy that hasn't been resolved yet. It may be resolved
|
||||
if we're reusing an existing connection. */
|
||||
else {
|
||||
/* This is a proxy that hasn't been resolved yet. */
|
||||
|
||||
/* resolve proxy */
|
||||
/* it might already be set if reusing a connection */
|
||||
conn->hostaddr = Curl_resolv(data, conn->proxyhost, conn->port,
|
||||
&conn->hostent_buf);
|
||||
hostaddr = Curl_resolv(data, conn->proxyhost, conn->port);
|
||||
|
||||
if(!conn->hostaddr) {
|
||||
if(!hostaddr) {
|
||||
failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost);
|
||||
result = CURLE_COULDNT_RESOLVE_PROXY;
|
||||
/* don't return yet, we need to clean up the timeout first */
|
||||
@ -2282,14 +2280,14 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
|
||||
if(-1 == conn->firstsocket) {
|
||||
/* Connect only if not already connected! */
|
||||
result = ConnectPlease(conn);
|
||||
result = ConnectPlease(conn, hostaddr);
|
||||
Curl_pgrsTime(data, TIMER_CONNECT); /* connect done, good or bad */
|
||||
|
||||
if(CURLE_OK != result)
|
||||
return result;
|
||||
|
||||
if(data->set.verbose)
|
||||
verboseconnect(conn);
|
||||
verboseconnect(conn, hostaddr);
|
||||
|
||||
if(conn->curl_connect) {
|
||||
/* is there a protocol-specific connect() procedure? */
|
||||
@ -2308,7 +2306,7 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
||||
else {
|
||||
Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
|
||||
if(data->set.verbose)
|
||||
verboseconnect(conn);
|
||||
verboseconnect(conn, hostaddr);
|
||||
}
|
||||
|
||||
conn->now = Curl_tvnow(); /* time this *after* the connect is done, we
|
||||
|
@ -282,9 +282,6 @@ struct connectdata {
|
||||
#define PROT_FTPS (1<<9)
|
||||
#define PROT_SSL (1<<10) /* protocol requires SSL */
|
||||
|
||||
Curl_addrinfo *hostaddr; /* IP-protocol independent host info pointer list */
|
||||
char *hostent_buf; /* pointer to allocated memory for name info */
|
||||
|
||||
#ifdef ENABLE_IPV6
|
||||
struct addrinfo *serv_addr; /* the particular host we use */
|
||||
#else
|
||||
|
Loading…
Reference in New Issue
Block a user