@ -968,37 +968,59 @@ static void clear_sock(struct pool *pool)
strcpy ( pool - > sockbuf , " " ) ;
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
/* 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 */
* from the socket and returns that as a malloced char */
char * recv_line ( struct pool * pool )
char * recv_line ( struct pool * pool )
{
{
ssize_t len , buflen ;
ssize_t len , buflen ;
char * tok , * sret = NULL ;
char * tok , * sret = NULL ;
ssize_t n ;
if ( ! strstr ( pool - > sockbuf , " \n " ) ) {
if ( ! strstr ( pool - > sockbuf , " \n " ) ) {
char s [ RBUFSIZE ] ;
struct timeval rstart , now ;
size_t sspace ;
gettimeofday ( & rstart , NULL ) ;
if ( ! socket_full ( pool , true ) ) {
if ( ! socket_full ( pool , true ) ) {
applog ( LOG_DEBUG , " Timed out waiting for data on socket_full " ) ;
applog ( LOG_DEBUG , " Timed out waiting for data on socket_full " ) ;
goto out ;
goto out ;
}
}
memset ( s , 0 , RBUFSIZE ) ;
mutex_lock ( & pool - > stratum_lock ) ;
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 ) ;
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 ) ;
buflen = strlen ( pool - > sockbuf ) ;
@ -1350,6 +1372,13 @@ bool initiate_stratum(struct pool *pool)
mutex_unlock ( & pool - > stratum_lock ) ;
mutex_unlock ( & pool - > stratum_lock ) ;
curl = pool - > stratum_curl ;
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 */
/* Create a http url for use with curl */
memset ( s , 0 , RBUFSIZE ) ;
memset ( s , 0 , RBUFSIZE ) ;
sprintf ( s , " http://%s:%s " , pool - > sockaddr_url , pool - > stratum_port ) ;
sprintf ( s , " http://%s:%s " , pool - > sockaddr_url , pool - > stratum_port ) ;