summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2014-05-12 18:32:51 +0400
committerDmitry Kozlov <xeb@mail.ru>2014-05-12 18:32:51 +0400
commite7b98bc79bf8e01d6e2897a95502827ce2a83e7d (patch)
tree347a14a59c00a4f824a5ad3ddd742512ec6b4893
parentc0cf8924783347c4f4b4faccba88247f3cd6accd (diff)
downloadaccel-ppp-e7b98bc79bf8e01d6e2897a95502827ce2a83e7d.tar.gz
accel-ppp-e7b98bc79bf8e01d6e2897a95502827ce2a83e7d.zip
ippool: introduced shuffle option
By default list of IP address is serial at startup. This option shuffles initial IP list so it becomes more random.
-rw-r--r--accel-pppd/accel-ppp.conf.53
-rw-r--r--accel-pppd/extra/ippool.c60
2 files changed, 61 insertions, 2 deletions
diff --git a/accel-pppd/accel-ppp.conf.5 b/accel-pppd/accel-ppp.conf.5
index d5fcb7ac..0b3ac31d 100644
--- a/accel-pppd/accel-ppp.conf.5
+++ b/accel-pppd/accel-ppp.conf.5
@@ -747,6 +747,9 @@ Configuration of ippool module.
.BI "gw-ip-address=" x.x.x.x
Specifies single IP address to be used as local address of ppp interfaces.
.TP
+.BI "shuffle=" 1|0
+Specifies whether to shuffle initial address list.
+.TP
.BI "gw=" range
Specifies range of local address of ppp interfaces if form:
.br
diff --git a/accel-pppd/extra/ippool.c b/accel-pppd/extra/ippool.c
index 825b8f37..15238025 100644
--- a/accel-pppd/extra/ippool.c
+++ b/accel-pppd/extra/ippool.c
@@ -51,6 +51,7 @@ static struct ipdb_t ipdb;
static in_addr_t conf_gw_ip_address;
static int conf_vendor = 0;
static int conf_attr = 88; // Framed-Pool
+static int conf_shuffle;
static int cnt;
static LIST_HEAD(pool_list);
@@ -175,18 +176,71 @@ static void add_range(struct ippool_t *p, struct list_head *list, const char *na
p->generate = generate;
}
+static uint8_t get_random()
+{
+ static uint8_t buf[128];
+ static int pos = 0;
+ int r;
+
+ if (pos == 0)
+ read(urandom_fd, buf, 128);
+
+ r = buf[pos++];
+
+ if (pos == 128)
+ pos = 0;
+
+ return r;
+}
+
static void generate_pool_p2p(struct ippool_t *p)
{
struct ippool_item_t *it;
struct ipaddr_t *addr = NULL;
struct ipaddr_t *peer_addr;
+ struct list_head *pos, *pos1 = p->tunnel_list.next, *pos2 = p->tunnel_list.prev;
+ uint8_t r, t = 0;
while (1) {
if (list_empty(&p->tunnel_list))
break;
else {
- peer_addr = list_entry(p->tunnel_list.next, typeof(*peer_addr), entry);
- list_del(&peer_addr->entry);
+ if (conf_shuffle) {
+ if (pos1 == &p->tunnel_list)
+ pos1 = pos1->next;
+
+ if (pos2 == &p->tunnel_list)
+ pos2 = pos2->prev;
+
+ if (t++ < 10)
+ r = get_random();
+ else
+ r = get_random()%64;
+
+ if (r < 32)
+ pos = pos1;
+ else if (r < 64)
+ pos = pos2;
+
+ pos1 = pos1->next;
+ pos2 = pos2->prev;
+
+ if (r >= 64)
+ continue;
+
+ peer_addr = list_entry(pos, typeof(*peer_addr), entry);
+ if (pos == pos1)
+ pos1 = pos1->next;
+
+ if (pos == pos2)
+ pos2 = pos2->prev;
+
+ list_del(&peer_addr->entry);
+ t = 0;
+ } else {
+ peer_addr = list_entry(p->tunnel_list.next, typeof(*peer_addr), entry);
+ list_del(&peer_addr->entry);
+ }
}
if (!conf_gw_ip_address) {
@@ -536,6 +590,8 @@ static void ippool_init2(void)
#endif
if (!strcmp(opt->name, "gw-ip-address"))
parse_gw_ip_address(opt->val);
+ else if (!strcmp(opt->name, "shuffle"))
+ conf_shuffle = atoi(opt->val);
else {
pool_name = NULL;
allocator = NULL;