Make cach'ing work with threads now, there are now three cases:
- Use a global dns cache (via setting the tentatively named, CURLOPT_DNS_USE_GLOBAL_CACHE option to true) - Use a per-handle dns cache, by default - Use a pooled dns cache when in the "multi" interface
This commit is contained in:
Родитель
d3299beec7
Коммит
8d7f402efb
|
@ -488,6 +488,9 @@ typedef enum {
|
||||||
*/
|
*/
|
||||||
CINIT(SSLENGINE_DEFAULT, LONG, 90),
|
CINIT(SSLENGINE_DEFAULT, LONG, 90),
|
||||||
|
|
||||||
|
/* Non-zero value means to use the global dns cache */
|
||||||
|
CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91),
|
||||||
|
|
||||||
CURLOPT_LASTENTRY /* the last unusued */
|
CURLOPT_LASTENTRY /* the last unusued */
|
||||||
} CURLoption;
|
} CURLoption;
|
||||||
|
|
||||||
|
|
18
lib/easy.c
18
lib/easy.c
|
@ -141,8 +141,6 @@ CURLcode curl_global_init(long flags)
|
||||||
if (initialized)
|
if (initialized)
|
||||||
return CURLE_OK;
|
return CURLE_OK;
|
||||||
|
|
||||||
Curl_host_cache_init();
|
|
||||||
|
|
||||||
if (flags & CURL_GLOBAL_SSL)
|
if (flags & CURL_GLOBAL_SSL)
|
||||||
Curl_SSL_init();
|
Curl_SSL_init();
|
||||||
|
|
||||||
|
@ -165,8 +163,8 @@ void curl_global_cleanup(void)
|
||||||
if (!initialized)
|
if (!initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Curl_host_cache_dtor();
|
Curl_global_host_cache_dtor();
|
||||||
|
|
||||||
if (init_flags & CURL_GLOBAL_SSL)
|
if (init_flags & CURL_GLOBAL_SSL)
|
||||||
Curl_SSL_cleanup();
|
Curl_SSL_cleanup();
|
||||||
|
|
||||||
|
@ -235,12 +233,24 @@ CURLcode curl_easy_perform(CURL *curl)
|
||||||
{
|
{
|
||||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||||
|
|
||||||
|
if (!data->hostcache) {
|
||||||
|
if (Curl_global_host_cache_use(data)) {
|
||||||
|
data->hostcache = Curl_global_host_cache_get();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
data->hostcache = curl_hash_alloc(7, Curl_freeaddrinfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return Curl_perform(data);
|
return Curl_perform(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void curl_easy_cleanup(CURL *curl)
|
void curl_easy_cleanup(CURL *curl)
|
||||||
{
|
{
|
||||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||||
|
if (!Curl_global_host_cache_use(data)) {
|
||||||
|
curl_hash_destroy(data->hostcache);
|
||||||
|
}
|
||||||
Curl_close(data);
|
Curl_close(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
lib/hash.c
11
lib/hash.c
|
@ -255,11 +255,22 @@ curl_hash_clean(curl_hash *h)
|
||||||
h->table = NULL;
|
h->table = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t
|
||||||
|
curl_hash_count(curl_hash *h)
|
||||||
|
{
|
||||||
|
return h->size;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
curl_hash_destroy(curl_hash *h)
|
curl_hash_destroy(curl_hash *h)
|
||||||
{
|
{
|
||||||
|
if (!h) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
curl_hash_clean(h);
|
curl_hash_clean(h);
|
||||||
free(h);
|
free(h);
|
||||||
|
h = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -71,6 +71,7 @@ int curl_hash_extended_delete(curl_hash *h, char *str_key, unsigned int str_key_
|
||||||
int curl_hash_extended_find(curl_hash *h, char *str_key, unsigned int str_key_len,
|
int curl_hash_extended_find(curl_hash *h, char *str_key, unsigned int str_key_len,
|
||||||
unsigned long num_key, void **p);
|
unsigned long num_key, void **p);
|
||||||
void curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *, curl_hash_element *));
|
void curl_hash_apply(curl_hash *h, void *user, void (*cb)(void *, curl_hash_element *));
|
||||||
|
size_t curl_hash_count(curl_hash *h);
|
||||||
void curl_hash_clean(curl_hash *h);
|
void curl_hash_clean(curl_hash *h);
|
||||||
void curl_hash_destroy(curl_hash *h);
|
void curl_hash_destroy(curl_hash *h);
|
||||||
|
|
||||||
|
|
26
lib/hostip.c
26
lib/hostip.c
|
@ -70,17 +70,27 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static curl_hash hostname_cache;
|
static curl_hash hostname_cache;
|
||||||
|
static int host_cache_initialized;
|
||||||
|
|
||||||
void Curl_host_cache_init(void)
|
void Curl_global_host_cache_init(void)
|
||||||
{
|
{
|
||||||
curl_hash_init(&hostname_cache, 7, Curl_freeaddrinfo);
|
if (!host_cache_initialized) {
|
||||||
|
curl_hash_init(&hostname_cache, 7, Curl_freeaddrinfo);
|
||||||
|
host_cache_initialized = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Curl_host_cache_dtor(void)
|
curl_hash *Curl_global_host_cache_get(void)
|
||||||
{
|
{
|
||||||
curl_hash_clean(&hostname_cache);
|
return &hostname_cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Curl_global_host_cache_dtor(void)
|
||||||
|
{
|
||||||
|
if (host_cache_initialized) {
|
||||||
|
curl_hash_clean(&hostname_cache);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
|
Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
|
||||||
char *hostname,
|
char *hostname,
|
||||||
|
@ -90,14 +100,15 @@ Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
|
||||||
Curl_addrinfo *addr = NULL;
|
Curl_addrinfo *addr = NULL;
|
||||||
size_t hostname_len = strlen(hostname)+1;
|
size_t hostname_len = strlen(hostname)+1;
|
||||||
|
|
||||||
if (curl_hash_find(&hostname_cache, hostname, hostname_len, (void **) &addr))
|
if (curl_hash_find(data->hostcache, hostname, hostname_len, (void **) &addr)) {
|
||||||
return addr;
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
addr = Curl_getaddrinfo(data, hostname, port, bufp);
|
addr = Curl_getaddrinfo(data, hostname, port, bufp);
|
||||||
if (!addr)
|
if (!addr)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
curl_hash_add(&hostname_cache, hostname, hostname_len, (const void *) addr);
|
curl_hash_add(data->hostcache, hostname, hostname_len, (const void *) addr);
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,3 +416,4 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
|
||||||
* vim600: fdm=marker
|
* vim600: fdm=marker
|
||||||
* vim: et sw=2 ts=2 sts=2 tw=78
|
* vim: et sw=2 ts=2 sts=2 tw=78
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -23,12 +23,17 @@
|
||||||
* $Id$
|
* $Id$
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include "hash.h"
|
||||||
|
|
||||||
struct addrinfo;
|
struct addrinfo;
|
||||||
struct hostent;
|
struct hostent;
|
||||||
struct SessionHandle;
|
struct SessionHandle;
|
||||||
|
|
||||||
void Curl_host_cache_init(void);
|
void Curl_global_host_cache_init(void);
|
||||||
void Curl_host_cache_dtor(void);
|
void Curl_global_host_cache_dtor(void);
|
||||||
|
curl_hash *Curl_global_host_cache_get(void);
|
||||||
|
|
||||||
|
#define Curl_global_host_cache_use(__p) ((__p)->set.global_dns_cache)
|
||||||
|
|
||||||
Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
|
Curl_addrinfo *Curl_resolv(struct SessionHandle *data,
|
||||||
char *hostname,
|
char *hostname,
|
||||||
|
|
24
lib/multi.c
24
lib/multi.c
|
@ -82,7 +82,8 @@ struct Curl_multi {
|
||||||
struct Curl_message *msgs;
|
struct Curl_message *msgs;
|
||||||
/* amount of messages in the queue */
|
/* amount of messages in the queue */
|
||||||
int num_msgs;
|
int num_msgs;
|
||||||
|
/* Hostname cache */
|
||||||
|
curl_hash *hostcache;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -244,7 +245,6 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
||||||
|
|
||||||
easy=multi->easy.next;
|
easy=multi->easy.next;
|
||||||
while(easy) {
|
while(easy) {
|
||||||
|
|
||||||
switch(easy->state) {
|
switch(easy->state) {
|
||||||
case CURLM_STATE_INIT:
|
case CURLM_STATE_INIT:
|
||||||
/* init this transfer. */
|
/* init this transfer. */
|
||||||
|
@ -256,6 +256,17 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CURLM_STATE_CONNECT:
|
case CURLM_STATE_CONNECT:
|
||||||
|
if (Curl_global_host_cache_use(easy->easy_handle)) {
|
||||||
|
easy->easy_handle->hostcache = Curl_global_host_cache_get();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (multi->hostcache == NULL) {
|
||||||
|
multi->hostcache = curl_hash_alloc(7, Curl_freeaddrinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
easy->easy_handle->hostcache = multi->hostcache;
|
||||||
|
}
|
||||||
|
|
||||||
/* Connect. We get a connection identifier filled in. */
|
/* Connect. We get a connection identifier filled in. */
|
||||||
easy->result = Curl_connect(easy->easy_handle, &easy->easy_conn);
|
easy->result = Curl_connect(easy->easy_handle, &easy->easy_conn);
|
||||||
|
|
||||||
|
@ -328,7 +339,7 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
|
||||||
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
||||||
if(GOOD_MULTI_HANDLE(multi)) {
|
if(GOOD_MULTI_HANDLE(multi)) {
|
||||||
multi->type = 0; /* not good anymore */
|
multi->type = 0; /* not good anymore */
|
||||||
|
curl_hash_destroy(multi->hostcache);
|
||||||
/* remove all easy handles */
|
/* remove all easy handles */
|
||||||
|
|
||||||
free(multi);
|
free(multi);
|
||||||
|
@ -341,3 +352,10 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
|
||||||
|
|
||||||
CURLMsg *curl_multi_info_read(CURLM *multi_handle, int *msgs_in_queue);
|
CURLMsg *curl_multi_info_read(CURLM *multi_handle, int *msgs_in_queue);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* local variables:
|
||||||
|
* eval: (load-file "../curl-mode.el")
|
||||||
|
* end:
|
||||||
|
* vim600: fdm=marker
|
||||||
|
* vim: et sw=2 ts=2 sts=2 tw=78
|
||||||
|
*/
|
||||||
|
|
|
@ -284,6 +284,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
|
||||||
va_start(param, option);
|
va_start(param, option);
|
||||||
|
|
||||||
switch(option) {
|
switch(option) {
|
||||||
|
case CURLOPT_DNS_USE_GLOBAL_CACHE: {
|
||||||
|
int use_cache = va_arg(param, int);
|
||||||
|
if (use_cache) {
|
||||||
|
Curl_global_host_cache_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
data->set.global_dns_cache = use_cache;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case CURLOPT_SSL_CIPHER_LIST:
|
case CURLOPT_SSL_CIPHER_LIST:
|
||||||
/* set a list of cipher we want to use in the SSL connection */
|
/* set a list of cipher we want to use in the SSL connection */
|
||||||
data->set.ssl.cipher_list = va_arg(param, char *);
|
data->set.ssl.cipher_list = va_arg(param, char *);
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
#include "hostip.h"
|
#include "hostip.h"
|
||||||
|
#include "hash.h"
|
||||||
|
|
||||||
#define PORT_FTP 21
|
#define PORT_FTP 21
|
||||||
#define PORT_TELNET 23
|
#define PORT_TELNET 23
|
||||||
|
@ -644,6 +645,8 @@ struct UserDefined {
|
||||||
bool reuse_fresh; /* do not re-use an existing connection */
|
bool reuse_fresh; /* do not re-use an existing connection */
|
||||||
bool expect100header; /* TRUE if we added Expect: 100-continue */
|
bool expect100header; /* TRUE if we added Expect: 100-continue */
|
||||||
bool ftp_use_epsv; /* if EPSV is to be attempted or not */
|
bool ftp_use_epsv; /* if EPSV is to be attempted or not */
|
||||||
|
|
||||||
|
bool global_dns_cache;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -658,6 +661,7 @@ struct UserDefined {
|
||||||
* 'struct urlstate' instead. */
|
* 'struct urlstate' instead. */
|
||||||
|
|
||||||
struct SessionHandle {
|
struct SessionHandle {
|
||||||
|
curl_hash *hostcache;
|
||||||
struct UserDefined set; /* values set by the libcurl user */
|
struct UserDefined set; /* values set by the libcurl user */
|
||||||
struct DynamicStatic change; /* possibly modified userdefined data */
|
struct DynamicStatic change; /* possibly modified userdefined data */
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче