Browse Source

Create new proxy entries on the fly with the client reconnect command and switch to it

master
Con Kolivas 11 years ago
parent
commit
bfec616da3
  1. 1
      src/ckpool.h
  2. 87
      src/generator.c
  3. 1
      src/stratifier.c

1
src/ckpool.h

@ -97,6 +97,7 @@ struct ckpool_instance {
server_instance_t **servers; server_instance_t **servers;
char *serverurl; // URL to bind our server/proxy to char *serverurl; // URL to bind our server/proxy to
int update_interval; // Seconds between stratum updates int update_interval; // Seconds between stratum updates
int chosen_server; // Chosen server for next connection
/* Proxy options */ /* Proxy options */
int proxies; int proxies;

87
src/generator.c

@ -82,6 +82,7 @@ struct proxy_instance {
bool notified; /* Received new template for work */ bool notified; /* Received new template for work */
bool diffed; /* Received new diff */ bool diffed; /* Received new diff */
bool reconnect; /* We need to drop and reconnect */
pthread_mutex_t notify_lock; pthread_mutex_t notify_lock;
notify_instance_t *notify_instances; notify_instance_t *notify_instances;
@ -516,8 +517,6 @@ out:
return ret; return ret;
} }
#define parse_reconnect(a, b) true
static bool parse_notify(proxy_instance_t *proxi, json_t *val) static bool parse_notify(proxy_instance_t *proxi, json_t *val)
{ {
const char *prev_hash, *bbversion, *nbit, *ntime; const char *prev_hash, *bbversion, *nbit, *ntime;
@ -626,6 +625,66 @@ static bool show_message(json_t *val)
return true; return true;
} }
static bool parse_reconnect(proxy_instance_t *proxi, json_t *val)
{
server_instance_t *newsi, *si = proxi->si;
ckpool_t *ckp = proxi->ckp;
const char *new_url;
bool ret = false;
int new_port;
char *url;
new_url = json_string_value(json_array_get(val, 0));
new_port = json_integer_value(json_array_get(val, 1));
if (new_url && strlen(new_url) && new_port) {
char *dot_pool, *dot_reconnect;
int len;
dot_pool = strchr(si->url, '.');
if (!dot_pool) {
LOGWARNING("Denied stratum reconnect request from server without domain %s",
si->url);
goto out;
}
dot_reconnect = strchr(new_url, '.');
if (!dot_reconnect) {
LOGWARNING("Denied stratum reconnect request to url without domain %s",
new_url);
goto out;
}
len = strlen(dot_reconnect);
if (strncmp(dot_pool, dot_reconnect, len)) {
LOGWARNING("Denied stratum reconnect request from %s to non-matching domain %s",
si->url, new_url);
goto out;
}
asprintf(&url, "%s:%d", new_url, new_port);
} else
url = strdup(si->url);
LOGINFO("Processing reconnect request to %s", url);
ret = true;
newsi = ckzalloc(sizeof(server_instance_t));
newsi->id = ckp->proxies++;
ckp->servers = realloc(ckp->servers, sizeof(server_instance_t *) * ckp->proxies);
ckp->servers[newsi->id] = newsi;
ckp->chosen_server = newsi->id;
newsi->url = url;
newsi->auth = strdup(si->auth);
newsi->pass = strdup(si->pass);
proxi->reconnect = true;
proxi = ckzalloc(sizeof(proxy_instance_t));
newsi->data = proxi;
proxi->auth = newsi->auth;
proxi->pass = newsi->pass;
proxi->si = newsi;
proxi->ckp = ckp;
proxi->cs = &newsi->cs;
out:
return ret;
}
static bool parse_method(proxy_instance_t *proxi, const char *msg) static bool parse_method(proxy_instance_t *proxi, const char *msg)
{ {
json_t *val = NULL, *method, *err_val, *params; json_t *val = NULL, *method, *err_val, *params;
@ -950,6 +1009,12 @@ static void *proxy_recv(void *arg)
send_proc(ckp->stratifier, "diff"); send_proc(ckp->stratifier, "diff");
proxi->diffed = false; proxi->diffed = false;
} }
if (proxi->reconnect) {
proxi->reconnect = false;
LOGWARNING("Reconnect issue, dropping existing connection");
send_proc(ckp->generator, "reconnect");
break;
}
continue; continue;
} }
if (parse_share(proxi, cs->buf)) { if (parse_share(proxi, cs->buf)) {
@ -1029,7 +1094,7 @@ static proxy_instance_t *live_proxy(ckpool_t *ckp)
LOGDEBUG("Attempting to connect to proxy"); LOGDEBUG("Attempting to connect to proxy");
retry: retry:
for (i = 0; i < ckp->proxies; i++) { for (i = ckp->chosen_server; i < ckp->proxies; i++) {
proxy_instance_t *proxi; proxy_instance_t *proxi;
server_instance_t *si; server_instance_t *si;
@ -1060,10 +1125,13 @@ retry:
break; break;
} }
if (!alive) { if (!alive) {
if (!ckp->chosen_server) {
LOGWARNING("Failed to connect to any servers as proxy, retrying in 5s!"); LOGWARNING("Failed to connect to any servers as proxy, retrying in 5s!");
sleep(5); sleep(5);
}
goto retry; goto retry;
} }
ckp->chosen_server = 0;
cs = alive->cs; cs = alive->cs;
LOGNOTICE("Connected to upstream server %s:%s as proxy", cs->url, cs->port); LOGNOTICE("Connected to upstream server %s:%s as proxy", cs->url, cs->port);
mutex_init(&alive->notify_lock); mutex_init(&alive->notify_lock);
@ -1199,9 +1267,10 @@ static int proxy_mode(ckpool_t *ckp, proc_instance_t *pi)
for (i = 0; i < ckp->proxies; i++) { for (i = 0; i < ckp->proxies; i++) {
ckp->servers[i] = ckzalloc(sizeof(server_instance_t)); ckp->servers[i] = ckzalloc(sizeof(server_instance_t));
si = ckp->servers[i]; si = ckp->servers[i];
si->url = ckp->proxyurl[i]; si->id = i;
si->auth = ckp->proxyauth[i]; si->url = strdup(ckp->proxyurl[i]);
si->pass = ckp->proxypass[i]; si->auth = strdup(ckp->proxyauth[i]);
si->pass = strdup(ckp->proxypass[i]);
proxi = ckzalloc(sizeof(proxy_instance_t)); proxi = ckzalloc(sizeof(proxy_instance_t));
si->data = proxi; si->data = proxi;
proxi->auth = si->auth; proxi->auth = si->auth;
@ -1213,13 +1282,17 @@ static int proxy_mode(ckpool_t *ckp, proc_instance_t *pi)
ret = proxy_loop(pi); ret = proxy_loop(pi);
for (i = 0; i < ckp->proxies; si = ckp->servers[i], i++) { for (i = 0; i < ckp->proxies; i++) {
si = ckp->servers[i];
close(si->cs.fd); close(si->cs.fd);
proxi = si->data; proxi = si->data;
free(proxi->enonce1); free(proxi->enonce1);
free(proxi->enonce1bin); free(proxi->enonce1bin);
free(proxi->sessionid); free(proxi->sessionid);
dealloc(si->data); dealloc(si->data);
dealloc(si->url);
dealloc(si->auth);
dealloc(si->pass);
dealloc(si); dealloc(si);
} }
dealloc(ckp->servers); dealloc(ckp->servers);

1
src/stratifier.c

@ -872,6 +872,7 @@ static int stratum_loop(ckpool_t *ckp, proc_instance_t *pi)
to = &timeout; to = &timeout;
reset: reset:
timeout.tv_sec = ckp->update_interval; timeout.tv_sec = ckp->update_interval;
timeout.tv_usec = 0;
retry: retry:
FD_ZERO(&readfds); FD_ZERO(&readfds);
FD_SET(us->sockd, &readfds); FD_SET(us->sockd, &readfds);

Loading…
Cancel
Save