| 
						
						
							
								
							
						
						
					 | 
				
				 | 
				 | 
				
					@ -75,6 +75,9 @@ struct client_instance {
					 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						/* Time this client started blocking, 0 when not blocked */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						time_t blocked_time; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						/* The size of the socket send buffer */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						int sendbufsize; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					struct sender_send { | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				 | 
				
					@ -153,6 +156,9 @@ struct connector_data {
					 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						/* Pending sends to the upstream server */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						ckmsgq_t *upstream_sends; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						connsock_t upstream_cs; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						/* Have we given the warning about inability to raise sendbuf size */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						bool wmem_warn; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					typedef struct connector_data cdata_t; | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				 | 
				
					@ -228,6 +234,7 @@ static int accept_client(cdata_t *cdata, const int epfd, const uint64_t server)
					 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						client_instance_t *client; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						struct epoll_event event; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						socklen_t address_len; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						socklen_t optlen; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						ck_rlock(&cdata->lock); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						no_clients = HASH_COUNT(cdata->clients); | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				 | 
				
					@ -302,6 +309,9 @@ static int accept_client(cdata_t *cdata, const int epfd, const uint64_t server)
					 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						 * removes it automatically from the epoll list. */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						__inc_instance_ref(client); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						client->fd = fd; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						optlen = sizeof(client->sendbufsize); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &client->sendbufsize, &optlen); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						LOGDEBUG("Client sendbufsize detected as %d", client->sendbufsize); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						return 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					} | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				 | 
				
					@ -669,6 +679,35 @@ static bool send_sender_send(ckpool_t *ckp, cdata_t *cdata, sender_send_t *sende
					 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						client->sending = sender_send; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						now_t = time(NULL); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						/* Increase sendbufsize to match large messages sent to clients - this
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						 * usually only applies to clients as mining nodes. */ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						if (unlikely(sender_send->len > client->sendbufsize && !cdata->wmem_warn)) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
							int opt, len = sender_send->len; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
							socklen_t optlen; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
							optlen = sizeof(opt); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
							opt = len * 4 / 3; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
							setsockopt(client->fd, SOL_SOCKET, SO_SNDBUF, &opt, optlen); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
							getsockopt(client->fd, SOL_SOCKET, SO_SNDBUF, &opt, &optlen); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
							opt /= 2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
							if (opt < len) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
								LOGDEBUG("Failed to set desired sendbufsize of %d unprivileged, only got %d", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
									 len, opt); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
								optlen = sizeof(opt); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
								opt = len * 4 / 3; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
								setsockopt(client->fd, SOL_SOCKET, SO_SNDBUFFORCE, &opt, optlen); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
								getsockopt(client->fd, SOL_SOCKET, SO_SNDBUF, &opt, &optlen); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
								opt /= 2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
							} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
							client->sendbufsize = opt; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
							if (opt < len) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
								LOGWARNING("Failed to increase sendbufsize to %d, increase wmem_max or start %s privileged", | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
									   len, ckp->name); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
								cdata->wmem_warn = true; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
							} else | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
								LOGDEBUG("Increased sendbufsize to %d of desired %d", opt, len); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
						while (sender_send->len) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
							int ret = write(client->fd, sender_send->buf + sender_send->ofs, sender_send->len); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				 | 
				
					
 | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
				
				 | 
				 | 
				
					
 
					 |