Commit 7186db23 authored by robertdavidgraham's avatar robertdavidgraham
Browse files

bunch of changes

parent 75c43c5c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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"
+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>


/***************************************************************************
@@ -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 */
@@ -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");*/
}

/***************************************************************************
@@ -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;
}
+1 −1
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@
struct Status
{
    struct {
        clock_t clock;
        uint64_t clock;
        time_t time;
        uint64_t count;
    } last;
+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"
@@ -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;
}
+8 −3
Original line number Diff line number Diff line
@@ -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