diff options
author | Kozlov Dmitry <xeb@mail.ru> | 2012-07-10 18:58:53 +0400 |
---|---|---|
committer | Kozlov Dmitry <xeb@mail.ru> | 2012-07-10 18:58:53 +0400 |
commit | 80c32d237e01b1c05663ccfa34003d2f49aa7eee (patch) | |
tree | a49da21b5219e4bc89d9794918f054f3620cb140 /accel-pppd/extra/ippool.c | |
parent | 64b5b693764c4f36870fd988ccbb53bcb188e74d (diff) | |
download | accel-ppp-80c32d237e01b1c05663ccfa34003d2f49aa7eee.tar.gz accel-ppp-80c32d237e01b1c05663ccfa34003d2f49aa7eee.zip |
initial session backup implementation
Diffstat (limited to 'accel-pppd/extra/ippool.c')
-rw-r--r-- | accel-pppd/extra/ippool.c | 102 |
1 files changed, 98 insertions, 4 deletions
diff --git a/accel-pppd/extra/ippool.c b/accel-pppd/extra/ippool.c index ab2dfb25..ccb3b2a2 100644 --- a/accel-pppd/extra/ippool.c +++ b/accel-pppd/extra/ippool.c @@ -9,6 +9,8 @@ #include "ipdb.h" #include "list.h" #include "spinlock.h" +#include "backup.h" +#include "ap_session_backup.h" #ifdef RADIUS #include "radius.h" @@ -23,6 +25,8 @@ struct ippool_t struct list_head gw_list; struct list_head tunnel_list; struct list_head items; + uint32_t startip; + uint32_t endip; spinlock_t lock; }; @@ -143,7 +147,7 @@ static int parse2(const char *str, uint32_t *begin, uint32_t *end) return 0; } -static void add_range(struct list_head *list, const char *name) +static void add_range(struct ippool_t *p, struct list_head *list, const char *name) { uint32_t i,startip, endip; struct ipaddr_t *ip; @@ -161,6 +165,9 @@ static void add_range(struct list_head *list, const char *name) list_add_tail(&ip->entry, list); cnt++; } + + p->startip = startip; + p->endip = endip; } static void generate_pool(struct ippool_t *p) @@ -243,6 +250,89 @@ static struct ipdb_t ipdb = { .put_ipv4 = put_ip, }; +#ifdef USE_BACKUP +static void put_ip_b(struct ap_session *ses, struct ipv4db_item_t *it) +{ + _free(it); +} + +static struct ipdb_t ipdb_b = { + .put_ipv4 = put_ip_b, +}; + +static int session_save(struct ap_session *ses, struct backup_mod *m) +{ + if (!ses->ipv4 || ses->ipv4->owner != &ipdb) + return -2; + + return 0; +} + +static int session_restore(struct ap_session *ses, struct backup_mod *m) +{ + struct backup_tag *tag; + in_addr_t addr = 0, peer_addr; + struct ippool_t *p; + struct ippool_item_t *it, *it0 = NULL; + + m = backup_find_mod(m->data, MODID_COMMON); + + list_for_each_entry(tag, &m->tag_list, entry) { + switch (tag->id) { + case SES_TAG_IPV4_ADDR: + addr = *(in_addr_t *)tag->data; + break; + case SES_TAG_IPV4_PEER_ADDR: + peer_addr = *(in_addr_t *)tag->data; + break; + } + } + + spin_lock(&def_pool->lock); + list_for_each_entry(it, &def_pool->items, entry) { + if (peer_addr == it->it.peer_addr && addr == it->it.addr) { + list_del(&it->entry); + it0 = it; + break; + } + } + spin_unlock(&def_pool->lock); + + if (!it0) { + list_for_each_entry(p, &pool_list, entry) { + spin_lock(&p->lock); + list_for_each_entry(it, &p->items, entry) { + if (peer_addr == it->it.peer_addr && addr == it->it.addr) { + list_del(&it->entry); + it0 = it; + break; + } + } + spin_unlock(&p->lock); + if (it0) + break; + } + } + + if (it0) + ses->ipv4 = &it0->it; + else { + ses->ipv4 = _malloc(sizeof(*ses->ipv4)); + ses->ipv4->addr = addr; + ses->ipv4->peer_addr = peer_addr; + ses->ipv4->owner = &ipdb_b; + } + + return 0; +} + +static struct backup_module backup_mod = { + .id = MODID_IPPOOL, + .save = session_save, + .restore = session_restore, +}; +#endif + #ifdef RADIUS static int parse_attr(struct ap_session *ses, struct rad_attr_t *attr) { @@ -348,11 +438,11 @@ static void ippool_init(void) p = pool_name ? find_pool(pool_name + 1, 1) : def_pool; if (!strcmp(opt->name, "gw")) - add_range(&p->gw_list, opt->val); + add_range(p, &p->gw_list, opt->val); else if (!strcmp(opt->name, "tunnel")) - add_range(&p->tunnel_list, opt->val); + add_range(p, &p->tunnel_list, opt->val); else if (!opt->val) - add_range(&p->tunnel_list, opt->name); + add_range(p, &p->tunnel_list, opt->name); } } @@ -363,6 +453,10 @@ static void ippool_init(void) ipdb_register(&ipdb); +#ifdef USE_BACKUP + backup_register_module(&backup_mod); +#endif + #ifdef RADIUS if (triton_module_loaded("radius")) triton_event_register_handler(EV_RADIUS_ACCESS_ACCEPT, (triton_event_func)ev_radius_access_accept); |