From 31aa4f6cebc51e26b349606fd78d71954bda87da Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Wed, 8 May 2013 21:59:58 +1000 Subject: [PATCH] Use raw sockets without curl for stratum communications. --- miner.h | 5 +- util.c | 143 ++++++++++++++++++++++++-------------------------------- 2 files changed, 64 insertions(+), 84 deletions(-) diff --git a/miner.h b/miner.h index 94c62078..7690f14f 100644 --- a/miner.h +++ b/miner.h @@ -13,6 +13,9 @@ #include "uthash.h" #include "logging.h" #include "util.h" +#include +#include +#include #ifdef HAVE_OPENCL #ifdef __APPLE_CC__ @@ -1104,7 +1107,7 @@ struct pool { /* Stratum variables */ char *stratum_url; char *stratum_port; - CURL *stratum_curl; + struct addrinfo stratum_hints; SOCKETTYPE sock; char *sockbuf; size_t sockbuf_size; diff --git a/util.c b/util.c index 0cc14da9..944cc8e6 100644 --- a/util.c +++ b/util.c @@ -199,23 +199,6 @@ out: return ptrlen; } -#if CURL_HAS_KEEPALIVE -static void keep_curlalive(CURL *curl) -{ - const int tcp_keepidle = 45; - const int tcp_keepintvl = 30; - const long int keepalive = 1; - - curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, keepalive); - curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, tcp_keepidle); - curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, tcp_keepintvl); -} - -static void keep_alive(CURL *curl, __maybe_unused SOCKETTYPE fd) -{ - keep_curlalive(curl); -} -#else static void keep_sockalive(SOCKETTYPE fd) { const int tcp_keepidle = 45; @@ -234,6 +217,18 @@ static void keep_sockalive(SOCKETTYPE fd) # endif /* __APPLE_CC__ */ } +#if CURL_HAS_KEEPALIVE +static void keep_curlalive(CURL *curl) +{ + const int tcp_keepidle = 45; + const int tcp_keepintvl = 30; + const long int keepalive = 1; + + curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, keepalive); + curl_easy_setopt(curl, CURLOPT_TCP_KEEPIDLE, tcp_keepidle); + curl_easy_setopt(curl, CURLOPT_TCP_KEEPINTVL, tcp_keepintvl); +} +#else static void keep_curlalive(CURL *curl) { SOCKETTYPE sock; @@ -241,11 +236,6 @@ static void keep_curlalive(CURL *curl) curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, (long *)&sock); keep_sockalive(sock); } - -static void keep_alive(CURL __maybe_unused *curl, SOCKETTYPE fd) -{ - keep_sockalive(fd); -} #endif static void last_nettime(struct timeval *last) @@ -1043,11 +1033,13 @@ static void clear_sock(struct pool *pool) { ssize_t n; - mutex_lock(&pool->stratum_lock); - do { - n = recv(pool->sock, pool->sockbuf, RECVSIZE, 0); - } while (n > 0); - mutex_unlock(&pool->stratum_lock); + if (socket_full(pool, false)) { + mutex_lock(&pool->stratum_lock); + do { + n = recv(pool->sock, pool->sockbuf, RECVSIZE, 0); + } while (n > 0); + mutex_unlock(&pool->stratum_lock); + } clear_sockbuf(pool); } @@ -1496,70 +1488,59 @@ out: return ret; } -static bool setup_stratum_curl(struct pool *pool) +static bool setup_stratum_socket(struct pool *pool) { - char curl_err_str[CURL_ERROR_SIZE]; - CURL *curl = NULL; - double byte_count; - char s[RBUFSIZE]; + struct addrinfo *servinfo, *hints, *p; + int sockd; mutex_lock(&pool->stratum_lock); pool->stratum_active = false; - if (pool->stratum_curl) { - /* See above in suspend_stratum */ + if (pool->sock) CLOSESOCKET(pool->sock); - } - pool->stratum_curl = curl_easy_init(); - if (unlikely(!pool->stratum_curl)) - quit(1, "Failed to curl_easy_init in initiate_stratum"); + pool->sock = 0; mutex_unlock(&pool->stratum_lock); - curl = pool->stratum_curl; - - if (!pool->sockbuf) { - pool->sockbuf = calloc(RBUFSIZE, 1); - if (!pool->sockbuf) - quit(1, "Failed to calloc pool sockbuf in initiate_stratum"); - pool->sockbuf_size = RBUFSIZE; + hints = &pool->stratum_hints; + memset(hints, 0, sizeof(struct addrinfo)); + hints->ai_family = AF_UNSPEC; + hints->ai_socktype = SOCK_STREAM; + if (getaddrinfo(pool->sockaddr_url, pool->stratum_port, hints, &servinfo) != 0) { + applog(LOG_WARNING, "Failed to getaddrinfo on %s:%s", + pool->sockaddr_url, pool->stratum_port); + return false; } - /* Create a http url for use with curl */ - sprintf(s, "http://%s:%s", pool->sockaddr_url, pool->stratum_port); + for (p = servinfo; p != NULL; p = p->ai_next) { + sockd = socket(p->ai_family, p->ai_socktype, p->ai_protocol); + if (sockd == -1) { + applog(LOG_DEBUG, "Failed socket"); + continue; + } - curl_easy_setopt(curl, CURLOPT_FRESH_CONNECT, 1); - curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30); - curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_err_str); - curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); - curl_easy_setopt(curl, CURLOPT_URL, s); - if (!opt_delaynet) - curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 1); - curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_TRY); - 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); + if (connect(sockd, p->ai_addr, p->ai_addrlen) == -1) { + CLOSESOCKET(sockd); + applog(LOG_DEBUG, "Failed connect"); + continue; + } + + break; } - curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1); - if (curl_easy_perform(curl)) { - applog(LOG_INFO, "Stratum connect failed to pool %d: %s", - pool->pool_no, curl_err_str); - /* Hopefully we can just clean this curl handle up properly */ - curl_easy_cleanup(curl); - pool->stratum_curl = NULL; + freeaddrinfo(servinfo); + if (p == NULL) { + applog(LOG_WARNING, "Failed to find servinfo on %s:%s", + pool->sockaddr_url, pool->stratum_port); return false; } - curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, (long *)&pool->sock); - keep_alive(curl, pool->sock); - pool->cgminer_pool_stats.times_sent++; - if (curl_easy_getinfo(curl, CURLINFO_SIZE_UPLOAD, &byte_count) == CURLE_OK) - pool->cgminer_pool_stats.bytes_sent += byte_count; - pool->cgminer_pool_stats.times_received++; - if (curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &byte_count) == CURLE_OK) - pool->cgminer_pool_stats.bytes_received += byte_count; + if (!pool->sockbuf) { + pool->sockbuf = calloc(RBUFSIZE, 1); + if (!pool->sockbuf) + quit(1, "Failed to calloc pool sockbuf in initiate_stratum"); + pool->sockbuf_size = RBUFSIZE; + } + pool->sock = sockd; + keep_sockalive(sockd); return true; } @@ -1598,13 +1579,9 @@ void suspend_stratum(struct pool *pool) mutex_lock(&pool->stratum_lock); pool->stratum_active = pool->stratum_notify = false; - if (pool->stratum_curl) { - /* libcurl seems to crash occasionally on this since so just - * sacrifice the ram knowing we leak one curl handle every - * time we disconnect stratum. */ + if (pool->sock) CLOSESOCKET(pool->sock); - } - pool->stratum_curl = NULL; + pool->sock = 0; mutex_unlock(&pool->stratum_lock); } @@ -1617,7 +1594,7 @@ bool initiate_stratum(struct pool *pool) int n2size; resend: - if (!setup_stratum_curl(pool)) { + if (!setup_stratum_socket(pool)) { sockd = false; goto out; }