From: Daniel Stenberg Date: Thu, 25 Apr 2002 19:00:57 +0000 (+0000) Subject: In order to not get problems with DNS cache pruning, we no longer store X-Git-Tag: upstream/7.37.1~15523 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8927ddec1687a438354eae6c527da92c6c63b50b;p=platform%2Fupstream%2Fcurl.git 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. --- diff --git a/lib/connect.c b/lib/connect.c index 3fe0e0eb0..9bd1bdfbd 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -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; } diff --git a/lib/ftp.c b/lib/ftp.c index f5117f10e..71ae76842 100644 --- a/lib/ftp.c +++ b/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 */ + (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; diff --git a/lib/hostip.c b/lib/hostip.c index 7bdb3ee7d..ea28b1cea 100644 --- a/lib/hostip.c +++ b/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); diff --git a/lib/hostip.h b/lib/hostip.h index dc8a258e0..8461a7e53 100644 --- a/lib/hostip.h +++ b/lib/hostip.h @@ -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, diff --git a/lib/url.c b/lib/url.c index bd010e6df..553c67e74 100644 --- a/lib/url.c +++ b/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 diff --git a/lib/urldata.h b/lib/urldata.h index 0a0416996..d61f28132 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -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