Browse Source

Merge branch 'httpsrv' into bfgminer

Luke Dashjr 12 years ago
parent
commit
3cc0c89b10
3 changed files with 57 additions and 20 deletions
  1. 49 20
      driver-getwork.c
  2. 5 0
      httpsrv.c
  3. 3 0
      httpsrv.h

+ 49 - 20
driver-getwork.c

@@ -19,6 +19,7 @@
 #include <uthash.h>
 #include <uthash.h>
 
 
 #include "deviceapi.h"
 #include "deviceapi.h"
+#include "httpsrv.h"
 #include "miner.h"
 #include "miner.h"
 
 
 struct device_drv getwork_drv;
 struct device_drv getwork_drv;
@@ -37,8 +38,6 @@ struct getwork_client *getwork_clients;
 static
 static
 pthread_mutex_t getwork_clients_mutex;
 pthread_mutex_t getwork_clients_mutex;
 
 
-// TODO: X-Hashes-Done?
-
 static
 static
 void prune_worklog()
 void prune_worklog()
 {
 {
@@ -91,13 +90,28 @@ void getwork_first_client()
 }
 }
 
 
 static
 static
-int getwork_error(struct MHD_Connection *conn, int16_t errcode, const char *errmsg, const char *idstr, size_t idstr_sz)
+void getwork_prepare_resp(struct MHD_Response *resp)
+{
+	httpsrv_prepare_resp(resp);
+	MHD_add_response_header(resp, MHD_HTTP_HEADER_CONTENT_TYPE, "application/json");
+	MHD_add_response_header(resp, "X-Mining-Extensions", "hashesdone");
+}
+
+static
+struct MHD_Response *getwork_gen_error(int16_t errcode, const char *errmsg, const char *idstr, size_t idstr_sz)
 {
 {
 	size_t replysz = 0x40 + strlen(errmsg) + idstr_sz;
 	size_t replysz = 0x40 + strlen(errmsg) + idstr_sz;
 	char * const reply = malloc(replysz);
 	char * const reply = malloc(replysz);
 	replysz = snprintf(reply, replysz, "{\"result\":null,\"error\":{\"code\":%d,\"message\":\"%s\"},\"id\":%s}", errcode, errmsg, idstr ?: "0");
 	replysz = snprintf(reply, replysz, "{\"result\":null,\"error\":{\"code\":%d,\"message\":\"%s\"},\"id\":%s}", errcode, errmsg, idstr ?: "0");
 	struct MHD_Response * const resp = MHD_create_response_from_buffer(replysz, reply, MHD_RESPMEM_MUST_FREE);
 	struct MHD_Response * const resp = MHD_create_response_from_buffer(replysz, reply, MHD_RESPMEM_MUST_FREE);
-	MHD_add_response_header(resp, MHD_HTTP_HEADER_CONTENT_TYPE, "application/json");
+	getwork_prepare_resp(resp);
+	return resp;
+}
+
+static
+int getwork_error(struct MHD_Connection *conn, int16_t errcode, const char *errmsg, const char *idstr, size_t idstr_sz)
+{
+	struct MHD_Response * const resp = getwork_gen_error(errcode, errmsg, idstr, idstr_sz);
 	const int ret = MHD_queue_response(conn, 500, resp);
 	const int ret = MHD_queue_response(conn, 500, resp);
 	MHD_destroy_response(resp);
 	MHD_destroy_response(resp);
 	return ret;
 	return ret;
@@ -116,6 +130,7 @@ int handle_getwork(struct MHD_Connection *conn, bytes_t *upbuf)
 	json_error_t jerr;
 	json_error_t jerr;
 	struct work *work;
 	struct work *work;
 	char *reply;
 	char *reply;
+	const char *hashesdone = NULL;
 	int ret;
 	int ret;
 	
 	
 	if (unlikely(!_init))
 	if (unlikely(!_init))
@@ -124,14 +139,6 @@ int handle_getwork(struct MHD_Connection *conn, bytes_t *upbuf)
 		getwork_init();
 		getwork_init();
 	}
 	}
 	
 	
