refactor: split resolve_server() into functions
This commit splits the branch-heavy resolve_server() function into various sub-functions, in order to reduce the amount of nested if/else-statements. Beside this, it also removes many else-sequences, by returning in the previous if-statement. Closes #9283
This commit is contained in:
Родитель
193772084f
Коммит
764c958c52
266
lib/url.c
266
lib/url.c
|
@ -3414,6 +3414,146 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data,
|
|||
return result;
|
||||
}
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
static CURLcode resolve_unix(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
char *unix_path)
|
||||
{
|
||||
struct Curl_dns_entry *hostaddr = NULL;
|
||||
bool longpath = FALSE;
|
||||
|
||||
DEBUGASSERT(unix_path);
|
||||
DEBUGASSERT(conn->dns_entry == NULL);
|
||||
|
||||
/* Unix domain sockets are local. The host gets ignored, just use the
|
||||
* specified domain socket address. Do not cache "DNS entries". There is
|
||||
* no DNS involved and we already have the filesystem path available. */
|
||||
hostaddr = calloc(1, sizeof(struct Curl_dns_entry));
|
||||
if(!hostaddr)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
hostaddr->addr = Curl_unix2addr(unix_path, &longpath,
|
||||
conn->bits.abstract_unix_socket);
|
||||
if(!hostaddr->addr) {
|
||||
if(longpath)
|
||||
/* Long paths are not supported for now */
|
||||
failf(data, "Unix socket path too long: '%s'", unix_path);
|
||||
free(hostaddr);
|
||||
return longpath ? CURLE_COULDNT_RESOLVE_HOST : CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
hostaddr->inuse++;
|
||||
conn->dns_entry = hostaddr;
|
||||
return CURLE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
static CURLcode resolve_proxy(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool *async)
|
||||
{
|
||||
struct Curl_dns_entry *hostaddr = NULL;
|
||||
struct hostname *host;
|
||||
timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
|
||||
int rc;
|
||||
|
||||
DEBUGASSERT(conn->dns_entry == NULL);
|
||||
|
||||
host = conn->bits.socksproxy ? &conn->socks_proxy.host :
|
||||
&conn->http_proxy.host;
|
||||
|
||||
conn->hostname_resolve = strdup(host->name);
|
||||
if(!conn->hostname_resolve)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
rc = Curl_resolv_timeout(data, conn->hostname_resolve, (int)conn->port,
|
||||
&hostaddr, timeout_ms);
|
||||
conn->dns_entry = hostaddr;
|
||||
if(rc == CURLRESOLV_PENDING)
|
||||
*async = TRUE;
|
||||
else if(rc == CURLRESOLV_TIMEDOUT)
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
else if(!hostaddr) {
|
||||
failf(data, "Couldn't resolve proxy '%s'", host->dispname);
|
||||
return CURLE_COULDNT_RESOLVE_PROXY;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
static CURLcode resolve_ip(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool *async)
|
||||
{
|
||||
struct Curl_dns_entry *hostaddr = NULL;
|
||||
struct hostname *connhost;
|
||||
timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
|
||||
int rc;
|
||||
|
||||
DEBUGASSERT(conn->dns_entry == NULL);
|
||||
|
||||
connhost = conn->bits.conn_to_host ? &conn->conn_to_host : &conn->host;
|
||||
|
||||
/* If not connecting via a proxy, extract the port from the URL, if it is
|
||||
* there, thus overriding any defaults that might have been set above. */
|
||||
conn->port = conn->bits.conn_to_port ? conn->conn_to_port :
|
||||
conn->remote_port;
|
||||
|
||||
/* Resolve target host right on */
|
||||
conn->hostname_resolve = strdup(connhost->name);
|
||||
if(!conn->hostname_resolve)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
rc = Curl_resolv_timeout(data, conn->hostname_resolve, (int)conn->port,
|
||||
&hostaddr, timeout_ms);
|
||||
conn->dns_entry = hostaddr;
|
||||
if(rc == CURLRESOLV_PENDING)
|
||||
*async = TRUE;
|
||||
else if(rc == CURLRESOLV_TIMEDOUT) {
|
||||
failf(data, "Failed to resolve host '%s' with timeout after %ld ms",
|
||||
connhost->dispname,
|
||||
Curl_timediff(Curl_now(), data->progress.t_startsingle));
|
||||
return CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
else if(!hostaddr) {
|
||||
failf(data, "Could not resolve host: %s", connhost->dispname);
|
||||
return CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
/* Perform a fresh resolve */
|
||||
static CURLcode resolve_fresh(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
bool *async)
|
||||
{
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
char *unix_path = conn->unix_domain_socket;
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(!unix_path && conn->socks_proxy.host.name &&
|
||||
!strncmp(UNIX_SOCKET_PREFIX"/",
|
||||
conn->socks_proxy.host.name, sizeof(UNIX_SOCKET_PREFIX)))
|
||||
unix_path = conn->socks_proxy.host.name + sizeof(UNIX_SOCKET_PREFIX) - 1;
|
||||
#endif
|
||||
|
||||
if(unix_path) {
|
||||
conn->transport = TRNSPRT_UNIX;
|
||||
return resolve_unix(data, conn, unix_path);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
if(CONN_IS_PROXIED(conn))
|
||||
return resolve_proxy(data, conn, async);
|
||||
#endif
|
||||
|
||||
return resolve_ip(data, conn, async);
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* Resolve the address of the server or proxy
|
||||
*************************************************************/
|
||||
|
@ -3421,135 +3561,19 @@ static CURLcode resolve_server(struct Curl_easy *data,
|
|||
struct connectdata *conn,
|
||||
bool *async)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
|
||||
|
||||
DEBUGASSERT(conn);
|
||||
DEBUGASSERT(data);
|
||||
/*************************************************************
|
||||
* Resolve the name of the server or proxy
|
||||
*************************************************************/
|
||||
if(conn->bits.reuse)
|
||||
|
||||
/* Resolve the name of the server or proxy */
|
||||
if(conn->bits.reuse) {
|
||||
/* We're reusing the connection - no need to resolve anything, and
|
||||
idnconvert_hostname() was called already in create_conn() for the re-use
|
||||
case. */
|
||||
*async = FALSE;
|
||||
|
||||
else {
|
||||
/* this is a fresh connect */
|
||||
int rc;
|
||||
struct Curl_dns_entry *hostaddr = NULL;
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
char *unix_path = NULL;
|
||||
|
||||
if(conn->unix_domain_socket)
|
||||
unix_path = conn->unix_domain_socket;
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
else if(conn->socks_proxy.host.name
|
||||
&& !strncmp(UNIX_SOCKET_PREFIX"/",
|
||||
conn->socks_proxy.host.name, sizeof(UNIX_SOCKET_PREFIX)))
|
||||
unix_path = conn->socks_proxy.host.name + sizeof(UNIX_SOCKET_PREFIX) - 1;
|
||||
#endif
|
||||
|
||||
if(unix_path) {
|
||||
/* Unix domain sockets are local. The host gets ignored, just use the
|
||||
* specified domain socket address. Do not cache "DNS entries". There is
|
||||
* no DNS involved and we already have the filesystem path available */
|
||||
|
||||
hostaddr = calloc(1, sizeof(struct Curl_dns_entry));
|
||||
if(!hostaddr)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
else {
|
||||
bool longpath = FALSE;
|
||||
hostaddr->addr = Curl_unix2addr(unix_path, &longpath,
|
||||
conn->bits.abstract_unix_socket);
|
||||
if(hostaddr->addr)
|
||||
hostaddr->inuse++;
|
||||
else {
|
||||
/* Long paths are not supported for now */
|
||||
if(longpath) {
|
||||
failf(data, "Unix socket path too long: '%s'", unix_path);
|
||||
result = CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
else
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
free(hostaddr);
|
||||
hostaddr = NULL;
|
||||
}
|
||||
conn->transport = TRNSPRT_UNIX;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
if(!CONN_IS_PROXIED(conn)) {
|
||||
struct hostname *connhost;
|
||||
if(conn->bits.conn_to_host)
|
||||
connhost = &conn->conn_to_host;
|
||||
else
|
||||
connhost = &conn->host;
|
||||
|
||||
/* If not connecting via a proxy, extract the port from the URL, if it is
|
||||
* there, thus overriding any defaults that might have been set above. */
|
||||
if(conn->bits.conn_to_port)
|
||||
conn->port = conn->conn_to_port;
|
||||
else
|
||||
conn->port = conn->remote_port;
|
||||
|
||||
/* Resolve target host right on */
|
||||
conn->hostname_resolve = strdup(connhost->name);
|
||||
if(!conn->hostname_resolve)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
rc = Curl_resolv_timeout(data, conn->hostname_resolve, (int)conn->port,
|
||||
&hostaddr, timeout_ms);
|
||||
if(rc == CURLRESOLV_PENDING)
|
||||
*async = TRUE;
|
||||
|
||||
else if(rc == CURLRESOLV_TIMEDOUT) {
|
||||
failf(data, "Failed to resolve host '%s' with timeout after %ld ms",
|
||||
connhost->dispname,
|
||||
Curl_timediff(Curl_now(), data->progress.t_startsingle));
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
}
|
||||
else if(!hostaddr) {
|
||||
failf(data, "Could not resolve host: %s", connhost->dispname);
|
||||
result = CURLE_COULDNT_RESOLVE_HOST;
|
||||
/* don't return yet, we need to clean up the timeout first */
|
||||
}
|
||||
}
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
else {
|
||||
/* This is a proxy that hasn't been resolved yet. */
|
||||
|
||||
struct hostname * const host = conn->bits.socksproxy ?
|
||||
&conn->socks_proxy.host : &conn->http_proxy.host;
|
||||
|
||||
/* resolve proxy */
|
||||
conn->hostname_resolve = strdup(host->name);
|
||||
if(!conn->hostname_resolve)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
rc = Curl_resolv_timeout(data, conn->hostname_resolve, (int)conn->port,
|
||||
&hostaddr, timeout_ms);
|
||||
|
||||
if(rc == CURLRESOLV_PENDING)
|
||||
*async = TRUE;
|
||||
|
||||
else if(rc == CURLRESOLV_TIMEDOUT)
|
||||
result = CURLE_OPERATION_TIMEDOUT;
|
||||
|
||||
else if(!hostaddr) {
|
||||
failf(data, "Couldn't resolve proxy '%s'", host->dispname);
|
||||
result = CURLE_COULDNT_RESOLVE_PROXY;
|
||||
/* don't return yet, we need to clean up the timeout first */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
DEBUGASSERT(conn->dns_entry == NULL);
|
||||
conn->dns_entry = hostaddr;
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
return result;
|
||||
return resolve_fresh(data, conn, async);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Загрузка…
Ссылка в новой задаче