Browse Source

Use raw sockets without curl for stratum communications.

nfactor-troky
Con Kolivas 12 years ago
parent
commit
31aa4f6ceb
  1. 5
      miner.h
  2. 143
      util.c

5
miner.h

@ -13,6 +13,9 @@
#include "uthash.h" #include "uthash.h"
#include "logging.h" #include "logging.h"
#include "util.h" #include "util.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#ifdef HAVE_OPENCL #ifdef HAVE_OPENCL
#ifdef __APPLE_CC__ #ifdef __APPLE_CC__
@ -1104,7 +1107,7 @@ struct pool {
/* Stratum variables */ /* Stratum variables */
char *stratum_url; char *stratum_url;
char *stratum_port; char *stratum_port;
CURL *stratum_curl; struct addrinfo stratum_hints;
SOCKETTYPE sock; SOCKETTYPE sock;
char *sockbuf; char *sockbuf;
size_t sockbuf_size; size_t sockbuf_size;

143
util.c

@ -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;
} }

Loading…
Cancel
Save