-	user = MHD_basic_auth_get_username_password(conn, NULL);
-	if (!user)
-	{
-		static const char fail[] = "Please provide a username\n";
-		resp = MHD_create_response_from_buffer(sizeof(fail)-1, (char*)fail, MHD_RESPMEM_PERSISTENT);
-		return MHD_queue_basic_auth_fail_response(conn, PACKAGE, resp);
-	}
-	
 	if (bytes_len(upbuf))
 	if (bytes_len(upbuf))
 	{
 	{
 		bytes_nullterminate(upbuf);
 		bytes_nullterminate(upbuf);
@@ -156,6 +163,14 @@ int handle_getwork(struct MHD_Connection *conn, bytes_t *upbuf)
 		submit = j2 ? __json_array_string(j2, 0) : NULL;
 		submit = j2 ? __json_array_string(j2, 0) : NULL;
 	}
 	}
 	
 	
+	user = MHD_basic_auth_get_username_password(conn, NULL);
+	if (!user)
+	{
+		resp = getwork_gen_error(-4096, "Please provide a username", idstr, idstr_sz);
+		ret = MHD_queue_basic_auth_fail_response(conn, PACKAGE, resp);
+		goto out;
+	}
+	
 	mutex_lock(&getwork_clients_mutex);
 	mutex_lock(&getwork_clients_mutex);
 	HASH_FIND_STR(getwork_clients, user, client);
 	HASH_FIND_STR(getwork_clients, user, client);
 	if (!client)
 	if (!client)
@@ -196,12 +211,13 @@ int handle_getwork(struct MHD_Connection *conn, bytes_t *upbuf)
 	user = NULL;
 	user = NULL;
 	thr = cgpu->thr[0];
 	thr = cgpu->thr[0];
 	
 	
+	hashesdone = MHD_lookup_connection_value(conn, MHD_HEADER_KIND, "X-Hashes-Done");
+	
 	if (submit)
 	if (submit)
 	{
 	{
 		unsigned char hdr[80];
 		unsigned char hdr[80];
 		const char *rejreason;
 		const char *rejreason;
 		uint32_t nonce;
 		uint32_t nonce;
-		struct timeval tv_now, tv_delta;
 		
 		
 		// NOTE: expecting hex2bin to fail since we only parse 80 of the 128
 		// NOTE: expecting hex2bin to fail since we only parse 80 of the 128
 		hex2bin(hdr, submit, 80);
 		hex2bin(hdr, submit, 80);
@@ -222,10 +238,8 @@ int handle_getwork(struct MHD_Connection *conn, bytes_t *upbuf)
 			else
 			else
 				rejreason = NULL;
 				rejreason = NULL;
 			
 			
-			timer_set_now(&tv_now);
-			timersub(&tv_now, &client->tv_hashes_done, &tv_delta);
-			client->tv_hashes_done = tv_now;
-			hashes_done(thr, 0x100000000, &tv_delta, NULL);
+			if (!hashesdone)
+				hashesdone = "0x100000000";
 		}
 		}
 		
 		
 		reply = malloc(36 + idstr_sz);
 		reply = malloc(36 + idstr_sz);
@@ -233,7 +247,8 @@ int handle_getwork(struct MHD_Connection *conn, bytes_t *upbuf)
 		sprintf(reply, "{\"error\":null,\"result\":%s,\"id\":%s}",
 		sprintf(reply, "{\"error\":null,\"result\":%s,\"id\":%s}",
 		        rejreason ? "false" : "true", idstr);
 		        rejreason ? "false" : "true", idstr);
 		resp = MHD_create_response_from_buffer(replysz, reply, MHD_RESPMEM_MUST_FREE);
 		resp = MHD_create_response_from_buffer(replysz, reply, MHD_RESPMEM_MUST_FREE);
