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:
Emil Engler 2022-08-08 23:58:20 +02:00 коммит произвёл Daniel Stenberg
Родитель 193772084f
Коммит 764c958c52
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 5CC908FDB71E12C2
1 изменённых файлов: 145 добавлений и 121 удалений

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);
}
/*