|
|
@ -199,23 +199,6 @@ out: |
|
|
|
return ptrlen; |
|
|
|
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) |
|
|
|
static void keep_sockalive(SOCKETTYPE fd) |
|
|
|
{ |
|
|
|
{ |
|
|
|
const int tcp_keepidle = 45; |
|
|
|
const int tcp_keepidle = 45; |
|
|
@ -234,6 +217,18 @@ static void keep_sockalive(SOCKETTYPE fd) |
|
|
|
# endif /* __APPLE_CC__ */ |
|
|
|
# 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) |
|
|
|
static void keep_curlalive(CURL *curl) |
|
|
|
{ |
|
|
|
{ |
|
|
|
SOCKETTYPE sock; |
|
|
|
SOCKETTYPE sock; |
|
|
@ -241,11 +236,6 @@ static void keep_curlalive(CURL *curl) |
|
|
|
curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, (long *)&sock); |
|
|
|
curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, (long *)&sock); |
|
|
|
keep_sockalive(sock); |
|
|
|
keep_sockalive(sock); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void keep_alive(CURL __maybe_unused *curl, SOCKETTYPE fd) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
keep_sockalive(fd); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
static void last_nettime(struct timeval *last) |
|
|
|
static void last_nettime(struct timeval *last) |
|
|
@ -1043,11 +1033,13 @@ static void clear_sock(struct pool *pool) |
|
|
|
{ |
|
|
|
{ |
|
|
|
ssize_t n; |
|
|
|
ssize_t n; |
|
|
|
|
|
|
|
|
|
|
|
mutex_lock(&pool->stratum_lock); |
|
|
|
if (socket_full(pool, false)) { |
|
|
|
do { |
|
|
|
mutex_lock(&pool->stratum_lock); |
|
|
|
n = recv(pool->sock, pool->sockbuf, RECVSIZE, 0); |
|
|
|
do { |
|
|
|
} while (n > 0); |
|
|
|
n = recv(pool->sock, pool->sockbuf, RECVSIZE, 0); |
|
|
|
mutex_unlock(&pool->stratum_lock); |
|
|
|
} while (n > 0); |
|
|
|
|
|
|
|
mutex_unlock(&pool->stratum_lock); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
clear_sockbuf(pool); |
|
|
|
clear_sockbuf(pool); |
|
|
|
} |
|
|
|
} |
|
|
@ -1496,70 +1488,59 @@ out: |
|
|
|
return ret; |
|
|
|
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]; |
|
|
|
struct addrinfo *servinfo, *hints, *p; |
|
|
|
CURL *curl = NULL; |
|
|
|
int sockd; |
|
|
|
double byte_count; |
|
|
|
|
|
|
|
char s[RBUFSIZE]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mutex_lock(&pool->stratum_lock); |
|
|
|
mutex_lock(&pool->stratum_lock); |
|
|
|
pool->stratum_active = false; |
|
|
|
pool->stratum_active = false; |
|
|
|
if (pool->stratum_curl) { |
|
|
|
if (pool->sock) |
|
|
|
/* See above in suspend_stratum */ |
|
|
|
|
|
|
|
CLOSESOCKET(pool->sock); |
|
|
|
CLOSESOCKET(pool->sock); |
|
|
|
} |
|
|
|
pool->sock = 0; |
|
|
|
pool->stratum_curl = curl_easy_init(); |
|
|
|
|
|
|
|
if (unlikely(!pool->stratum_curl)) |
|
|
|
|
|
|
|
quit(1, "Failed to curl_easy_init in initiate_stratum"); |
|
|
|
|
|
|
|
mutex_unlock(&pool->stratum_lock); |
|
|
|
mutex_unlock(&pool->stratum_lock); |
|
|
|
|
|
|
|
|
|
|
|
curl = pool->stratum_curl; |
|
|
|
hints = &pool->stratum_hints; |
|
|
|
|
|
|
|
memset(hints, 0, sizeof(struct addrinfo)); |
|
|
|
if (!pool->sockbuf) { |
|
|
|
hints->ai_family = AF_UNSPEC; |
|
|
|
pool->sockbuf = calloc(RBUFSIZE, 1); |
|
|
|
hints->ai_socktype = SOCK_STREAM; |
|
|
|
if (!pool->sockbuf) |
|
|
|
if (getaddrinfo(pool->sockaddr_url, pool->stratum_port, hints, &servinfo) != 0) { |
|
|
|
quit(1, "Failed to calloc pool sockbuf in initiate_stratum"); |
|
|
|
applog(LOG_WARNING, "Failed to getaddrinfo on %s:%s", |
|
|
|
pool->sockbuf_size = RBUFSIZE; |
|
|
|
pool->sockaddr_url, pool->stratum_port); |
|
|
|
|
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Create a http url for use with curl */ |
|
|
|
for (p = servinfo; p != NULL; p = p->ai_next) { |
|
|
|
sprintf(s, "http://%s:%s", pool->sockaddr_url, pool->stratum_port); |
|
|
|
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); |
|
|
|
if (connect(sockd, p->ai_addr, p->ai_addrlen) == -1) { |
|
|
|
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 30); |
|
|
|
CLOSESOCKET(sockd); |
|
|
|
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_err_str); |
|
|
|
applog(LOG_DEBUG, "Failed connect"); |
|
|
|
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); |
|
|
|
continue; |
|
|
|
curl_easy_setopt(curl, CURLOPT_URL, s); |
|
|
|
} |
|
|
|
if (!opt_delaynet) |
|
|
|
|
|
|
|
curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 1); |
|
|
|
break; |
|
|
|
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); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
curl_easy_setopt(curl, CURLOPT_CONNECT_ONLY, 1); |
|
|
|
freeaddrinfo(servinfo); |
|
|
|
if (curl_easy_perform(curl)) { |
|
|
|
if (p == NULL) { |
|
|
|
applog(LOG_INFO, "Stratum connect failed to pool %d: %s", |
|
|
|
applog(LOG_WARNING, "Failed to find servinfo on %s:%s", |
|
|
|
pool->pool_no, curl_err_str); |
|
|
|
pool->sockaddr_url, pool->stratum_port); |
|
|
|
/* Hopefully we can just clean this curl handle up properly */ |
|
|
|
|
|
|
|
curl_easy_cleanup(curl); |
|
|
|
|
|
|
|
pool->stratum_curl = NULL; |
|
|
|
|
|
|
|
return false; |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
curl_easy_getinfo(curl, CURLINFO_LASTSOCKET, (long *)&pool->sock); |
|
|
|
|
|
|
|
keep_alive(curl, pool->sock); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pool->cgminer_pool_stats.times_sent++; |
|
|
|
if (!pool->sockbuf) { |
|
|
|
if (curl_easy_getinfo(curl, CURLINFO_SIZE_UPLOAD, &byte_count) == CURLE_OK) |
|
|
|
pool->sockbuf = calloc(RBUFSIZE, 1); |
|
|
|
pool->cgminer_pool_stats.bytes_sent += byte_count; |
|
|
|
if (!pool->sockbuf) |
|
|
|
pool->cgminer_pool_stats.times_received++; |
|
|
|
quit(1, "Failed to calloc pool sockbuf in initiate_stratum"); |
|
|
|
if (curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &byte_count) == CURLE_OK) |
|
|
|
pool->sockbuf_size = RBUFSIZE; |
|
|
|
pool->cgminer_pool_stats.bytes_received += byte_count; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pool->sock = sockd; |
|
|
|
|
|
|
|
keep_sockalive(sockd); |
|
|
|
return true; |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1598,13 +1579,9 @@ void suspend_stratum(struct pool *pool) |
|
|
|
|
|
|
|
|
|
|
|
mutex_lock(&pool->stratum_lock); |
|
|
|
mutex_lock(&pool->stratum_lock); |
|
|
|
pool->stratum_active = pool->stratum_notify = false; |
|
|
|
pool->stratum_active = pool->stratum_notify = false; |
|
|
|
if (pool->stratum_curl) { |
|
|
|
if (pool->sock) |
|
|
|
/* libcurl seems to crash occasionally on this since so just
|
|
|
|
|
|
|
|
* sacrifice the ram knowing we leak one curl handle every |
|
|
|
|
|
|
|
* time we disconnect stratum. */ |
|
|
|
|
|
|
|
CLOSESOCKET(pool->sock); |
|
|
|
CLOSESOCKET(pool->sock); |
|
|
|
} |
|
|
|
pool->sock = 0; |
|
|
|
pool->stratum_curl = NULL; |
|
|
|
|
|
|
|
mutex_unlock(&pool->stratum_lock); |
|
|
|
mutex_unlock(&pool->stratum_lock); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -1617,7 +1594,7 @@ bool initiate_stratum(struct pool *pool) |
|
|
|
int n2size; |
|
|
|
int n2size; |
|
|
|
|
|
|
|
|
|
|
|
resend: |
|
|
|
resend: |
|
|
|
if (!setup_stratum_curl(pool)) { |
|
|
|
if (!setup_stratum_socket(pool)) { |
|
|
|
sockd = false; |
|
|
|
sockd = false; |
|
|
|
goto out; |
|
|
|
goto out; |
|
|
|
} |
|
|
|
} |
|
|
|