-		MHD_add_response_header(resp, MHD_HTTP_HEADER_CONTENT_TYPE, "application/json");
+		getwork_prepare_resp(resp);
+		MHD_add_response_header(resp, "X-Mining-Identifier", cgpu->proc_repr);
 		if (rejreason)
 		if (rejreason)
 			MHD_add_response_header(resp, "X-Reject-Reason", rejreason);
 			MHD_add_response_header(resp, "X-Reject-Reason", rejreason);
 		ret = MHD_queue_response(conn, 200, resp);
 		ret = MHD_queue_response(conn, 200, resp);
@@ -243,7 +258,10 @@ int handle_getwork(struct MHD_Connection *conn, bytes_t *upbuf)
 	
 	
 	if (cgpu->deven == DEV_DISABLED)
 	if (cgpu->deven == DEV_DISABLED)
 	{
 	{
-		ret = getwork_error(conn, -10, "Virtual device has been disabled", idstr, idstr_sz);
+		resp = getwork_gen_error(-10, "Virtual device has been disabled", idstr, idstr_sz);
+		MHD_add_response_header(resp, "X-Mining-Identifier", cgpu->proc_repr);
+		ret = MHD_queue_response(conn, 500, resp);
+		MHD_destroy_response(resp);
 		goto out;
 		goto out;
 	}
 	}
 	
 	
@@ -264,12 +282,23 @@ int handle_getwork(struct MHD_Connection *conn, bytes_t *upbuf)
 		HASH_ADD_KEYPTR(hh, client->work, work->data, 76, work);
 		HASH_ADD_KEYPTR(hh, client->work, work->data, 76, work);
 		
 		
 		resp = MHD_create_response_from_buffer(replysz, reply, MHD_RESPMEM_MUST_FREE);
 		resp = MHD_create_response_from_buffer(replysz, reply, MHD_RESPMEM_MUST_FREE);
-		MHD_add_response_header(resp, MHD_HTTP_HEADER_CONTENT_TYPE, "application/json");
+		getwork_prepare_resp(resp);
+		MHD_add_response_header(resp, "X-Mining-Identifier", cgpu->proc_repr);
 		ret = MHD_queue_response(conn, 200, resp);
 		ret = MHD_queue_response(conn, 200, resp);
 		MHD_destroy_response(resp);
 		MHD_destroy_response(resp);
 	}
 	}
 	
 	
 out:
 out:
+	if (hashesdone)
+	{
+		struct timeval tv_now, tv_delta;
+		long long lld = strtoll(hashesdone, NULL, 0);
+		timer_set_now(&tv_now);
+		timersub(&tv_now, &client->tv_hashes_done, &tv_delta);
+		client->tv_hashes_done = tv_now;
+		hashes_done(thr, lld, &tv_delta, NULL);
+	}
+	
 	free(user);
 	free(user);
 	free(idstr);
 	free(idstr);
 	if (json)
 	if (json)

+ 5 - 0
httpsrv.c

@@ -21,6 +21,11 @@ static struct MHD_Daemon *httpsrv;
 
 
 extern int handle_getwork(struct MHD_Connection *, bytes_t *);
 extern int handle_getwork(struct MHD_Connection *, bytes_t *);
 
 
+void httpsrv_prepare_resp(struct MHD_Response *resp)
+{
+	MHD_add_response_header(resp, MHD_HTTP_HEADER_SERVER, PACKAGE"/"VERSION" getwork server");
+}
+
 static
 static
 int httpsrv_handle_req(struct MHD_Connection *conn, const char *url, const char *method, bytes_t *upbuf)
 int httpsrv_handle_req(struct MHD_Connection *conn, const char *url, const char *method, bytes_t *upbuf)
 {
 {

+ 3 - 0
httpsrv.h

@@ -1,7 +1,10 @@
 #ifndef _BFG_HTTPSRV_H
 #ifndef _BFG_HTTPSRV_H
 #define _BFG_HTTPSRV_H
 #define _BFG_HTTPSRV_H
 
 
+#include <microhttpd.h>
+
 extern void httpsrv_start(unsigned short port);
 extern void httpsrv_start(unsigned short port);
+extern void httpsrv_prepare_resp(struct MHD_Response *);
 extern void httpsrv_stop();
 extern void httpsrv_stop();
 
 
 #endif
 #endif