Loading src/main-conf.c +1 −1 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ Read in the configuration for MASSCAN. Configuration parameters can be read either from the command-line or a configuration file. or a configuration file. Parameters have the same name in both. */ #include "masscan.h" #include "ranges.h" Loading src/main-status.c +27 −8 Original line number Diff line number Diff line /* for printing the status to the command-line roughly once per second the complication is that we cann't afford a "time" check for each packet, since it's a system call, so we try to keep a rough approximation of when to print a status. */ #include "main-status.h" #include "port-timer.h" #include <stdio.h> #include <string.h> /*************************************************************************** Loading @@ -11,8 +21,7 @@ void status_print(struct Status *status, uint64_t count, uint64_t max_count) { double elapsed; clock_t now; unsigned i; uint64_t now; /* speed up or slow down how often we report so that we get about * 1-second between reports */ Loading @@ -28,16 +37,25 @@ status_print(struct Status *status, uint64_t count, uint64_t max_count) status->last.time = t; } now = clock(); elapsed = ((double)now - (double)status->last.clock)/(double)CLOCKS_PER_SEC; if (count <= status->last.count) return; now = port_gettime(); elapsed = ((double)now - (double)status->last.clock)/(double)1000000.0; if (elapsed == 0) return; status->last.clock = now; status->charcount = printf("rate = %5.3f-kilaprobes/sec %5.3f%% done \n", status->charcount = printf("rate = %5.3f-kilaprobes/sec %5.3f%% done \r", ((double)(count - status->last.count)*1.0/elapsed)/1000.0, (double)(count*100.0/max_count)); (double)(count*100.0/max_count) ); fflush(stdout); status->last.count = count; for (i=0; i<status->charcount; i++) /*for (i=0; i<status->charcount; i++) putc('\b', stdout); printf("x\b");*/ } /*************************************************************************** Loading @@ -59,8 +77,9 @@ status_finish(struct Status *status) void status_start(struct Status *status) { memset(status, 0, sizeof(*status)); status->last.clock = clock(); status->last.time = time(0); status->last.count = 0; status->timer = 0x7f; status->timer = 0x1; } src/main-status.h +1 −1 Original line number Diff line number Diff line Loading @@ -6,7 +6,7 @@ struct Status { struct { clock_t clock; uint64_t clock; time_t time; uint64_t count; } last; Loading src/main-throttle.c +74 −67 Original line number Diff line number Diff line /* rate calculations for the packets Since we are sending packet at a rate of 10-million-per-second, we the calculations need to be done in a light-weight manner. For one thing, we can't do a system-call per packet. NOTE: one complication to watch for is the difference between clock time and elapsed time, and that they change. We have to avoid a problem where somebody suspends the computer for a few days, then wake it up, at which point the system tries sending a million packets/secon instead of the desired thousand packets/second. */ #include "main-throttle.h" #include "port-timer.h" #include "logger.h" Loading @@ -9,83 +23,76 @@ ***************************************************************************/ void throttler_start(struct Throttler *throttler, double max_rate) { throttler->current_rate = 0.0; unsigned i; memset(throttler, 0, sizeof(*throttler)); throttler->max_rate = max_rate; throttler->last_timestamp = port_gettime(); throttler->last_count = 0; throttler->max_batch = 1.0; for (i=0; i<sizeof(throttler->buckets)/sizeof(throttler->buckets[0]); i++) { throttler->buckets[i].timestamp = port_gettime(); throttler->buckets[i].packet_count = 0; } throttler->batch_size = 1; LOG(1, "maxrate = %0.2f\n", throttler->max_rate); } /*************************************************************************** * We return the number of packets that can be sent in a batch. Thus, * instead of trying to throttle each packet individually, which has a * high per-packet cost, we try to throttle a bunch at a time. Normally, * this function will return 1, only at high rates does it return larger * numbers. * * NOTE: The minimum value this returns is 1. When it's less than that, * it'll pause and wait until it's ready to send a packet. ***************************************************************************/ uint64_t throttler_next_batch(struct Throttler *throttler, uint64_t count) throttler_next_batch(struct Throttler *throttler, uint64_t packet_count) { uint64_t timestamp = port_gettime(); double elapsed = ((double)(timestamp - throttler->last_timestamp))/1000000.0; double packets_sent = (double)(count - throttler->last_count); double new_rate; if (packets_sent < 1.01) return (uint64_t)throttler->max_batch; /* BOUNDARY CASE: if the elapsed time is zero, or very small, we * get confused. Therefore, handle this case specially */ if (elapsed < 0.00001) { throttler->max_batch *= 1.4; if (throttler->max_batch > 1000.0) throttler->max_batch = 1000.0; return (uint64_t)throttler->max_batch; } uint64_t timestamp; uint64_t index; uint64_t old_timestamp; uint64_t old_packet_count; double current_rate; double max_rate = throttler->max_rate; throttler->last_timestamp = timestamp; throttler->last_count = count; again: timestamp = port_gettime(); new_rate = 0.9 * throttler->current_rate + 0.1 * (packets_sent/elapsed); index = (throttler->index) & 0xFF; throttler->buckets[index].timestamp = timestamp; throttler->buckets[index].packet_count = packet_count; index = (++throttler->index) & 0xFF; old_timestamp = throttler->buckets[index].timestamp; old_packet_count = throttler->buckets[index].packet_count; if (new_rate > 10000000.0) printf("."); throttler->current_rate = new_rate; current_rate = 1.0*(packet_count - old_packet_count)/((timestamp - old_timestamp)/1000000.0); { double overrate = throttler->current_rate - throttler->max_rate; double overpackets = elapsed * overrate; if (current_rate > max_rate) { double waittime; if (throttler->current_rate > throttler->max_rate) { double waittime = overpackets / throttler->max_rate; unsigned x; uint64_t x1, x2; /* calculate waittime, in seconds */ waittime = (current_rate - max_rate) / throttler->max_rate; /* going to fast, so slow down */ throttler->max_batch *= 0.99; if (throttler->max_batch < 1.0) throttler->max_batch = 1.0; if (waittime > 0.1) waittime = 0.1; if (waittime > 0.2) { waittime = 0.01; } port_usleep((uint64_t)(waittime * 1000000.0)); /* wait a bit */ x = (unsigned)(waittime * 1000000.0); x1 = port_gettime(); port_usleep(x); x2 = port_gettime(); x1 = x2 - x1; //printf("%f \n", throttler->max_batch); } else { /* going to slow, so increase the speed */ throttler->max_batch *= 1.01; if (throttler->max_batch > 1000.0) throttler->max_batch = 1000.0; } throttler->batch_size *= 0.999; goto again; } return (uint64_t)throttler->max_batch; throttler->batch_size *= 1.005; if (throttler->batch_size > 10000) throttler->batch_size = 10000; throttler->current_rate = current_rate; return (uint64_t)throttler->batch_size; } src/main-throttle.h +8 −3 Original line number Diff line number Diff line Loading @@ -6,9 +6,14 @@ struct Throttler { double max_rate; double current_rate; double max_batch; uint64_t last_count; uint64_t last_timestamp; double batch_size; unsigned index; struct { uint64_t timestamp; uint64_t packet_count; } buckets[256]; }; Loading Loading
src/main-conf.c +1 −1 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ Read in the configuration for MASSCAN. Configuration parameters can be read either from the command-line or a configuration file. or a configuration file. Parameters have the same name in both. */ #include "masscan.h" #include "ranges.h" Loading
src/main-status.c +27 −8 Original line number Diff line number Diff line /* for printing the status to the command-line roughly once per second the complication is that we cann't afford a "time" check for each packet, since it's a system call, so we try to keep a rough approximation of when to print a status. */ #include "main-status.h" #include "port-timer.h" #include <stdio.h> #include <string.h> /*************************************************************************** Loading @@ -11,8 +21,7 @@ void status_print(struct Status *status, uint64_t count, uint64_t max_count) { double elapsed; clock_t now; unsigned i; uint64_t now; /* speed up or slow down how often we report so that we get about * 1-second between reports */ Loading @@ -28,16 +37,25 @@ status_print(struct Status *status, uint64_t count, uint64_t max_count) status->last.time = t; } now = clock(); elapsed = ((double)now - (double)status->last.clock)/(double)CLOCKS_PER_SEC; if (count <= status->last.count) return; now = port_gettime(); elapsed = ((double)now - (double)status->last.clock)/(double)1000000.0; if (elapsed == 0) return; status->last.clock = now; status->charcount = printf("rate = %5.3f-kilaprobes/sec %5.3f%% done \n", status->charcount = printf("rate = %5.3f-kilaprobes/sec %5.3f%% done \r", ((double)(count - status->last.count)*1.0/elapsed)/1000.0, (double)(count*100.0/max_count)); (double)(count*100.0/max_count) ); fflush(stdout); status->last.count = count; for (i=0; i<status->charcount; i++) /*for (i=0; i<status->charcount; i++) putc('\b', stdout); printf("x\b");*/ } /*************************************************************************** Loading @@ -59,8 +77,9 @@ status_finish(struct Status *status) void status_start(struct Status *status) { memset(status, 0, sizeof(*status)); status->last.clock = clock(); status->last.time = time(0); status->last.count = 0; status->timer = 0x7f; status->timer = 0x1; }
src/main-status.h +1 −1 Original line number Diff line number Diff line Loading @@ -6,7 +6,7 @@ struct Status { struct { clock_t clock; uint64_t clock; time_t time; uint64_t count; } last; Loading
src/main-throttle.c +74 −67 Original line number Diff line number Diff line /* rate calculations for the packets Since we are sending packet at a rate of 10-million-per-second, we the calculations need to be done in a light-weight manner. For one thing, we can't do a system-call per packet. NOTE: one complication to watch for is the difference between clock time and elapsed time, and that they change. We have to avoid a problem where somebody suspends the computer for a few days, then wake it up, at which point the system tries sending a million packets/secon instead of the desired thousand packets/second. */ #include "main-throttle.h" #include "port-timer.h" #include "logger.h" Loading @@ -9,83 +23,76 @@ ***************************************************************************/ void throttler_start(struct Throttler *throttler, double max_rate) { throttler->current_rate = 0.0; unsigned i; memset(throttler, 0, sizeof(*throttler)); throttler->max_rate = max_rate; throttler->last_timestamp = port_gettime(); throttler->last_count = 0; throttler->max_batch = 1.0; for (i=0; i<sizeof(throttler->buckets)/sizeof(throttler->buckets[0]); i++) { throttler->buckets[i].timestamp = port_gettime(); throttler->buckets[i].packet_count = 0; } throttler->batch_size = 1; LOG(1, "maxrate = %0.2f\n", throttler->max_rate); } /*************************************************************************** * We return the number of packets that can be sent in a batch. Thus, * instead of trying to throttle each packet individually, which has a * high per-packet cost, we try to throttle a bunch at a time. Normally, * this function will return 1, only at high rates does it return larger * numbers. * * NOTE: The minimum value this returns is 1. When it's less than that, * it'll pause and wait until it's ready to send a packet. ***************************************************************************/ uint64_t throttler_next_batch(struct Throttler *throttler, uint64_t count) throttler_next_batch(struct Throttler *throttler, uint64_t packet_count) { uint64_t timestamp = port_gettime(); double elapsed = ((double)(timestamp - throttler->last_timestamp))/1000000.0; double packets_sent = (double)(count - throttler->last_count); double new_rate; if (packets_sent < 1.01) return (uint64_t)throttler->max_batch; /* BOUNDARY CASE: if the elapsed time is zero, or very small, we * get confused. Therefore, handle this case specially */ if (elapsed < 0.00001) { throttler->max_batch *= 1.4; if (throttler->max_batch > 1000.0) throttler->max_batch = 1000.0; return (uint64_t)throttler->max_batch; } uint64_t timestamp; uint64_t index; uint64_t old_timestamp; uint64_t old_packet_count; double current_rate; double max_rate = throttler->max_rate; throttler->last_timestamp = timestamp; throttler->last_count = count; again: timestamp = port_gettime(); new_rate = 0.9 * throttler->current_rate + 0.1 * (packets_sent/elapsed); index = (throttler->index) & 0xFF; throttler->buckets[index].timestamp = timestamp; throttler->buckets[index].packet_count = packet_count; index = (++throttler->index) & 0xFF; old_timestamp = throttler->buckets[index].timestamp; old_packet_count = throttler->buckets[index].packet_count; if (new_rate > 10000000.0) printf("."); throttler->current_rate = new_rate; current_rate = 1.0*(packet_count - old_packet_count)/((timestamp - old_timestamp)/1000000.0); { double overrate = throttler->current_rate - throttler->max_rate; double overpackets = elapsed * overrate; if (current_rate > max_rate) { double waittime; if (throttler->current_rate > throttler->max_rate) { double waittime = overpackets / throttler->max_rate; unsigned x; uint64_t x1, x2; /* calculate waittime, in seconds */ waittime = (current_rate - max_rate) / throttler->max_rate; /* going to fast, so slow down */ throttler->max_batch *= 0.99; if (throttler->max_batch < 1.0) throttler->max_batch = 1.0; if (waittime > 0.1) waittime = 0.1; if (waittime > 0.2) { waittime = 0.01; } port_usleep((uint64_t)(waittime * 1000000.0)); /* wait a bit */ x = (unsigned)(waittime * 1000000.0); x1 = port_gettime(); port_usleep(x); x2 = port_gettime(); x1 = x2 - x1; //printf("%f \n", throttler->max_batch); } else { /* going to slow, so increase the speed */ throttler->max_batch *= 1.01; if (throttler->max_batch > 1000.0) throttler->max_batch = 1000.0; } throttler->batch_size *= 0.999; goto again; } return (uint64_t)throttler->max_batch; throttler->batch_size *= 1.005; if (throttler->batch_size > 10000) throttler->batch_size = 10000; throttler->current_rate = current_rate; return (uint64_t)throttler->batch_size; }
src/main-throttle.h +8 −3 Original line number Diff line number Diff line Loading @@ -6,9 +6,14 @@ struct Throttler { double max_rate; double current_rate; double max_batch; uint64_t last_count; uint64_t last_timestamp; double batch_size; unsigned index; struct { uint64_t timestamp; uint64_t packet_count; } buckets[256]; }; Loading