Commit eaf7ed0dcd4004ef9908c4cf968571e7df9c93fb

Con Kolivas 2012-10-01T22:13:20

Detect if a getwork based pool has the X-Stratum header on startup, and if so, switch to the stratum based pool.

diff --git a/cgminer.c b/cgminer.c
index 6426232..894c3cd 100644
--- a/cgminer.c
+++ b/cgminer.c
@@ -4192,6 +4192,9 @@ static bool pool_active(struct pool *pool, bool pinging)
 	CURL *curl;
 	int rolltime;
 
+	applog(LOG_INFO, "Testing pool %s", pool->rpc_url);
+
+retry_stratum:
 	if (pool->has_stratum) {
 		if ((!pool->stratum_active || pinging) && !initiate_stratum(pool))
 			return false;
@@ -4212,12 +4215,25 @@ static bool pool_active(struct pool *pool, bool pinging)
 		return false;
 	}
 
-	applog(LOG_INFO, "Testing pool %s", pool->rpc_url);
 	gettimeofday(&tv_getwork, NULL);
 	val = json_rpc_call(curl, pool->rpc_url, pool->rpc_userpass, rpc_req,
 			true, false, &rolltime, pool, false);
 	gettimeofday(&tv_getwork_reply, NULL);
 
+	/* Detect if a http getwork pool has an X-Stratum header at startup,
+	 * and if so, switch to that in preference to getwork */
+	if (unlikely(!pinging && pool->stratum_url)) {
+		applog(LOG_NOTICE, "Switching pool %d %s to %s", pool->pool_no, pool->rpc_url, pool->stratum_url);
+		pool->has_stratum = true;
+		pool->rpc_url = strdup(pool->stratum_url);
+		extract_sockaddr(pool, pool->stratum_url);
+		initiate_stratum(pool);
+		auth_stratum(pool);
+		curl_easy_cleanup(curl);
+
+		goto  retry_stratum;
+	}
+
 	if (val) {
 		struct work *work = make_work();
 		bool rc;
diff --git a/util.c b/util.c
index 6b08338..b81af61 100644
--- a/util.c
+++ b/util.c
@@ -54,6 +54,7 @@ struct header_info {
 	char		*lp_path;
 	int		rolltime;
 	char		*reason;
+	char		*stratum_url;
 	bool		hadrolltime;
 	bool		canroll;
 	bool		hadexpire;
@@ -183,6 +184,11 @@ static size_t resp_hdr_cb(void *ptr, size_t size, size_t nmemb, void *user_data)
 		val = NULL;
 	}
 
+	if (!strcasecmp("X-Stratum", key)) {
+		hi->stratum_url = val;
+		val = NULL;
+	}
+
 out:
 	free(key);
 	free(val);
@@ -261,7 +267,7 @@ json_t *json_rpc_call(CURL *curl, const char *url,
 {
 	long timeout = longpoll ? (60 * 60) : 60;
 	struct data_buffer all_data = {NULL, 0};
-	struct header_info hi = {NULL, 0, NULL, false, false, false};
+	struct header_info hi = {NULL, 0, NULL, NULL, false, false, false};
 	char len_hdr[64], user_agent_hdr[128];
 	char curl_err_str[CURL_ERROR_SIZE];
 	struct curl_slist *headers = NULL;
@@ -388,9 +394,19 @@ json_t *json_rpc_call(CURL *curl, const char *url,
 			pool->hdr_path = hi.lp_path;
 		} else
 			pool->hdr_path = NULL;
-	} else if (hi.lp_path) {
-		free(hi.lp_path);
-		hi.lp_path = NULL;
+		if (hi.stratum_url) {
+			pool->stratum_url = hi.stratum_url;
+			hi.stratum_url = NULL;
+		}
+	} else {
+		if (hi.lp_path) {
+			free(hi.lp_path);
+			hi.lp_path = NULL;
+		}
+		if (hi.stratum_url) {
+			free(hi.stratum_url);
+			hi.stratum_url = NULL;
+		}
 	}
 
 	*rolltime = hi.rolltime;