Skip to content

Commit

Permalink
Changes to timing and igmpproxy
Browse files Browse the repository at this point in the history
This commit contains a number of changes to the timing structure and
main event loops.
Also several variables and structs were moved to igmpproxy.h in preperation
to coming changes.
Includes minor changes to config.c and request.c to include new blacklists
for interfaces.
callout.c is modified to a simpler and more stable algorithm.
igmpproxy.h and igmpproxy.c are sanitized and adopted to the new callout queue.

FIXES: #58

Fixed a few typos and comments

Added sighup_action to struct Config
  • Loading branch information
Uglymotha committed May 30, 2020
1 parent f71ba40 commit 9517ac5
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 356 deletions.
214 changes: 48 additions & 166 deletions src/callout.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,91 +37,47 @@

/* the code below implements a callout queue */
static int id = 0;
static struct timeOutQueue *queue = 0; /* pointer to the beginning of timeout queue */
static struct timeOutQueue *queue = NULL; /* pointer to the beginning of timeout queue */

struct timeOutQueue {
struct timeOutQueue *next; // Next event in queue
int id;
timer_f func; // function to call
void *data; // Data for function
int time; // Time offset for next event
long time; // Time for event
struct timeOutQueue *next; // Next event in queue
};

// Method for dumping the Queue to the log.
static void debugQueue(void);

/**
* Initializes the callout queue
*/
void callout_init(void) {
queue = NULL;
}

