- Major release - Completely replace active/standby clustering with a new peer-to-peer clustering method which allows much greater throughput and is a lot more fault tolerant - Add internal tbf implementation for throttling without relying on tc and kernel HTB - Add support for iBGP and eBGP to advertise routes - Add cli commands "show cluster", "show bgp", "show ipcache", "show throttle", "show tbf", "suspend bgp", "restart bgp", "show user" - Interception destination must be set per-user - If SMP machine, allow use of SCHED_FIFO, which should improve performance - Added config option to send GARP at startup - Added plugin_become_master and plugin_new_session_master plugin hooks - Remove useless sessionsendarp(). This isn't needed now that we are using TUN instead of TAP. - ICMP rate limiting so not every unreachable packet is replied with an ICMP unreachable message - mangle table is not required on anything but the cluster master, so slaves will drop the mangle table and attempt to unload the ip_conntrack module - Statically assigned IP addresses (by Radius) work now - Add -d command-line flag to detach and become a daemon - Configuration file is now "/etc/l2tpns/startup-config" - Reduced MIN_IP_SIZE to 0x19 to stop a pile of Short IP warnings - Resend initial IPCP request until it's acknowleged by the client - Better radius session cleanup logic - Many miscellaenous bugfixes and performance enhancements - Thanks to Michael O'Reilly and Brendan O'Dea for most of these new features
141 lines
2.1 KiB
C
141 lines
2.1 KiB
C
// L2TPNS Linked List Stuff
|
|
// $Id: ll.c,v 1.3 2004-06-23 03:52:24 fred_nerk Exp $
|
|
|
|
#include <stdio.h>
|
|
#include <sys/file.h>
|
|
#include <sys/stat.h>
|
|
#include <malloc.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include <arpa/inet.h>
|
|
#include <errno.h>
|
|
#include <unistd.h>
|
|
#include "ll.h"
|
|
|
|
linked_list *ll_init()
|
|
{
|
|
return (linked_list *)calloc(sizeof(linked_list), 1);
|
|
}
|
|
|
|
void ll_done(linked_list *l)
|
|
{
|
|
li *i = l->head, *n;
|
|
|
|
while (i)
|
|
{
|
|
n = i->next;
|
|
free(i);
|
|
i = n;
|
|
}
|
|
|
|
free(l);
|
|
}
|
|
|
|
li *ll_push(linked_list *l, void *data)
|
|
{
|
|
li *i;
|
|
|
|
if (!l) return NULL;
|
|
if (!(i = (li *)calloc(sizeof(li), 1))) return NULL;
|
|
|
|
i->data = data;
|
|
i->next = NULL;
|
|
if (l->end)
|
|
l->end->next = i;
|
|
else
|
|
l->head = i;
|
|
l->end = i;
|
|
|
|
return i;
|
|
}
|
|
|
|
void *ll_pop(linked_list *l)
|
|
{
|
|
li *i;
|
|
void *data;
|
|
|
|
if (!l) return NULL;
|
|
if (!l->head)
|
|
return NULL;
|
|
|
|
data = l->head->data;
|
|
i = l->head->next;
|
|
free(l->head);
|
|
l->head = i;
|
|
return data;
|
|
}
|
|
|
|
void ll_iterate(linked_list *l, int(*func)(void *))
|
|
{
|
|
li *i;
|
|
if (!l || !func) return;
|
|
|
|
for (i = l->head; i; i = i->next)
|
|
{
|
|
if (i->data)
|
|
if (!func(i))
|
|
break;
|
|
}
|
|
}
|
|
|
|
void ll_reset(linked_list *l)
|
|
{
|
|
if (!l) return;
|
|
l->current = NULL;
|
|
}
|
|
|
|
void *ll_next(linked_list *l)
|
|
{
|
|
if (!l) return NULL;
|
|
if (!l->current)
|
|
l->current = l->head;
|
|
else
|
|
l->current = l->current->next;
|
|
if (!l->current)
|
|
return NULL;
|
|
return l->current->data;
|
|
}
|
|
|
|
void ll_delete(linked_list *l, void *data)
|
|
{
|
|
li *i = l->head, *p = NULL;
|
|
|
|
while (i)
|
|
{
|
|
if (i->data == data)
|
|
{
|
|
if (l->head == i) l->head = i->next;
|
|
if (l->end == i) l->end = i->next;
|
|
if (p) p->next = i->next;
|
|
free(i);
|
|
l->current = NULL;
|
|
return;
|
|
}
|
|
p = i;
|
|
i = i->next;
|
|
}
|
|
}
|
|
|
|
int ll_size(linked_list *l)
|
|
{
|
|
int count = 0;
|
|
li *i;
|
|
|
|
if (!l) return 0;
|
|
|
|
for (i = l->head; i; i = i->next)
|
|
if (i->data) count++;
|
|
|
|
return count;
|
|
}
|
|
|
|
int ll_contains(linked_list *l, void *search)
|
|
{
|
|
li *i;
|
|
for (i = l->head; i; i = i->next)
|
|
if (i->data == search)
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|