diff --git a/README b/README index 1438008a..e2a005fe 100644 --- a/README +++ b/README @@ -168,7 +168,7 @@ Options for both config file and command line: --scrypt Use the scrypt algorithm for mining (litecoin only) --sharelog Append share log to file --shares Quit after mining N shares (default: unlimited) ---socks-proxy Set socks4 proxy (host:port) +--socks-proxy Set socks4 proxy (host:port) for all pools without a proxy specified --syslog Use system log for output messages (default: standard error) --temp-cutoff Temperature where a device will be automatically disabled, one value or comma separated list (default: 95) --text-only|-T Disable ncurses formatted screen output @@ -295,6 +295,28 @@ Add overclocking settings, GPU and fan control with different engine settings fo cgminer -o http://pool:port -u username -p password -I 9 --auto-fan --auto-gpu --gpu-engine 750-950,945,700-930,960 --gpu-memclock 300 +Single pool with a standard http proxy, regular desktop: + +cgminer -o http:proxy:port|http://pool:port -u username -p password + +Single pool with a socks5 proxy, regular desktop: + +cgminer -o socks5:proxy:port|http://pool:port -u username -p password + +The list of proxy types are: + http: standard http 1.1 proxy + http0: http 1.0 proxy + socks4: socks4 proxy + socks5: socks5 proxy + socks4a: socks4a proxy + socks5h: socks5 proxy using a hostname + +If you compile cgminer with a version of CURL before 7.19.4 then some of the above will +not be available. All are available since CURL version 7.19.4 + +If you specify the --socks-proxy option to cgminer, it will only be applied to all pools +that don't specify their own proxy setting like above + READ WARNINGS AND DOCUMENTATION BELOW ABOUT OVERCLOCKING On Linux you virtually always need to export your display settings before diff --git a/api.c b/api.c index 4aefcf01..e3185188 100644 --- a/api.c +++ b/api.c @@ -1841,6 +1841,13 @@ static void poolstatus(__maybe_unused SOCKETTYPE c, __maybe_unused char *param, root = api_add_escape(root, "User", pool->rpc_user, false); root = api_add_time(root, "Last Share Time", &(pool->last_share_time), false); root = api_add_int(root, "Diff1 Work", &(pool->diff1), false); + if (pool->rpc_proxy) { + root = api_add_const(root, "Proxy Type", proxytype(pool->rpc_proxytype), false); + root = api_add_escape(root, "Proxy", pool->rpc_proxy, false); + } else { + root = api_add_const(root, "Proxy Type", BLANK, false); + root = api_add_const(root, "Proxy", BLANK, false); + } if (isjson && (i > 0)) strcat(io_buffer, COMMA); diff --git a/cgminer.c b/cgminer.c index 69976f33..e1a37a17 100644 --- a/cgminer.c +++ b/cgminer.c @@ -419,6 +419,8 @@ static struct pool *add_pool(void) /* Make sure the pool doesn't think we've been idle since time 0 */ pool->tv_idle.tv_sec = ~0UL; + pool->rpc_proxy = NULL; + return pool; } @@ -547,6 +549,8 @@ static char *set_url(char *arg) add_pool(); pool = pools[total_urls - 1]; + arg = get_proxy(arg, pool); + opt_set_charp(arg, &pool->rpc_url); if (strncmp(arg, "http://", 7) && strncmp(arg, "https://", 8)) { @@ -4999,6 +5003,8 @@ void add_pool_details(bool live, char *url, char *user, char *pass) pool = add_pool(); + url = get_proxy(url, pool); + pool->rpc_url = url; pool->rpc_user = user; pool->rpc_pass = pass; diff --git a/miner.h b/miner.h index 4771176f..3167fabd 100644 --- a/miner.h +++ b/miner.h @@ -592,6 +592,8 @@ extern const uint32_t sha256_init_state[]; extern json_t *json_rpc_call(CURL *curl, const char *url, const char *userpass, const char *rpc_req, bool, bool, int *, struct pool *pool, bool); +extern const char *proxytype(curl_proxytype proxytype); +extern char *get_proxy(char *url, struct pool *pool); extern char *bin2hex(const unsigned char *p, size_t len); extern bool hex2bin(unsigned char *p, const char *hexstr, size_t len); @@ -770,6 +772,8 @@ struct pool { char *rpc_url; char *rpc_userpass; char *rpc_user, *rpc_pass; + curl_proxytype rpc_proxytype; + char *rpc_proxy; pthread_mutex_t pool_lock; diff --git a/util.c b/util.c index 724ffa9d..27866531 100644 --- a/util.c +++ b/util.c @@ -305,7 +305,10 @@ json_t *json_rpc_call(CURL *curl, const char *url, curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, resp_hdr_cb); curl_easy_setopt(curl, CURLOPT_HEADERDATA, &hi); curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_TRY); - if (opt_socks_proxy) { + if (pool->rpc_proxy) { + curl_easy_setopt(curl, CURLOPT_PROXY, pool->rpc_proxy); + curl_easy_setopt(curl, CURLOPT_PROXYTYPE, pool->rpc_proxytype); + } else if (opt_socks_proxy) { curl_easy_setopt(curl, CURLOPT_PROXY, opt_socks_proxy); curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4); } @@ -460,6 +463,68 @@ err_out: return NULL; } +#if (LIBCURL_VERSION_MAJOR == 7 && LIBCURL_VERSION_MINOR >= 10) || (LIBCURL_VERSION_MAJOR > 7) +static struct { + const char *name; + curl_proxytype proxytype; +} proxynames[] = { + { "http:", CURLPROXY_HTTP }, +#if (LIBCURL_VERSION_MAJOR > 7) || (LIBCURL_VERSION_MINOR > 19) || (LIBCURL_VERSION_MINOR == 19 && LIBCURL_VERSION_PATCH >= 4) + { "http0:", CURLPROXY_HTTP_1_0 }, +#endif +#if (LIBCURL_VERSION_MAJOR > 7) || (LIBCURL_VERSION_MINOR > 15) || (LIBCURL_VERSION_MINOR == 15 && LIBCURL_VERSION_PATCH >= 2) + { "socks4:", CURLPROXY_SOCKS4 }, +#endif + { "socks5:", CURLPROXY_SOCKS5 }, +#if (LIBCURL_VERSION_MAJOR > 7) || (LIBCURL_VERSION_MINOR >= 18) + { "socks4a:", CURLPROXY_SOCKS4A }, + { "socks5h:", CURLPROXY_SOCKS5_HOSTNAME }, +#endif +}; +#endif + +const char *proxytype(curl_proxytype proxytype) +{ + int i; + + for (i = 0; proxynames[i].name; i++) + if (proxynames[i].proxytype == proxytype) + return proxynames[i].name; + + return "invalid"; +} + +char *get_proxy(char *url, struct pool *pool) +{ + pool->rpc_proxy = NULL; + +#if (LIBCURL_VERSION_MAJOR == 7 && LIBCURL_VERSION_MINOR >= 10) || (LIBCURL_VERSION_MAJOR > 7) + char *split; + int plen, len, i; + + for (i = 0; proxynames[i].name; i++) { + plen = strlen(proxynames[i].name); + if (strncmp(url, proxynames[i].name, plen) == 0) { + if (!(split = strchr(url, '|'))) + return url; + + *split = '\0'; + len = split - url; + pool->rpc_proxy = malloc(1 + len - plen); + if (!(pool->rpc_proxy)) + quit(1, "Failed to malloc rpc_proxy"); + + strcpy(pool->rpc_proxy, url); + pool->rpc_proxytype = proxynames[i].proxytype; + url = split + 1; + break; + } + } +#endif + return url; +} + + char *bin2hex(const unsigned char *p, size_t len) { char *s = malloc((len * 2) + 1);