/**
* Clears all scheduled timeouts...
*/
void free_all_callouts(void) {
struct timeOutQueue *p;

while (queue) {
p = queue;
queue = queue->next;
free(p);
for (p = queue ? queue->next : NULL; queue; queue = p, p = p ? p->next : NULL) {
free(queue); // Alloced by timer_setTimer()
}
my_log(LOG_DEBUG, 0, "free_all_callouts: All Timeouts removed, Queue is empty.");
}


/**
* elapsed_time seconds have passed; perform all the events that should
* happen.
* Execute all expired timers, using .5s grace.
*/
void age_callout_queue(int elapsed_time) {
struct timeOutQueue *ptr;
struct timeOutQueue *_queue = NULL;
struct timeOutQueue *last = NULL;
int i = 0;

for (ptr = queue; ptr; ptr = ptr->next) {
if (ptr->time > elapsed_time) {
ptr->time -= elapsed_time;
break;
} else {
elapsed_time -= ptr->time;
if (_queue == NULL)
_queue = ptr;
last = ptr;
}
}

queue = ptr;
if (last) {
last->next = NULL;
}

/* process existing events */
for (ptr = _queue; ptr; ptr = _queue, i++) {
_queue = _queue->next;
void age_callout_queue(struct timespec curtime) {
struct timeOutQueue *ptr = queue;
int i = 1;
if (curtime.tv_sec == 0) clock_gettime (CLOCK_MONOTONIC, &curtime);
while (ptr && ((ptr->time <= curtime.tv_sec) || (curtime.tv_nsec >= 500000000 && ptr->time <= curtime.tv_sec-1))) {
my_log(LOG_DEBUG, 0, "About to call timeout %d (#%d)", ptr->id, i);
if (ptr->func)
ptr->func(ptr->data);
free(ptr);
}
}

/**
* Return in how many seconds age_callout_queue() would like to be called.
* Return -1 if there are no events pending.
*/
int timer_nextTimer(void) {
if (queue) {
if (queue->time < 0) {
my_log(LOG_WARNING, 0, "timer_nextTimer top of queue says %d",
queue->time);
return 0;
struct timeOutQueue *tmp = ptr;
if (ptr->func) {
ptr->func(ptr->data);
}
return queue->time;
queue = ptr = ptr->next;
free(tmp); // Alloced by timer_setTimer()
i++;
}
return -1;
}

/**
Expand All @@ -131,61 +87,41 @@ int timer_nextTimer(void) {
* @param data - Pointer to the function data to supply...
*/
int timer_setTimer(int delay, timer_f action, void *data) {
struct timeOutQueue *ptr, *node, *prev;
int i = 0;
struct timeOutQueue *ptr = queue, *node;
struct timespec curtime;
int i = 1;

/* create a node */
// create a node. Freed by free_all_callouts() and age_callout_queue().
node = (struct timeOutQueue *)malloc(sizeof(struct timeOutQueue));
if (node == 0) {
if (! node) {
my_log(LOG_WARNING, 0, "Malloc Failed in timer_settimer\n");
return -1;
}
clock_gettime(CLOCK_MONOTONIC, &curtime);
node->func = action;
node->data = data;
node->time = delay;
node->next = 0;
node->time = curtime.tv_sec + delay;
node->id = ++id;
node->next = NULL;

prev = ptr = queue;

/* insert node in the queue */

/* if the queue is empty, insert the node and return */
if (!queue) {
if (! queue) {
// if the queue is empty, insert the node and return.
queue = node;
}
else {
/* chase the pointer looking for the right place */
while (ptr) {
if (delay < ptr->time) {
// We found the correct node
node->next = ptr;
if (ptr == queue) {
queue = node;
}
else {
prev->next = node;
}
ptr->time -= node->time;
my_log(LOG_DEBUG, 0,
"Created timeout %d (#%d) - delay %d secs",
node->id, i, node->time);
debugQueue();
return node->id;
} else {
// Continur to check nodes.
delay -= ptr->time; node->time = delay;
prev = ptr;
ptr = ptr->next;
}
i++;
} else {
// chase the queue looking for the right place.
for (i++; ptr->next && node->time >= ptr->next->time; ptr = ptr->next, i++);
if (ptr == queue && node->time < ptr->time) {
// Start of queue, insert.
queue = node;
node->next = ptr;
} else {
node->next = ptr->next;
ptr->next = node;
}
prev->next = node;
}
my_log(LOG_DEBUG, 0, "Created timeout %d (#%d) - delay %d secs",
node->id, i, node->time);
debugQueue();

debugQueue();
my_log(LOG_DEBUG, 0, "Created timeout %d (#%d) - delay %d secs", node->id, i, delay);
return node->id;
}

Expand All @@ -194,76 +130,22 @@ int timer_setTimer(int delay, timer_f action, void *data) {
*/
int timer_leftTimer(int timer_id) {
struct timeOutQueue *ptr;
int left = 0;

if (!timer_id)
return -1;

for (ptr = queue; ptr; ptr = ptr->next) {
left += ptr->time;
if (ptr->id == timer_id) {
return left;
}
struct timespec curtime;
for (ptr = queue; ptr && ptr->id != timer_id; ptr = ptr->next);
if (ptr) {
clock_gettime(CLOCK_MONOTONIC, &curtime);
return (ptr->time - curtime.tv_sec);
}
return -1;
}

/**
* clears the associated timer. Returns 1 if succeeded.
*/
int timer_clearTimer(int timer_id) {
struct timeOutQueue *ptr, *prev;
int i = 0;

if (!timer_id)
return 0;

prev = ptr = queue;

/*
* find the right node, delete it. the subsequent node's time
* gets bumped up
*/

debugQueue();
while (ptr) {
if (ptr->id == timer_id) {
/* got the right node */

/* unlink it from the queue */
if (ptr == queue)
queue = queue->next;
else
prev->next = ptr->next;

/* increment next node if any */
if (ptr->next != 0)
(ptr->next)->time += ptr->time;

if (ptr->data)
free(ptr->data);
my_log(LOG_DEBUG, 0, "deleted timer %d (#%d)", ptr->id, i);
free(ptr);
debugQueue();
return 1;
}
prev = ptr;
ptr = ptr->next;
i++;
}
// If we get here, the timer was not deleted.
my_log(LOG_DEBUG, 0, "failed to delete timer %d (#%d)", timer_id, i);
debugQueue();
return 0;
}

/**
* debugging utility
*/
static void debugQueue(void) {
struct timeOutQueue *ptr;

for (ptr = queue; ptr; ptr = ptr->next) {
my_log(LOG_DEBUG, 0, "(Id:%d, Time:%d) ", ptr->id, ptr->time);
int i;
for (i = 1, ptr = queue; ptr; ptr = ptr->next, i++) {
my_log(LOG_DEBUG, 0, "(%d - Id:%d, Time:%d) ", i, ptr->id, ptr->time);
}
}
25 changes: 13 additions & 12 deletions src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,11 @@ struct vifconfig {

// Keep allowed nets for VIF.
struct SubnetList* allowednets;
struct SubnetList* deniednets;

// Allowed Groups
struct SubnetList* allowedgroups;
struct SubnetList* deniedgroups;

// Next config in list...
struct vifconfig* next;
Expand Down Expand Up @@ -226,32 +228,29 @@ void configureVifs(void) {
}

// Loop through all VIFs...
for ( Ix = 0; (Dp = getIfByIx(Ix)); Ix++ ) {
if ( Dp->InAdr.s_addr && ! (Dp->Flags & IFF_LOOPBACK) ) {

for (Ix = 0; (Dp = getIfByIx(Ix)); Ix++) {
if (Dp->InAdr.s_addr && ! (Dp->Flags & IFF_LOOPBACK)) {
// Now try to find a matching config...
for( confPtr = vifconf; confPtr; confPtr = confPtr->next) {

for (confPtr = vifconf; confPtr; confPtr = confPtr->next) {
// I the VIF names match...
if(strcmp(Dp->Name, confPtr->name)==0) {
if (strcmp(Dp->Name, confPtr->name) == 0) {
struct SubnetList *vifLast;

my_log(LOG_DEBUG, 0, "Found config for %s", Dp->Name);


// Set the VIF state
Dp->state = confPtr->state;

Dp->threshold = confPtr->threshold;
Dp->ratelimit = confPtr->ratelimit;

// Go to last allowed net on VIF...
for(vifLast = Dp->allowednets; vifLast->next; vifLast = vifLast->next);

// Insert the configured nets...
// Go to last allowed net on VIF and insert configured nets.
for (vifLast = Dp->allowednets; vifLast->next; vifLast = vifLast->next);
vifLast->next = confPtr->allowednets;

// Link the black- and whitelists.
Dp->deniednets = confPtr->deniednets;
Dp->allowedgroups = confPtr->allowedgroups;
Dp->deniedgroups = confPtr->deniedgroups;

break;
}
Expand Down Expand Up @@ -290,7 +289,9 @@ struct vifconfig *parsePhyintToken(void) {
tmpPtr->threshold = 1;
tmpPtr->state = commonConfig.defaultInterfaceState;
tmpPtr->allowednets = NULL;
tmpPtr->deniednets = NULL;
tmpPtr->allowedgroups = NULL;
tmpPtr->deniedgroups = NULL;

// Make a copy of the token to store the IF name
tmpPtr->name = strdup( token );
Expand Down
Loading

0 comments on commit 9517ac5

Please sign in to comment.