mirror of
https://github.com/curl/curl.git
synced 2026-07-23 01:27:16 +03:00
socks: support unix sockets for socks proxy
Usage: curl -x "socks5h://localhost/run/tor/socks" "https://example.com" Updated runtests.pl to run a socksd server listening on unix socket Added tests test1467 test1468 Added documentation for proxy command line option and socks proxy options Closes #8668
This commit is contained in:
parent
ee52bead4d
commit
dfa84a0450
12 changed files with 240 additions and 23 deletions
80
lib/url.c
80
lib/url.c
|
|
@ -147,6 +147,10 @@ static void conn_free(struct connectdata *conn);
|
|||
# error READBUFFER_SIZE is too small
|
||||
#endif
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
#define UNIX_SOCKET_PREFIX "localhost"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* get_protocol_family()
|
||||
*
|
||||
|
|
@ -2407,13 +2411,18 @@ static CURLcode parse_proxy(struct Curl_easy *data,
|
|||
int port = -1;
|
||||
char *proxyuser = NULL;
|
||||
char *proxypasswd = NULL;
|
||||
char *host;
|
||||
char *host = NULL;
|
||||
bool sockstype;
|
||||
CURLUcode uc;
|
||||
struct proxy_info *proxyinfo;
|
||||
CURLU *uhp = curl_url();
|
||||
CURLcode result = CURLE_OK;
|
||||
char *scheme = NULL;
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
char *path = NULL;
|
||||
bool is_unix_proxy = FALSE;
|
||||
#endif
|
||||
|
||||
|
||||
if(!uhp) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
|
|
@ -2538,21 +2547,54 @@ static CURLcode parse_proxy(struct Curl_easy *data,
|
|||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
Curl_safefree(proxyinfo->host.rawalloc);
|
||||
proxyinfo->host.rawalloc = host;
|
||||
if(host[0] == '[') {
|
||||
/* this is a numerical IPv6, strip off the brackets */
|
||||
size_t len = strlen(host);
|
||||
host[len-1] = 0; /* clear the trailing bracket */
|
||||
host++;
|
||||
zonefrom_url(uhp, data, conn);
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
if(sockstype && strcasecompare(UNIX_SOCKET_PREFIX, host)) {
|
||||
uc = curl_url_get(uhp, CURLUPART_PATH, &path, CURLU_URLDECODE);
|
||||
if(uc) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
/* path will be "/", if no path was was found */
|
||||
if(strcmp("/", path)) {
|
||||
is_unix_proxy = TRUE;
|
||||
free(host);
|
||||
host = aprintf(UNIX_SOCKET_PREFIX"%s", path);
|
||||
if(!host) {
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
Curl_safefree(proxyinfo->host.rawalloc);
|
||||
proxyinfo->host.rawalloc = host;
|
||||
proxyinfo->host.name = host;
|
||||
host = NULL;
|
||||
}
|
||||
}
|
||||
proxyinfo->host.name = host;
|
||||
|
||||
if(!is_unix_proxy) {
|
||||
#endif
|
||||
Curl_safefree(proxyinfo->host.rawalloc);
|
||||
proxyinfo->host.rawalloc = host;
|
||||
if(host[0] == '[') {
|
||||
/* this is a numerical IPv6, strip off the brackets */
|
||||
size_t len = strlen(host);
|
||||
host[len-1] = 0; /* clear the trailing bracket */
|
||||
host++;
|
||||
zonefrom_url(uhp, data, conn);
|
||||
}
|
||||
proxyinfo->host.name = host;
|
||||
host = NULL;
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
}
|
||||
#endif
|
||||
|
||||
error:
|
||||
free(proxyuser);
|
||||
free(proxypasswd);
|
||||
free(host);
|
||||
free(scheme);
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
free(path);
|
||||
#endif
|
||||
curl_url_cleanup(uhp);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -3384,25 +3426,35 @@ static CURLcode resolve_server(struct Curl_easy *data,
|
|||
struct Curl_dns_entry *hostaddr = NULL;
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
if(conn->unix_domain_socket) {
|
||||
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 */
|
||||
const char *path = conn->unix_domain_socket;
|
||||
|
||||
hostaddr = calloc(1, sizeof(struct Curl_dns_entry));
|
||||
if(!hostaddr)
|
||||
result = CURLE_OUT_OF_MEMORY;
|
||||
else {
|
||||
bool longpath = FALSE;
|
||||
hostaddr->addr = Curl_unix2addr(path, &longpath,
|
||||
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'", path);
|
||||
failf(data, "Unix socket path too long: '%s'", unix_path);
|
||||
result = CURLE_COULDNT_RESOLVE_HOST;
|
||||
}
|
||||
else
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue