diff options
-rw-r--r-- | CHANGES | 20 | ||||
-rw-r--r-- | docs/KNOWN_BUGS | 13 | ||||
-rw-r--r-- | lib/url.c | 29 | ||||
-rw-r--r-- | lib/urldata.h | 16 |
4 files changed, 54 insertions, 24 deletions
@@ -7,6 +7,26 @@ Changelog Daniel (28 January 2005) +- KNOWN_BUGS #17 fixed. A DNS cache entry may not remain locked between two + curl_easy_perform() invokes. It was previously unlocked at disconnect, which + could mean that it remained locked between multiple transfers. The DNS cache + may not live as long as the connection cache does, as they are separate. + + To deal with the lack of DNS (host address) data availability in re-used + connections, libcurl now keeps a copy of the IP adress as a string, to be + able to show it even on subsequent requests on the same connection. + + The problem could be made to appear with this stunt: + + 1. create a multi handle + 2. add an easy handle + 3. fetch a URL that is persistent (leaves the connection alive) + 4. remove the easy handle from the multi + 5. kill the multi handle + 6. create a multi handle + 7. add the same easy handle to the new multi handle + 8. fetch a URL from the same server as before (re-using the connection) + - Stephen More pointed out that CURLOPT_FTPPORT and the -P option didn't work when built ipv6-enabled. I've now made a fix for it. Writing test cases for custom port hosts turned too tricky so unfortunately there's none. diff --git a/docs/KNOWN_BUGS b/docs/KNOWN_BUGS index 48c589294..bfa9aec18 100644 --- a/docs/KNOWN_BUGS +++ b/docs/KNOWN_BUGS @@ -6,19 +6,6 @@ may have been fixed since this was written! 18. test case 57 has </test> that should be </client> but when corrected, the test case fails! -17. Memory badness: - 1. create a multi handle - 2. add an easy handle - 3. fetch a URL that is persistent (leaves the connection alive) - 4. remove the easy handle from the multi - 5. kill the multi handle - 6. create a multi handle - 7. add the same easy handle to the new multi handle - 8. fetch a URL from the same server as before (re-using the connection) - - Use valgrind to see the memory problems when libcurl assumes that the DNS - data lives as long as the connection - 16. FTP URLs passed to curl may contain NUL (0x00) in the RFC 1738 <user>, <password>, and <fpath> components, encoded as "%00". The problem is that curl_unescape does not detect this, but instead returns a shortened C @@ -1417,12 +1417,6 @@ CURLcode Curl_disconnect(struct connectdata *conn) data = conn->data; - if(conn->dns_entry && data->hostcache) - /* if the DNS entry is still around, and the host cache is not blanked - (which it is for example when a shared one is killed by - curl_multi_cleanup() and similar stuff) */ - Curl_resolv_unlock(data, conn->dns_entry); /* done with this */ - #if defined(CURLDEBUG) && defined(AGGRESIVE_TEST) /* scan for DNS cache entries still marked as in use */ Curl_hash_apply(data->hostcache, @@ -1503,6 +1497,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_safefree(conn->allocptr.ref); Curl_safefree(conn->allocptr.host); Curl_safefree(conn->allocptr.cookiehost); + Curl_safefree(conn->ip_addr_str); #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \ defined(USE_THREADING_GETADDRINFO) @@ -1991,10 +1986,22 @@ static void verboseconnect(struct connectdata *conn) char addrbuf[256]; /* Get a printable version of the network address. */ - Curl_printable_address(conn->ip_addr, addrbuf, sizeof(addrbuf)); + if(!conn->bits.reuse) { + Curl_printable_address(conn->ip_addr, addrbuf, sizeof(addrbuf)); + + /* save the string */ + if(conn->ip_addr_str) + free(conn->ip_addr_str); + conn->ip_addr_str = strdup(addrbuf); + if(!conn->ip_addr_str) + return; /* FAIL */ + } + /* else, + Re-used, ip_addr is not safe to access. */ + infof(data, "Connected to %s (%s) port %d\n", conn->bits.httpproxy ? conn->proxy.dispname : conn->host.dispname, - addrbuf[0] ? addrbuf : "??", conn->port); + conn->ip_addr_str, conn->port); } /* @@ -3533,12 +3540,16 @@ CURLcode Curl_done(struct connectdata **connp, struct SessionHandle *data=conn->data; /* cleanups done even if the connection is re-used */ - if(conn->bits.rangestringalloc) { free(conn->range); conn->bits.rangestringalloc = FALSE; } + if(conn->dns_entry) { + Curl_resolv_unlock(data, conn->dns_entry); /* done with this */ + conn->dns_entry = NULL; + } + /* Cleanup possible redirect junk */ if(conn->newurl) { free(conn->newurl); diff --git a/lib/urldata.h b/lib/urldata.h index 76de45757..c51ccf303 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -450,9 +450,21 @@ struct connectdata { #define PROT_FTPS (1<<9) #define PROT_SSL (1<<10) /* protocol requires SSL */ - /* the particular host we use, in two different ways */ + /* 'dns_entry' is the particular host we use. This points to an entry in the + DNS cache and it will not get pruned while locked. It gets unlocked in + Curl_done() */ struct Curl_dns_entry *dns_entry; - Curl_addrinfo *ip_addr; /* the particular IP we connected to */ + + /* '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 Curl_done() */ + Curl_addrinfo *ip_addr; + + /* 'ip_addr_str' is the ip_addr data as a human readable malloc()ed string. + It remains available as long as the connection does, which is longer than + the ip_addr itself. Currently, this is only set (and used) in + url.c:verboseconnect(). */ + char *ip_addr_str; char protostr[16]; /* store the protocol string in this buffer */ |