Use raw sockets without curl for stratum communications.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235
diff --git a/miner.h b/miner.h
index 94c6207..7690f14 100644
--- a/miner.h
+++ b/miner.h
@@ -13,6 +13,9 @@
#include "uthash.h"
#include "logging.h"
#include "util.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
#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 0cc14da..944cc8e 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;
}