From 72b1206e4f2d6c60a2ccf4bd75e1744ef038d057 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 5 Sep 2014 10:29:38 +1000 Subject: [PATCH 1/2] There should always be a client instance by the time we are parsing a method message --- src/stratifier.c | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/src/stratifier.c b/src/stratifier.c index f31d4949..3dc1c4a7 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -2094,18 +2094,10 @@ static void send_json_err(int64_t client_id, json_t *id_val, const char *err_msg stratum_add_send(val, client_id); } -static void update_client(const int64_t client_id) +static void update_client(stratum_instance_t *client, const int64_t client_id) { - stratum_instance_t *client; - stratum_send_update(client_id, true); - - ck_rlock(&instance_lock); - client = __instance_by_id(client_id); - ck_runlock(&instance_lock); - - if (likely(client)) - stratum_send_diff(client); + stratum_send_diff(client); } static json_params_t *create_json_params(const int64_t client_id, const json_t *params, const json_t *id_val, const char *address) @@ -2126,6 +2118,15 @@ static void parse_method(const int64_t client_id, json_t *id_val, json_t *method const char *method; char buf[256]; + ck_rlock(&instance_lock); + client = __instance_by_id(client_id); + ck_runlock(&instance_lock); + + if (unlikely(!client)) { + LOGINFO("Failed to find client id %d in hashtable!", client_id); + return; + } + /* Random broken clients send something not an integer as the id so we copy * the json item for id_val as is for the response. */ method = json_string_value(method_val); @@ -2139,16 +2140,7 @@ static void parse_method(const int64_t client_id, json_t *id_val, json_t *method json_object_set_nocheck(val, "id", id_val); json_object_set_new_nocheck(val, "error", json_null()); stratum_add_send(val, client_id); - update_client(client_id); - return; - } - - ck_rlock(&instance_lock); - client = __instance_by_id(client_id); - ck_runlock(&instance_lock); - - if (unlikely(!client)) { - LOGINFO("Failed to find client id %d in hashtable!", client_id); + update_client(client, client_id); return; } From dbc64715f6aa1e5ba16ead7ae176c74af37731d5 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 5 Sep 2014 11:09:38 +1000 Subject: [PATCH 2/2] Drop and invalidate clients that fail to subscribe or authorise --- src/stratifier.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/stratifier.c b/src/stratifier.c index 3dc1c4a7..bbced5c1 100644 --- a/src/stratifier.c +++ b/src/stratifier.c @@ -232,6 +232,7 @@ struct stratum_instance { char address[INET6_ADDRSTRLEN]; bool authorised; + bool invalid; bool idle; bool notified_idle; @@ -2133,17 +2134,28 @@ static void parse_method(const int64_t client_id, json_t *id_val, json_t *method if (cmdmatch(method, "mining.subscribe")) { json_t *val, *result_val = parse_subscribe(client_id, params_val); - if (!result_val) + if (unlikely(!result_val)) return; val = json_object(); json_object_set_new_nocheck(val, "result", result_val); json_object_set_nocheck(val, "id", id_val); json_object_set_new_nocheck(val, "error", json_null()); stratum_add_send(val, client_id); + if (unlikely(!json_is_true(result_val))) { + client->invalid = true; + return; + } update_client(client, client_id); return; } + if (unlikely(client->invalid)) { + LOGINFO("Dropping invalidated client %d", client->id); + snprintf(buf, 255, "dropclient=%ld", client->id); + send_proc(client->ckp->connector, buf); + drop_client(client->id); + } + if (unlikely(cmdmatch(method, "mining.passthrough"))) { /* We need to inform the connector process that this client * is a passthrough and to manage its messages accordingly. @@ -2168,13 +2180,14 @@ static void parse_method(const int64_t client_id, json_t *id_val, json_t *method } /* We should only accept authorised requests from here on */ - if (!client->authorised) { + if (unlikely(!client->authorised)) { /* Dropping unauthorised clients here also allows the * stratifier process to restart since it will have lost all * the stratum instance data. Clients will just reconnect. */ LOGINFO("Dropping unauthorised client %d", client->id); snprintf(buf, 255, "dropclient=%ld", client->id); send_proc(client->ckp->connector, buf); + drop_client(client->id); return; }