From 812f7541fdbd51e2cf855d86f495a019cd2cf2ba Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sat, 7 Sep 2013 15:36:48 +1000 Subject: [PATCH 1/7] Change message in status when using a balanced pool strategy to notify if there's a stratum pool as well. --- cgminer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cgminer.c b/cgminer.c index 892c6cf4..bbf57e8d 100644 --- a/cgminer.c +++ b/cgminer.c @@ -2148,7 +2148,7 @@ static void curses_print_status(void) local_work, total_go, total_ro); wclrtoeol(statuswin); if ((pool_strategy == POOL_LOADBALANCE || pool_strategy == POOL_BALANCE) && total_pools > 1) { - cg_mvwprintw(statuswin, 4, 0, " Connected to multiple pools with%s LP", + cg_mvwprintw(statuswin, 4, 0, " Connected to multiple pools with%s block change notify", have_longpoll ? "": "out"); } else if (pool->has_stratum) { cg_mvwprintw(statuswin, 4, 0, " Connected to %s diff %s with stratum as user %s", @@ -5318,6 +5318,8 @@ static void *stratum_sthread(void *userdata) static void init_stratum_threads(struct pool *pool) { + have_longpoll = true; + if (unlikely(pthread_create(&pool->stratum_sthread, NULL, stratum_sthread, (void *)pool))) quit(1, "Failed to create stratum sthread"); if (unlikely(pthread_create(&pool->stratum_rthread, NULL, stratum_rthread, (void *)pool))) From 5b378f443a06d8a3ae4682ed459117e74fccb23b Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sat, 7 Sep 2013 15:41:07 +1000 Subject: [PATCH 2/7] Increase the time for the waiting for work message to be given to be greater than that required for a pool swap in the scheduler which is set to 5s. --- cgminer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cgminer.c b/cgminer.c index bbf57e8d..76fd1c58 100644 --- a/cgminer.c +++ b/cgminer.c @@ -5547,15 +5547,15 @@ static struct work *hash_pop(void) int rc; cgtime(&now); - then.tv_sec = now.tv_sec + 5; + then.tv_sec = now.tv_sec + 10; then.tv_nsec = now.tv_usec * 1000; rc = pthread_cond_timedwait(&getq->cond, stgd_lock, &then); /* Check again for !no_work as multiple threads may be * waiting on this condition and another may set the * bool separately. */ if (rc && !no_work) { - applog(LOG_WARNING, "Waiting for work to be available from pools."); no_work = true; + applog(LOG_WARNING, "Waiting for work to be available from pools."); } } else pthread_cond_wait(&getq->cond, stgd_lock); From a41660f2f00a6955e9448a29287cf8b0e5b5a468 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sat, 7 Sep 2013 19:02:38 +1000 Subject: [PATCH 3/7] Only show long-poll message in pool summary if it's not using stratum. --- cgminer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cgminer.c b/cgminer.c index 76fd1c58..d2b7b152 100644 --- a/cgminer.c +++ b/cgminer.c @@ -3952,7 +3952,8 @@ static void display_pool_summary(struct pool *pool) wlog("Pool: %s\n", pool->rpc_url); if (pool->solved) wlog("SOLVED %d BLOCK%s!\n", pool->solved, pool->solved > 1 ? "S" : ""); - wlog("%s own long-poll support\n", pool->hdr_path ? "Has" : "Does not have"); + if (!pool->has_stratum) + wlog("%s own long-poll support\n", pool->hdr_path ? "Has" : "Does not have"); wlog(" Queued work requests: %d\n", pool->getwork_requested); wlog(" Share submissions: %d\n", pool->accepted + pool->rejected); wlog(" Accepted shares: %d\n", pool->accepted); From 9f87d2abafd9fd577c31b0484aff288bc2a411cd Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 8 Sep 2013 00:34:53 +1000 Subject: [PATCH 4/7] Remove now redundant FAQ regarding proxies. --- README | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README b/README index c0d35b30..0d489137 100644 --- a/README +++ b/README @@ -755,11 +755,6 @@ every time cgminer looks for new hardware to hotplug it it can cause these sorts of problems. You can disable hotplug with: --hotplug 0 -Q: Can I use a proxy? -A: Proxies only work with the getwork and GBT protocols using the --proxy -command. If you wish to use a proxy with stratum, people have supported -success with various 3rd party tools like proxifier. - Q: What should my Work Utility (WU) be? A: Work utility is the product of hashrate * luck and only stabilises over a very long period of time. Assuming all your work is valid work, bitcoin mining From f652b1e29135c496b3338e113e66b00e24198310 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 8 Sep 2013 10:14:19 +1000 Subject: [PATCH 5/7] Fix warning on mingw build. --- util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util.c b/util.c index 550f4ed8..52ab46b2 100644 --- a/util.c +++ b/util.c @@ -1726,7 +1726,7 @@ bool auth_stratum(struct pool *pool) static int recv_byte(int sockd) { - unsigned char c; + char c; if (recv(sockd, &c, 1, 0) != -1) return c; From 89c07fa5c739c5a0f3c58fff7586e71bbb358699 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 8 Sep 2013 16:32:44 +1000 Subject: [PATCH 6/7] Add support for socks4/4a proxies with stratum, and drop back to socks4 support via the global --socks-proxy command to not break previous configurations. --- README | 2 +- cgminer.c | 2 +- util.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 85 insertions(+), 3 deletions(-) diff --git a/README b/README index 0d489137..7997059e 100644 --- a/README +++ b/README @@ -185,7 +185,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 socks proxy (host:port) for all pools without a proxy specified +--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 diff --git a/cgminer.c b/cgminer.c index d2b7b152..2936eeb2 100644 --- a/cgminer.c +++ b/cgminer.c @@ -1249,7 +1249,7 @@ static struct opt_table opt_config_table[] = { "Quit after mining N shares (default: unlimited)"), OPT_WITH_ARG("--socks-proxy", opt_set_charp, NULL, &opt_socks_proxy, - "Set socks proxy (host:port)"), + "Set socks4 proxy (host:port)"), #ifdef HAVE_SYSLOG_H OPT_WITHOUT_ARG("--syslog", opt_set_bool, &use_syslog, diff --git a/util.c b/util.c index 52ab46b2..d49b09a6 100644 --- a/util.c +++ b/util.c @@ -347,7 +347,7 @@ json_t *json_rpc_call(CURL *curl, const char *url, 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_SOCKS5); + curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS4); } if (userpass) { curl_easy_setopt(curl, CURLOPT_USERPWD, userpass); @@ -1851,6 +1851,80 @@ static bool socks5_negotiate(struct pool *pool, int sockd) return true; } +static bool socks4_negotiate(struct pool *pool, int sockd, bool socks4a) +{ + unsigned short port; + in_addr_t inp; + char buf[515]; + int i, len; + + buf[0] = 0x04; + buf[1] = 0x01; + port = atoi(pool->stratum_port); + buf[2] = port >> 8; + buf[3] = port & 0xff; + sprintf(&buf[8], "CGMINER"); + + /* See if we've been given an IP address directly to avoid needing to + * resolve it. */ + inp = inet_network(pool->sockaddr_url); + if ((int)inp != -1) + socks4a = false; + else { + /* Try to extract the IP address ourselves first */ + struct addrinfo servinfobase, *servinfo, hints; + + servinfo = &servinfobase; + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_INET; /* IPV4 only */ + if (!getaddrinfo(pool->sockaddr_url, NULL, &hints, &servinfo)) { + struct sockaddr_in *saddr_in = (struct sockaddr_in *)servinfo->ai_addr; + + inp = ntohl(saddr_in->sin_addr.s_addr); + socks4a = false; + freeaddrinfo(servinfo); + } + } + + if (!socks4a) { + if ((int)inp == -1) { + applog(LOG_WARNING, "Invalid IP address specified for socks4 proxy: %s", + pool->sockaddr_url); + return false; + } + buf[4] = (inp >> 24) & 0xFF; + buf[5] = (inp >> 16) & 0xFF; + buf[6] = (inp >> 8) & 0xFF; + buf[7] = (inp >> 0) & 0xFF; + send(sockd, buf, 16, 0); + } else { + /* This appears to not be working but hopefully most will be + * able to resolve IP addresses themselves. */ + buf[4] = 0; + buf[5] = 0; + buf[6] = 0; + buf[7] = 1; + len = strlen(pool->sockaddr_url); + if (len > 255) + len = 255; + memcpy(&buf[16], pool->sockaddr_url, len); + len += 16; + buf[len++] = '\0'; + send(sockd, buf, len, 0); + } + + if (recv_byte(sockd) != 0x00 || recv_byte(sockd) != 0x5a) { + applog(LOG_WARNING, "Bad response from %s:%s SOCKS4 server", + pool->sockaddr_proxy_url, pool->sockaddr_proxy_port); + return false; + } + + for (i = 0; i < 6; i++) + recv_byte(sockd); + + return true; +} + static bool setup_stratum_socket(struct pool *pool) { struct addrinfo servinfobase, *servinfo, *hints, pbase, *p; @@ -1933,6 +2007,14 @@ static bool setup_stratum_socket(struct pool *pool) if (!socks5_negotiate(pool, sockd)) return false; break; + case CURLPROXY_SOCKS4: + if (!socks4_negotiate(pool, sockd, false)) + return false; + break; + case CURLPROXY_SOCKS4A: + if (!socks4_negotiate(pool, sockd, true)) + return false; + break; default: applog(LOG_WARNING, "Unsupported proxy type for %s:%s", pool->sockaddr_proxy_url, pool->sockaddr_proxy_port); From 7570d885daa707888addb457e60524292d71edf6 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 8 Sep 2013 19:54:18 +1000 Subject: [PATCH 7/7] Remove unused pbase variable. --- util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/util.c b/util.c index d49b09a6..fc488a49 100644 --- a/util.c +++ b/util.c @@ -1927,7 +1927,7 @@ static bool socks4_negotiate(struct pool *pool, int sockd, bool socks4a) static bool setup_stratum_socket(struct pool *pool) { - struct addrinfo servinfobase, *servinfo, *hints, pbase, *p; + struct addrinfo servinfobase, *servinfo, *hints, *p; char *sockaddr_url, *sockaddr_port; int sockd; @@ -1943,7 +1943,7 @@ static bool setup_stratum_socket(struct pool *pool) hints->ai_family = AF_UNSPEC; hints->ai_socktype = SOCK_STREAM; servinfo = &servinfobase; - p = &pbase; + if (!pool->rpc_proxy && opt_socks_proxy) { pool->rpc_proxy = opt_socks_proxy; extract_sockaddr(pool->rpc_proxy, &pool->sockaddr_proxy_url, &pool->sockaddr_proxy_port);