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:
parent
193772084f
commit
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;
|
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
|
* Resolve the address of the server or proxy
|
||||||
*************************************************************/
|
*************************************************************/
|
||||||
@ -3421,135 +3561,19 @@ static CURLcode resolve_server(struct Curl_easy *data,
|
|||||||
struct connectdata *conn,
|
struct connectdata *conn,
|
||||||
bool *async)
|
bool *async)
|
||||||
{
|
{
|
||||||
CURLcode result = CURLE_OK;
|
|
||||||
timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
|
|
||||||
|
|
||||||
DEBUGASSERT(conn);
|
DEBUGASSERT(conn);
|
||||||
DEBUGASSERT(data);
|
DEBUGASSERT(data);
|
||||||
/*************************************************************
|
|
||||||
* Resolve the name of the server or proxy
|
/* Resolve the name of the server or proxy */
|
||||||
*************************************************************/
|
if(conn->bits.reuse) {
|
||||||
if(conn->bits.reuse)
|
|
||||||
/* We're reusing the connection - no need to resolve anything, and
|
/* We're reusing the connection - no need to resolve anything, and
|
||||||
idnconvert_hostname() was called already in create_conn() for the re-use
|
idnconvert_hostname() was called already in create_conn() for the re-use
|
||||||
case. */
|
case. */
|
||||||
*async = FALSE;
|
*async = FALSE;
|
||||||
|
return CURLE_OK;
|
||||||
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 result;
|
return resolve_fresh(data, conn, async);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user