| 
						
						
							
								
							
						
						
					 | 
					 | 
					@ -2081,19 +2081,25 @@ static int64_t prio_sort(proxy_t *a, proxy_t *b) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return (a->priority - b->priority); | 
					 | 
					 | 
					 | 
						return (a->priority - b->priority); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					/* Masked increment */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static int64_t masked_inc(int64_t value, int64_t mask) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						value &= ~mask; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						value++; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						value |= mask; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						return value; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/* Priority values can be sparse, they do not need to be sequential */ | 
					 | 
					 | 
					 | 
					/* Priority values can be sparse, they do not need to be sequential */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void __set_proxy_prio(sdata_t *sdata, proxy_t *proxy, int64_t priority) | 
					 | 
					 | 
					 | 
					static void __set_proxy_prio(sdata_t *sdata, proxy_t *proxy, int64_t priority) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						proxy_t *tmpa, *tmpb, *exists = NULL; | 
					 | 
					 | 
					 | 
						proxy_t *tmpa, *tmpb, *exists = NULL; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						int64_t next_prio = 0; | 
					 | 
					 | 
					 | 
						int64_t mask, next_prio = 0; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/* Encode the userid as the high bits in priority */ | 
					 | 
					 | 
					 | 
						/* Encode the userid as the high bits in priority */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (!proxy->global) { | 
					 | 
					 | 
					 | 
						mask = proxy->userid; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							int64_t high_bits = proxy->userid; | 
					 | 
					 | 
					 | 
						mask <<= 32; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
						priority |= mask; | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							high_bits <<= 32; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							priority |= high_bits; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/* See if the priority is already in use */ | 
					 | 
					 | 
					 | 
						/* See if the priority is already in use */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						HASH_ITER(hh, sdata->proxies, tmpa, tmpb) { | 
					 | 
					 | 
					 | 
						HASH_ITER(hh, sdata->proxies, tmpa, tmpb) { | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -2101,7 +2107,7 @@ static void __set_proxy_prio(sdata_t *sdata, proxy_t *proxy, int64_t priority) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								break; | 
					 | 
					 | 
					 | 
								break; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (tmpa->priority == priority) { | 
					 | 
					 | 
					 | 
							if (tmpa->priority == priority) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								exists = tmpa; | 
					 | 
					 | 
					 | 
								exists = tmpa; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								next_prio = exists->priority + 1; | 
					 | 
					 | 
					 | 
								next_prio = masked_inc(priority, mask); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								break; | 
					 | 
					 | 
					 | 
								break; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							} | 
					 | 
					 | 
					 | 
							} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -2109,7 +2115,7 @@ static void __set_proxy_prio(sdata_t *sdata, proxy_t *proxy, int64_t priority) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						HASH_ITER(hh, exists, tmpa, tmpb) { | 
					 | 
					 | 
					 | 
						HASH_ITER(hh, exists, tmpa, tmpb) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (tmpa->priority > next_prio) | 
					 | 
					 | 
					 | 
							if (tmpa->priority > next_prio) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								break; | 
					 | 
					 | 
					 | 
								break; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							tmpa->priority++; | 
					 | 
					 | 
					 | 
							tmpa->priority = masked_inc(tmpa->priority, mask); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							next_prio++; | 
					 | 
					 | 
					 | 
							next_prio++; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						proxy->priority = priority; | 
					 | 
					 | 
					 | 
						proxy->priority = priority; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -2225,11 +2231,16 @@ static proxy_t *existing_subproxy(sdata_t *sdata, const int id, const int subid) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return subproxy; | 
					 | 
					 | 
					 | 
						return subproxy; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static void check_userproxies(sdata_t *sdata, proxy_t *proxy, const int userid); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void set_proxy_prio(sdata_t *sdata, proxy_t *proxy, const int priority) | 
					 | 
					 | 
					 | 
					static void set_proxy_prio(sdata_t *sdata, proxy_t *proxy, const int priority) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						mutex_lock(&sdata->proxy_lock); | 
					 | 
					 | 
					 | 
						mutex_lock(&sdata->proxy_lock); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						__set_proxy_prio(sdata, proxy, priority); | 
					 | 
					 | 
					 | 
						__set_proxy_prio(sdata, proxy, priority); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						mutex_unlock(&sdata->proxy_lock); | 
					 | 
					 | 
					 | 
						mutex_unlock(&sdata->proxy_lock); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						if (!proxy->global) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							check_userproxies(sdata, proxy, proxy->userid); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/* Set proxy to the current proxy and calculate how much headroom it has */ | 
					 | 
					 | 
					 | 
					/* Set proxy to the current proxy and calculate how much headroom it has */ | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -2290,7 +2301,7 @@ static void generator_recruit(const ckpool_t *ckp, const int proxyid, const int | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/* Find how much headroom we have and connect up to that many clients that are
 | 
					 | 
					 | 
					 | 
					/* Find how much headroom we have and connect up to that many clients that are
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * not currently on this pool, recruiting more slots to switch more clients | 
					 | 
					 | 
					 | 
					 * not currently on this pool, recruiting more slots to switch more clients | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * later on lazily. Only reconnect clients bound to global proxies. */ | 
					 | 
					 | 
					 | 
					 * later on lazily. Only reconnect clients bound to global proxies. */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void reconnect_clients(sdata_t *sdata) | 
					 | 
					 | 
					 | 
					static void reconnect_global_clients(sdata_t *sdata) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						stratum_instance_t *client, *tmpclient; | 
					 | 
					 | 
					 | 
						stratum_instance_t *client, *tmpclient; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						int reconnects = 0; | 
					 | 
					 | 
					 | 
						int reconnects = 0; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -2372,6 +2383,32 @@ static void check_bestproxy(sdata_t *sdata) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							LOGNOTICE("Stratifier setting active proxy to %d", changed_id); | 
					 | 
					 | 
					 | 
							LOGNOTICE("Stratifier setting active proxy to %d", changed_id); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static proxy_t *best_proxy(sdata_t *sdata) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						proxy_t *proxy; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						mutex_lock(&sdata->proxy_lock); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						proxy = sdata->proxy; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						mutex_unlock(&sdata->proxy_lock); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						return proxy; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static void check_globalproxies(sdata_t *sdata, proxy_t *proxy) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						check_bestproxy(sdata); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						if (proxy->parent == best_proxy(sdata)->parent) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							reconnect_global_clients(sdata); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					static void check_proxy(sdata_t *sdata, proxy_t *proxy) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						if (proxy->global) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							check_globalproxies(sdata, proxy); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						else | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							check_userproxies(sdata, proxy, proxy->userid); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void dead_proxyid(sdata_t *sdata, const int id, const int subid, const bool replaced, const bool deleted) | 
					 | 
					 | 
					 | 
					static void dead_proxyid(sdata_t *sdata, const int id, const int subid, const bool replaced, const bool deleted) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						stratum_instance_t *client, *tmp; | 
					 | 
					 | 
					 | 
						stratum_instance_t *client, *tmp; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -2383,6 +2420,7 @@ static void dead_proxyid(sdata_t *sdata, const int id, const int subid, const bo | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (proxy) { | 
					 | 
					 | 
					 | 
						if (proxy) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							proxy->dead = true; | 
					 | 
					 | 
					 | 
							proxy->dead = true; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							proxy->deleted = deleted; | 
					 | 
					 | 
					 | 
							proxy->deleted = deleted; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							set_proxy_prio(sdata, proxy, 0xFFFF); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (!replaced && proxy->global) | 
					 | 
					 | 
					 | 
							if (!replaced && proxy->global) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								check_bestproxy(sdata); | 
					 | 
					 | 
					 | 
								check_bestproxy(sdata); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -2516,6 +2554,8 @@ static void update_subscribe(ckpool_t *ckp, const char *cmd) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							LOGWARNING("Only able to set nonce2len %d of requested %d on proxy %d:%d", | 
					 | 
					 | 
					 | 
							LOGWARNING("Only able to set nonce2len %d of requested %d on proxy %d:%d", | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								   proxy->enonce2varlen, ckp->nonce2length, id, subid); | 
					 | 
					 | 
					 | 
								   proxy->enonce2varlen, ckp->nonce2length, id, subid); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						json_decref(val); | 
					 | 
					 | 
					 | 
						json_decref(val); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						check_proxy(sdata, proxy); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/* Find the highest priority alive proxy belonging to userid and recruit extra
 | 
					 | 
					 | 
					 | 
					/* Find the highest priority alive proxy belonging to userid and recruit extra
 | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -2544,7 +2584,7 @@ static void recruit_best_userproxy(sdata_t *sdata, const int userid, const int r | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					/* Check how much headroom the userid proxies have and reconnect any clients
 | 
					 | 
					 | 
					 | 
					/* Check how much headroom the userid proxies have and reconnect any clients
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * that are not bound to it that should be */ | 
					 | 
					 | 
					 | 
					 * that are not bound to it that should be */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void check_userproxies(sdata_t *sdata, const int userid) | 
					 | 
					 | 
					 | 
					static void check_userproxies(sdata_t *sdata, proxy_t *proxy, const int userid) | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						int64_t headroom = proxy_headroom(sdata, userid); | 
					 | 
					 | 
					 | 
						int64_t headroom = proxy_headroom(sdata, userid); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						stratum_instance_t *client, *tmpclient; | 
					 | 
					 | 
					 | 
						stratum_instance_t *client, *tmpclient; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -2558,8 +2598,10 @@ static void check_userproxies(sdata_t *sdata, const int userid) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								continue; | 
					 | 
					 | 
					 | 
								continue; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (client->user_id != userid) | 
					 | 
					 | 
					 | 
							if (client->user_id != userid) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								continue; | 
					 | 
					 | 
					 | 
								continue; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							/* Is this client bound to a dead proxy? */ | 
					 | 
					 | 
					 | 
							/* Is the client already bound to a proxy of its own userid of
 | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (!client->reconnect && client->proxy->userid == userid) | 
					 | 
					 | 
					 | 
							 * a higher priority than this one. */ | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							if (client->proxy->userid == userid && | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							    client->proxy->parent->priority <= proxy->parent->priority) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								continue; | 
					 | 
					 | 
					 | 
								continue; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (headroom-- < 1) | 
					 | 
					 | 
					 | 
							if (headroom-- < 1) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								continue; | 
					 | 
					 | 
					 | 
								continue; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -2576,17 +2618,6 @@ static void check_userproxies(sdata_t *sdata, const int userid) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							recruit_best_userproxy(sdata, userid, -headroom); | 
					 | 
					 | 
					 | 
							recruit_best_userproxy(sdata, userid, -headroom); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static proxy_t *best_proxy(sdata_t *sdata) | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						proxy_t *proxy; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						mutex_lock(&sdata->proxy_lock); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						proxy = sdata->proxy; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						mutex_unlock(&sdata->proxy_lock); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						return proxy; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					} | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static void update_notify(ckpool_t *ckp, const char *cmd) | 
					 | 
					 | 
					 | 
					static void update_notify(ckpool_t *ckp, const char *cmd) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						sdata_t *sdata = ckp->sdata, *dsdata; | 
					 | 
					 | 
					 | 
						sdata_t *sdata = ckp->sdata, *dsdata; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -2676,12 +2707,7 @@ static void update_notify(ckpool_t *ckp, const char *cmd) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								LOGNOTICE("Block hash on proxy %d changed to %s", id, dsdata->lastswaphash); | 
					 | 
					 | 
					 | 
								LOGNOTICE("Block hash on proxy %d changed to %s", id, dsdata->lastswaphash); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (proxy->global) { | 
					 | 
					 | 
					 | 
						check_proxy(sdata, proxy); | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							check_bestproxy(sdata); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (proxy->parent != best_proxy(sdata)->parent) | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								reconnect_clients(sdata); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} else | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							check_userproxies(sdata, proxy->userid); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						clean |= new_block; | 
					 | 
					 | 
					 | 
						clean |= new_block; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						LOGINFO("Proxy %d:%d broadcast updated stratum notify with%s clean", id, | 
					 | 
					 | 
					 | 
						LOGINFO("Proxy %d:%d broadcast updated stratum notify with%s clean", id, | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							subid, clean ? "" : "out"); | 
					 | 
					 | 
					 | 
							subid, clean ? "" : "out"); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
					 | 
					@ -4355,19 +4381,16 @@ static proxy_t *__best_subproxy(proxy_t *proxy) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 * running out of room. */ | 
					 | 
					 | 
					 | 
					 * running out of room. */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					static sdata_t *select_sdata(const ckpool_t *ckp, sdata_t *ckp_sdata, const int userid) | 
					 | 
					 | 
					 | 
					static sdata_t *select_sdata(const ckpool_t *ckp, sdata_t *ckp_sdata, const int userid) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					{ | 
					 | 
					 | 
					 | 
					{ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						proxy_t *current, *proxy, *tmp, *best = NULL; | 
					 | 
					 | 
					 | 
						proxy_t *global, *proxy, *tmp, *best = NULL; | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (!ckp->proxy || ckp->passthrough) | 
					 | 
					 | 
					 | 
						if (!ckp->proxy || ckp->passthrough) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return ckp_sdata; | 
					 | 
					 | 
					 | 
							return ckp_sdata; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						current = ckp_sdata->proxy; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (!current) { | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							LOGWARNING("No proxy available yet to generate subscribes"); | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return NULL; | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
					 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						/* Proxies are ordered by priority so first available will be the best
 | 
					 | 
					 | 
					 | 
						/* Proxies are ordered by priority so first available will be the best
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						 * priority */ | 
					 | 
					 | 
					 | 
						 * priority */ | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						mutex_lock(&ckp_sdata->proxy_lock); | 
					 | 
					 | 
					 | 
						mutex_lock(&ckp_sdata->proxy_lock); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
						best = global = ckp_sdata->proxy; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						HASH_ITER(hh, ckp_sdata->proxies, proxy, tmp) { | 
					 | 
					 | 
					 | 
						HASH_ITER(hh, ckp_sdata->proxies, proxy, tmp) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (proxy->userid < userid) | 
					 | 
					 | 
					 | 
							if (proxy->userid < userid) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								continue; | 
					 | 
					 | 
					 | 
								continue; | 
				
			
			
		
	
	
		
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
					 | 
					@ -4381,12 +4404,14 @@ static sdata_t *select_sdata(const ckpool_t *ckp, sdata_t *ckp_sdata, const int | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					
 | 
					 | 
					 | 
					 | 
					
 | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (!best) { | 
					 | 
					 | 
					 | 
						if (!best) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (!userid) | 
					 | 
					 | 
					 | 
							if (!userid) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								LOGWARNING("Temporarily insufficient subproxies to accept more clients"); | 
					 | 
					 | 
					 | 
								LOGWARNING("Temporarily insufficient proxies to accept more clients"); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
							else | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
					 | 
								LOGNOTICE("Temporarily insufficient proxies for userid %d to accept more clients", userid); | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							return NULL; | 
					 | 
					 | 
					 | 
							return NULL; | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} | 
					 | 
					 | 
					 | 
						} | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						if (!userid) { | 
					 | 
					 | 
					 | 
						if (!userid) { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (best->id != current->id || current_headroom(ckp_sdata, &proxy) < 2) | 
					 | 
					 | 
					 | 
							if (best->id != global->id || current_headroom(ckp_sdata, &proxy) < 2) | 
				
			
			
				
				
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								generator_recruit(ckp, current->id, 1); | 
					 | 
					 | 
					 | 
								generator_recruit(ckp, global->id, 1); | 
				
			
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
						} else { | 
					 | 
					 | 
					 | 
						} else { | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
							if (proxy_headroom(ckp_sdata, userid) < 2) | 
					 | 
					 | 
					 | 
							if (proxy_headroom(ckp_sdata, userid) < 2) | 
				
			
			
		
	
		
		
			
				
					
					 | 
					 | 
					 | 
								generator_recruit(ckp, best->id, 1); | 
					 | 
					 | 
					 | 
								generator_recruit(ckp, best->id, 1); | 
				
			
			
		
	
	
		
		
			
				
					| 
						
							
								
							
						
						
						
					 | 
					 | 
					
  |