Permalink
Browse files

Change the pool stratum socket buffer to be dynamically allocated to …

…accomodate any size coinbase and keep receiving data in recv line for up to 60s if no end of line has been received.
  • Loading branch information...
1 parent 6e2e7d3 commit e1387dc85cd63b1bcd588fc35919210c23ff4197 @ckolivas committed Dec 29, 2012
Showing with 48 additions and 18 deletions.
  1. +4 −3 miner.h
  2. +44 −15 util.c
View
@@ -859,8 +859,8 @@ struct stratum_work {
double diff;
};
-#define RECVSIZE 8192
-#define RBUFSIZE (RECVSIZE + 4)
+#define RBUFSIZE 8192
+#define RECVSIZE (RBUFSIZE - 4)
struct pool {
int pool_no;
@@ -929,7 +929,8 @@ struct pool {
char *stratum_port;
CURL *stratum_curl;
SOCKETTYPE sock;
- char sockbuf[RBUFSIZE];
+ char *sockbuf;
+ size_t sockbuf_size;
char *sockaddr_url; /* stripped url used for sockaddr */
char *nonce1;
uint32_t nonce2;
View
59 util.c
@@ -968,37 +968,59 @@ static void clear_sock(struct pool *pool)
strcpy(pool->sockbuf, "");
}
+/* Make sure the pool sockbuf is large enough to cope with any coinbase size
+ * by reallocing it to a large enough size rounded up to a multiple of RBUFSIZE
+ * and zeroing the new memory */
+static void recalloc_sock(struct pool *pool, size_t len)
+{
+ size_t old, new;
+
+ old = strlen(pool->sockbuf);
+ new = old + len + 1;
+ if (new < pool->sockbuf_size)
+ return;
+ new = new + (RBUFSIZE - (new % RBUFSIZE));
+ applog(LOG_DEBUG, "Recallocing pool sockbuf to %d", new);
+ pool->sockbuf = realloc(pool->sockbuf, new);
+ if (!pool->sockbuf)
+ quit(1, "Failed to realloc pool sockbuf in recalloc_sock");
+ memset(pool->sockbuf + old, 0, new - old);
+ pool->sockbuf_size = new;
+}
+
/* Peeks at a socket to find the first end of line and then reads just that
* from the socket and returns that as a malloced char */
char *recv_line(struct pool *pool)
{
ssize_t len, buflen;
char *tok, *sret = NULL;
- ssize_t n;
if (!strstr(pool->sockbuf, "\n")) {
- char s[RBUFSIZE];
- size_t sspace;
+ struct timeval rstart, now;
+ gettimeofday(&rstart, NULL);
if (!socket_full(pool, true)) {
applog(LOG_DEBUG, "Timed out waiting for data on socket_full");
goto out;
}
- memset(s, 0, RBUFSIZE);
mutex_lock(&pool->stratum_lock);
- n = recv(pool->sock, s, RECVSIZE, 0);
+ do {
+ char s[RBUFSIZE];
+ size_t slen, n;
+
+ memset(s, 0, RBUFSIZE);
+ n = recv(pool->sock, s, RECVSIZE, 0);
+ if (n < 1 && errno != EAGAIN && errno != EWOULDBLOCK) {
+ applog(LOG_DEBUG, "Failed to recv sock in recv_line");
+ break;
+ }
+ slen = strlen(s);
+ recalloc_sock(pool, slen);
+ strcat(pool->sockbuf, s);
+ gettimeofday(&now, NULL);
+ } while (tdiff(&now, &rstart) < 60 && !strstr(pool->sockbuf, "\n"));
mutex_unlock(&pool->stratum_lock);
-
- if (n < 1 && errno != EAGAIN && errno != EWOULDBLOCK) {
- applog(LOG_DEBUG, "Failed to recv sock in recv_line");
- goto out;
- }
- /* Prevent buffer overflows, but if 8k is still not enough,
- * likely we have had some comms issues and the data is all
- * useless anyway */
- sspace = RECVSIZE - strlen(pool->sockbuf);
- strncat(pool->sockbuf, s, sspace);
}
buflen = strlen(pool->sockbuf);
@@ -1350,6 +1372,13 @@ bool initiate_stratum(struct pool *pool)
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;
+ }
+
/* Create a http url for use with curl */
memset(s, 0, RBUFSIZE);
sprintf(s, "http://%s:%s", pool->sockaddr_url, pool->stratum_port);

0 comments on commit e1387dc

Please sign in to comment.