diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2014-05-12 18:32:51 +0400 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2014-05-12 18:32:51 +0400 |
commit | e7b98bc79bf8e01d6e2897a95502827ce2a83e7d (patch) | |
tree | 347a14a59c00a4f824a5ad3ddd742512ec6b4893 | |
parent | c0cf8924783347c4f4b4faccba88247f3cd6accd (diff) | |
download | accel-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.5 | 3 | ||||
-rw-r--r-- | accel-pppd/extra/ippool.c | 60 |
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; |