diff options
author | Dmitry Kozlov <xeb@mail.ru> | 2021-04-30 11:54:05 +0300 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2021-04-30 11:54:05 +0300 |
commit | 277ad4c3c7af01b266136c5068b282d43d774949 (patch) | |
tree | 3575abe2e4489ac1cd2617fca3f47fdcf60af7f8 | |
parent | b1ca6157c6fcd93966e115f113a032a42f77843d (diff) | |
parent | 3b74e1088af7b525880b386136c0330bbed377a0 (diff) | |
download | accel-ppp-277ad4c3c7af01b266136c5068b282d43d774949.tar.gz accel-ppp-277ad4c3c7af01b266136c5068b282d43d774949.zip |
Merge branch 'master' of github.com:accel-ppp/accel-ppp
-rw-r--r-- | accel-pppd/extra/ippool.c | 181 | ||||
-rw-r--r-- | accel-pppd/extra/ipv6pool.c | 158 |
2 files changed, 174 insertions, 165 deletions
diff --git a/accel-pppd/extra/ippool.c b/accel-pppd/extra/ippool.c index 00f22f1..7a91cf4 100644 --- a/accel-pppd/extra/ippool.c +++ b/accel-pppd/extra/ippool.c @@ -332,38 +332,39 @@ static void generate_pool_net30(struct ippool_t *p) static struct ipv4db_item_t *get_ip(struct ap_session *ses) { struct ippool_item_t *it; - struct ippool_t *p; + struct ippool_t *pool, *start; if (ses->ipv4_pool_name) - p = find_pool(ses->ipv4_pool_name, 0); + pool = find_pool(ses->ipv4_pool_name, 0); else - p = def_pool; + pool = def_pool; - if (!p) + if (!pool) return NULL; -again: - spin_lock(&p->lock); - if (!list_empty(&p->items)) { - it = list_entry(p->items.next, typeof(*it), entry); - list_del(&it->entry); - } else - it = NULL; - spin_unlock(&p->lock); + start = pool; + do { + spin_lock(&pool->lock); + if (!list_empty(&pool->items)) { + it = list_entry(pool->items.next, typeof(*it), entry); + list_del(&it->entry); + } else + it = NULL; + spin_unlock(&pool->lock); - if (it) { - if (ses->ctrl->ppp) - it->it.addr = conf_gw_ip_address; - else - it->it.addr = 0; + if (it) { + if (ses->ctrl->ppp) + it->it.addr = conf_gw_ip_address; + else + it->it.addr = 0; - it->it.mask = 0; + it->it.mask = 0; - return &it->it; - } else if (p->next) { - p = p->next; - goto again; - } + return &it->it; + } + + pool = pool->next; + } while (pool && pool != start); return NULL; } @@ -539,63 +540,58 @@ static int parse_vendor_opt(const char *opt) } #endif -static void parse_options(const char *opt, char **pool_name, generate_func *generate, struct ippool_t **next) +static int parse_options(const char *opt, struct ippool_t **pool, generate_func *generate, struct ippool_t **next) { - char *ptr1, *ptr2; - int len; - char tmp[256]; - - ptr1 = strstr(opt, ",name="); - if (ptr1) { - ptr1 += 6; - for (ptr2 = ptr1; *ptr2 && *ptr2 != ','; ptr2++); - len = ptr2 - ptr1; - *pool_name = _malloc(len + 1); - memcpy(*pool_name, ptr1, len); - (*pool_name)[len] = 0; - } - - ptr1 = strstr(opt, ",allocator="); - if (ptr1) { - ptr1 += 11; - for (ptr2 = ptr1; *ptr2 && *ptr2 != ','; ptr2++); - len = ptr2 - ptr1; - - if (len == 3 && memcmp(ptr1, "p2p", 3) == 0) + char *name, *ptr; + + name = strstr(opt, ",name="); + if (name) { + name += sizeof(",name=") - 1; + ptr = strchrnul(name, ','); + name = _strndup(name, ptr - name); + if (!name) + return -1; + *pool = find_pool(name, 1); + } else if ((name = strchr(opt, ',')) && !strchr(name + 1, '=')) { + name = _strdup(name + 1); + if (!name) + return -1; + *pool = find_pool(name, 1); + } else + *pool = def_pool; + + name = strstr(opt, ",allocator="); + if (name) { + name += sizeof(",allocator=") - 1; + ptr = strchrnul(name, ','); + name = strncpy(alloca(ptr - name + 1), name, ptr - name + 1); + if (strcmp(name, "p2p") == 0) *generate = generate_pool_p2p; - else if (len == 5 && memcmp(ptr1, "net30", 5) == 0) + else if (strcmp(name, "net30") == 0) *generate = generate_pool_net30; - else + else { log_error("ipool: '%s': unknown allocator\n", opt); - } - - ptr1 = strstr(opt, ",next="); - if (ptr1) { - ptr1 += 6; - for (ptr2 = ptr1; *ptr2 && *ptr2 != ','; ptr2++); - if (*ptr2 == ',') { - len = ptr2 - ptr1; - memcpy(tmp, ptr1, len); - tmp[len] = 0; - ptr1 = tmp; + return -1; } + } else + *generate = generate_pool_p2p; + + name = strstr(opt, ",next="); + if (name) { + name += sizeof(",next=") - 1; + ptr = strchrnul(name, ','); + name = strncpy(alloca(ptr - name + 1), name, ptr - name + 1); + *next = find_pool(name, 0); + if (!*next) { + name = _strdup(name); + if (!name) + return -1; + *next = find_pool(name, 1); + } + } else + *next = NULL; - *next = find_pool(ptr1, 0); - if (!(*next)) - log_error("ippool: %s: next pool not found\n", opt); - } - - if (!*pool_name) { - ptr1 = strchr(opt, ','); - if (!ptr1) - return; - - for (ptr2 = ptr1 + 1; *ptr2 && *ptr2 != '='; ptr2++); - if (*ptr2 == '=') - return; - - *pool_name = _strdup(ptr1 + 1); - } + return 0; } static void ippool_init1(void) @@ -607,10 +603,8 @@ static void ippool_init2(void) { struct conf_sect_t *s = conf_get_section("ip-pool"); struct conf_option_t *opt; - struct ippool_t *p; - char *pool_name = NULL; + struct ippool_t *pool, *next; generate_func generate; - struct ippool_t *next; if (!s) return; @@ -623,9 +617,7 @@ static void ippool_init2(void) if (!strcmp(opt->name, "vendor")) { conf_vendor = parse_vendor_opt(opt->val); continue; - } - - if (!strcmp(opt->name, "attr")) { + } else if (!strcmp(opt->name, "attr")) { conf_attr = parse_attr_opt(opt->val); continue; } @@ -636,30 +628,32 @@ static void ippool_init2(void) else if (!strcmp(opt->name, "shuffle")) conf_shuffle = atoi(opt->val); else { - pool_name = NULL; - generate = generate_pool_p2p; - next = NULL; - - parse_options(opt->raw, &pool_name, &generate, &next); - - p = pool_name ? find_pool(pool_name, 1) : def_pool; + if (parse_options(opt->raw, &pool, &generate, &next)) { + log_error("ippool: failed to parse '%s'\n", opt->raw); + continue; + } if (!strcmp(opt->name, "gw")) - add_range(p, &p->gw_list, opt->val, generate); + add_range(pool, &pool->gw_list, opt->val, generate); else if (!strcmp(opt->name, "tunnel")) - add_range(p, &p->tunnel_list, opt->val, generate); + add_range(pool, &pool->tunnel_list, opt->val, generate); else if (!opt->val || strchr(opt->name, ',')) - add_range(p, &p->tunnel_list, opt->name, generate); + add_range(pool, &pool->tunnel_list, opt->name, generate); - p->next = next; + if (next) + pool->next = next; } } if (def_pool->generate) def_pool->generate(def_pool); - list_for_each_entry(p, &pool_list, entry) - p->generate(p); + list_for_each_entry(pool, &pool_list, entry) { + if (pool->generate) + pool->generate(pool); + else + log_warn("ippool: pool '%s' is empty or not defined\n", pool->name); + } #ifdef USE_BACKUP backup_register_module(&backup_mod); @@ -673,4 +667,3 @@ static void ippool_init2(void) DEFINE_INIT(51, ippool_init1); DEFINE_INIT2(52, ippool_init2); - diff --git a/accel-pppd/extra/ipv6pool.c b/accel-pppd/extra/ipv6pool.c index 24ea373..3494a91 100644 --- a/accel-pppd/extra/ipv6pool.c +++ b/accel-pppd/extra/ipv6pool.c @@ -249,7 +249,7 @@ static struct ipv6db_item_t *get_ip(struct ap_session *ses) { struct ippool_item_t *it; struct ipv6db_addr_t *a; - struct ippool_t *pool; + struct ippool_t *pool, *start; if (ses->ipv6_pool_name) pool = find_pool(IPPOOL_ADDRESS, ses->ipv6_pool_name, 0); @@ -259,30 +259,31 @@ static struct ipv6db_item_t *get_ip(struct ap_session *ses) if (!pool) return NULL; -again: - spin_lock(&pool->lock); - if (!list_empty(&pool->items)) { - it = list_entry(pool->items.next, typeof(*it), entry); - list_del(&it->entry); - } else - it = NULL; - spin_unlock(&pool->lock); - - if (it) { - a = list_entry(it->it.addr_list.next, typeof(*a), entry); - if (a->prefix_len == 128) { - memcpy(&it->it.intf_id, conf_gw_addr.s6_addr + 8, 8); - memcpy(&it->it.peer_intf_id, a->addr.s6_addr + 8, 8); - } else { - it->it.intf_id = 0; - it->it.peer_intf_id = 0; + start = pool; + do { + spin_lock(&pool->lock); + if (!list_empty(&pool->items)) { + it = list_entry(pool->items.next, typeof(*it), entry); + list_del(&it->entry); + } else + it = NULL; + spin_unlock(&pool->lock); + + if (it) { + a = list_entry(it->it.addr_list.next, typeof(*a), entry); + if (a->prefix_len == 128) { + memcpy(&it->it.intf_id, conf_gw_addr.s6_addr + 8, 8); + memcpy(&it->it.peer_intf_id, a->addr.s6_addr + 8, 8); + } else { + it->it.intf_id = 0; + it->it.peer_intf_id = 0; + } + + return &it->it; } - return &it->it; - } else if (pool->next) { pool = pool->next; - goto again; - } + } while (pool && pool != start); return NULL; } @@ -299,28 +300,28 @@ static void put_ip(struct ap_session *ses, struct ipv6db_item_t *it) static struct ipv6db_prefix_t *get_dp(struct ap_session *ses) { struct dppool_item_t *it; - struct ippool_t *pool; + struct ippool_t *pool, *start; if (ses->dpv6_pool_name) pool = find_pool(IPPOOL_PREFIX, ses->dpv6_pool_name, 0); else pool = def_dppool; -again: - spin_lock(&pool->lock); - if (!list_empty(&pool->items)) { - it = list_entry(pool->items.next, typeof(*it), entry); - list_del(&it->entry); - } else - it = NULL; - spin_unlock(&pool->lock); + start = pool; + do { + spin_lock(&pool->lock); + if (!list_empty(&pool->items)) { + it = list_entry(pool->items.next, typeof(*it), entry); + list_del(&it->entry); + } else + it = NULL; + spin_unlock(&pool->lock); + + if (it) + return &it->it; - if (it) - return &it->it; - else if (pool->next) { pool = pool->next; - goto again; - } + } while (pool && pool != start); return NULL; } @@ -404,30 +405,39 @@ static int parse_vendor_opt(const char *opt) } #endif -static void parse_options(enum ippool_type type, const char *opt, char **pool_name, struct ippool_t **next) +static int parse_options(enum ippool_type type, const char *opt, struct ippool_t **pool, struct ippool_t **next) { - char *ptr1, *ptr2, *tmp; - - ptr1 = strstr(opt, ",name="); - if (ptr1) { - ptr1 += sizeof(",name=") - 1; - ptr2 = strchrnul(ptr1, ','); - *pool_name = _strndup(ptr1, ptr2 - ptr1); - } - - ptr1 = strstr(opt, ",next="); - if (ptr1) { - ptr1 += sizeof(",next=") - 1; - ptr2 = strchrnul(ptr1, ','); - if (*ptr2 == ',') { - tmp = alloca(ptr2 - ptr1 + 1); - strncpy(tmp, ptr1, ptr2 - ptr1); - ptr1 = tmp; + char *name, *ptr; + + name = strstr(opt, ",name="); + if (name) { + name += sizeof(",name=") - 1; + ptr = strchrnul(name, ','); + name = _strndup(name, ptr - name); + if (!name) + return -1; + *pool = find_pool(type, name, 1); + } else if (type == IPPOOL_PREFIX) + *pool = def_dppool; + else + *pool = def_ippool; + + name = strstr(opt, ",next="); + if (name) { + name += sizeof(",next=") - 1; + ptr = strchrnul(name, ','); + name = strncpy(alloca(ptr - name + 1), name, ptr - name + 1); + *next = find_pool(type, name, 0); + if (!*next) { + name = _strdup(name); + if (!name) + return -1; + *next = find_pool(type, name, 1); } - *next = find_pool(type, ptr1, 0); - if (!(*next)) - log_error("ipv6_pool: %s: next pool not found\n", opt); - } + } else + *next = NULL; + + return 0; } static void ippool_init1(void) @@ -440,7 +450,7 @@ static void ippool_init2(void) struct conf_sect_t *s = conf_get_section("ipv6-pool"); struct conf_option_t *opt; struct ippool_t *pool, *next; - char *pool_name, *val; + char *val; enum ippool_type type; #ifdef RADIUS int dppool_attr = 0, ippool_attr = 0; @@ -458,12 +468,10 @@ static void ippool_init2(void) if (!strcmp(opt->name, "vendor")) { conf_vendor = parse_vendor_opt(opt->val); continue; - } - if (!strcmp(opt->name, "attr-prefix")) { + } else if (!strcmp(opt->name, "attr-prefix")) { dppool_attr = parse_attr_opt(opt->val); continue; - } - if (!strcmp(opt->name, "attr-address")) { + } else if (!strcmp(opt->name, "attr-address")) { ippool_attr = parse_attr_opt(opt->val); continue; } @@ -471,26 +479,34 @@ static void ippool_init2(void) #endif if (!strcmp(opt->name, "gw-ip6-address")) { if (inet_pton(AF_INET6, opt->val, &conf_gw_addr) == 0) - log_error("ipv6_pool: failed to parse gw-ip6-address\n"); + log_error("ipv6_pool: failed to parse '%s'\n", opt->raw); continue; } else if (!strcmp(opt->name, "delegate")) { type = IPPOOL_PREFIX; val = opt->val; - pool = def_dppool; } else { type = IPPOOL_ADDRESS; val = opt->name; - pool = def_ippool; } - pool_name = NULL; - parse_options(type, opt->raw, &pool_name, &next); + if (parse_options(type, opt->raw, &pool, &next)) { + log_error("ipv6_pool: failed to parse '%s'\n", opt->raw); + continue; + } - if (pool_name) - pool = find_pool(type, pool_name, 1); add_prefix(type, pool, val); - pool->next = next; + if (next) + pool->next = next; + } + + list_for_each_entry(pool, &ippool_list, entry) { + if (list_empty(&pool->items)) + log_warn("ipv6_pool: pool '%s' is empty or not defined\n", pool->name); + } + list_for_each_entry(pool, &dppool_list, entry) { + if (list_empty(&pool->items)) + log_warn("ipv6_pool: delegate pool '%s' is empty or not defined\n", pool->name); } #ifdef RADIUS |