Introduce a --net-delay option which guarantees at least 250ms between any networking requests to not overload slow routers.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
diff --git a/README b/README
index 12386bb..8c1c519 100644
--- a/README
+++ b/README
@@ -131,6 +131,7 @@ Options for both config file and command line:
--load-balance Change multipool strategy from failover to even load balance
--log|-l <arg> Interval in seconds between log output (default: 5)
--monitor|-m <arg> Use custom pipe cmd for output messages
+--net-delay Impose small delays in networking to not overload slow routers
--no-longpoll Disable X-Long-Polling support
--pass|-p <arg> Password for bitcoin JSON-RPC server
--per-device-stats Force verbose mode and output per-device statistics
diff --git a/main.c b/main.c
index 585d21f..69d69e1 100644
--- a/main.c
+++ b/main.c
@@ -239,6 +239,7 @@ char *opt_api_description = PACKAGE_STRING;
int opt_api_port = 4028;
bool opt_api_listen = false;
bool opt_api_network = false;
+bool opt_delaynet = false;
char *opt_kernel_path;
char *cgminer_path;
@@ -262,6 +263,8 @@ static pthread_mutex_t qd_lock;
static pthread_mutex_t *stgd_lock;
static pthread_mutex_t curses_lock;
static pthread_rwlock_t blk_lock;
+pthread_rwlock_t netacc_lock;
+
double total_mhashes_done;
static struct timeval total_tv_start, total_tv_end;
@@ -1631,6 +1634,9 @@ static struct opt_table opt_config_table[] = {
opt_set_charp, NULL, &opt_stderr_cmd,
"Use custom pipe cmd for output messages"),
#endif // defined(unix)
+ OPT_WITHOUT_ARG("--net-delay",
+ opt_set_bool, &opt_delaynet,
+ "Impose small delays in networking to not overload slow routers"),
#ifdef HAVE_ADL
OPT_WITHOUT_ARG("--no-adl",
opt_set_bool, &opt_noadl,
@@ -5875,6 +5881,7 @@ int main (int argc, char *argv[])
mutex_init(&curses_lock);
mutex_init(&control_lock);
rwlock_init(&blk_lock);
+ rwlock_init(&netacc_lock);
sprintf(packagename, "%s %s", PACKAGE, VERSION);
diff --git a/miner.h b/miner.h
index a21de5f..9743fd6 100644
--- a/miner.h
+++ b/miner.h
@@ -415,6 +415,9 @@ extern char *opt_api_description;
extern int opt_api_port;
extern bool opt_api_listen;
extern bool opt_api_network;
+extern bool opt_delaynet;
+
+extern pthread_rwlock_t netacc_lock;
extern const uint32_t sha256_init_state[];
extern json_t *json_rpc_call(CURL *curl, const char *url, const char *userpass,
diff --git a/util.c b/util.c
index 48bcf5e..2314339 100644
--- a/util.c
+++ b/util.c
@@ -42,6 +42,7 @@
#endif
bool successful_connect = false;
+struct timeval nettime;
struct data_buffer {
void *buf;
@@ -286,6 +287,21 @@ int json_rpc_call_sockopt_cb(void *userdata, curl_socket_t fd, curlsocktype purp
}
#endif
+static void last_nettime(struct timeval *last)
+{
+ rd_lock(&netacc_lock);
+ last->tv_sec = nettime.tv_sec;
+ last->tv_usec = nettime.tv_usec;
+ rd_unlock(&netacc_lock);
+}
+
+static void set_nettime(void)
+{
+ wr_lock(&netacc_lock);
+ gettimeofday(&nettime, NULL);
+ wr_unlock(&netacc_lock);
+}
+
json_t *json_rpc_call(CURL *curl, const char *url,
const char *userpass, const char *rpc_req,
bool probe, bool longpoll, bool *rolltime,
@@ -358,6 +374,25 @@ json_t *json_rpc_call(CURL *curl, const char *url,
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
+ if (opt_delaynet) {
+ long long now_msecs, last_msecs;
+ struct timeval now, last;
+
+ gettimeofday(&now, NULL);
+ last_nettime(&last);
+ now_msecs = (long long)now.tv_sec * 1000;
+ now_msecs += now.tv_usec / 1000;
+ last_msecs = (long long)last.tv_sec * 1000;
+ last_msecs += last.tv_usec / 1000;
+ if (now_msecs > last_msecs && now_msecs - last_msecs < 250) {
+ struct timespec rgtp;
+
+ rgtp.tv_sec = 0;
+ rgtp.tv_nsec = (250 - (now_msecs - last_msecs)) * 1000000;
+ nanosleep(&rgtp, NULL);
+ }
+ set_nettime();
+ }
rc = curl_easy_perform(curl);
if (rc) {
applog(LOG_INFO, "HTTP request failed: %s", curl_err_str);