diff options
-rw-r--r-- | accel-pptpd/CMakeLists.txt | 1 | ||||
-rw-r--r-- | accel-pptpd/accel-pptpd.conf | 4 | ||||
-rw-r--r-- | accel-pptpd/ipdb.c | 23 | ||||
-rw-r--r-- | accel-pptpd/ipdb.h | 15 | ||||
-rw-r--r-- | accel-pptpd/ippool.c | 209 | ||||
-rw-r--r-- | accel-pptpd/iprange.c | 2 | ||||
-rw-r--r-- | accel-pptpd/ppp/ipcp_opt_ipaddr.c | 48 | ||||
-rw-r--r-- | accel-pptpd/radius/dm_coa.c (renamed from accel-pptpd/radius/pd_coa.c) | 106 | ||||
-rw-r--r-- | accel-pptpd/radius/radius.c | 33 | ||||
-rw-r--r-- | accel-pptpd/radius/radius.h | 5 | ||||
-rw-r--r-- | accel-pptpd/triton/triton.c | 6 |
11 files changed, 366 insertions, 86 deletions
diff --git a/accel-pptpd/CMakeLists.txt b/accel-pptpd/CMakeLists.txt index 729b4e2a..a462358f 100644 --- a/accel-pptpd/CMakeLists.txt +++ b/accel-pptpd/CMakeLists.txt @@ -30,6 +30,7 @@ ADD_EXECUTABLE(pptpd ipdb.c iprange.c + ippool.c main.c ) diff --git a/accel-pptpd/accel-pptpd.conf b/accel-pptpd/accel-pptpd.conf index 9d5aa9b2..206c9d2d 100644 --- a/accel-pptpd/accel-pptpd.conf +++ b/accel-pptpd/accel-pptpd.conf @@ -31,4 +31,6 @@ verbose=1 192.168.10.20-20 [ip-pool] -192.168.100.200/24 +#gw-ip-address=192.168.100.10 +gw=192.168.100.210-211 +tunnel=192.168.100.200-201 diff --git a/accel-pptpd/ipdb.c b/accel-pptpd/ipdb.c index 7b679dc7..62a99e9f 100644 --- a/accel-pptpd/ipdb.c +++ b/accel-pptpd/ipdb.c @@ -3,23 +3,24 @@ static LIST_HEAD(ipdb_handlers); -int __export ipdb_get(struct ppp_t *ppp, in_addr_t *addr, in_addr_t *peer_addr) +__export struct ipdb_item_t *ipdb_get(struct ppp_t *ppp) { struct ipdb_t *ipdb; + struct ipdb_item_t *it; - list_for_each_entry(ipdb, &ipdb_handlers, entry) - if (!ipdb->get(ppp, addr, peer_addr)) - return 0; + list_for_each_entry(ipdb, &ipdb_handlers, entry) { + it = ipdb->get(ppp); + if (it) + return it; + } - return -1; + return NULL; } -void __export ipdb_put(struct ppp_t *ppp, in_addr_t addr, in_addr_t peer_addr) -{ - struct ipdb_t *ipdb; - list_for_each_entry(ipdb, &ipdb_handlers, entry) - if (ipdb->put) - ipdb->put(ppp, addr, peer_addr); +void __export ipdb_put(struct ppp_t *ppp, struct ipdb_item_t *it) +{ + if (it->owner->put) + it->owner->put(ppp, it); } void __export ipdb_register(struct ipdb_t *ipdb) diff --git a/accel-pptpd/ipdb.h b/accel-pptpd/ipdb.h index 6703a48b..ebf38853 100644 --- a/accel-pptpd/ipdb.h +++ b/accel-pptpd/ipdb.h @@ -6,15 +6,22 @@ #include "ppp.h" #include "list.h" +struct ipdb_item_t +{ + struct ipdb_t *owner; + in_addr_t addr; + in_addr_t peer_addr; +}; + struct ipdb_t { struct list_head entry; - int (*get)(struct ppp_t *ppp, in_addr_t *addr, in_addr_t *peer_addr); - void (*put)(struct ppp_t *ppp, in_addr_t addr, in_addr_t peer_addr); + struct ipdb_item_t *(*get)(struct ppp_t *ppp); + void (*put)(struct ppp_t *ppp, struct ipdb_item_t *); }; -int ipdb_get(struct ppp_t *ppp, in_addr_t *addr, in_addr_t *peer_addr); -void ipdb_put(struct ppp_t *ppp, in_addr_t addr, in_addr_t peer_addr); +struct ipdb_item_t *ipdb_get(struct ppp_t *ppp); +void ipdb_put(struct ppp_t *ppp, struct ipdb_item_t *); void ipdb_register(struct ipdb_t *); diff --git a/accel-pptpd/ippool.c b/accel-pptpd/ippool.c new file mode 100644 index 00000000..eb79b02a --- /dev/null +++ b/accel-pptpd/ippool.c @@ -0,0 +1,209 @@ +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> +#include <unistd.h> +#include <string.h> +#include <arpa/inet.h> + +#include "ipdb.h" +#include "list.h" +#include "triton/spinlock.h" + +struct ippool_item_t +{ + struct list_head entry; + struct ipdb_item_t it; +}; + +struct ipaddr_t +{ + struct list_head entry; + in_addr_t addr; +}; + +static LIST_HEAD(gw_list); +static LIST_HEAD(tunnel_list); +static LIST_HEAD(ippool); +static spinlock_t pool_lock = SPINLOCK_INITIALIZER; +static struct ipdb_t ipdb; + +static in_addr_t conf_gw_ip_address; +static int cnt; + +static void parse_gw_ip_address(const char *val) +{ + if (!val) + return; + + conf_gw_ip_address = inet_addr(val); +} + +//parses ranges like x.x.x.x/mask +static int parse1(const char *str, uint32_t *begin, uint32_t *end) +{ + int n, f1, f2, f3, f4, m, mask = 0; + + n = sscanf(str, "%u.%u.%u.%u/%u",&f1, &f2, &f3, &f4, &m); + if (n != 5) + return -1; + if (f1 > 255) + return -1; + if (f1 > 255) + return -1; + if (f1 > 255) + return -1; + if (f1 > 255) + return -1; + if (m == 0 || m > 32) + return -1; + + for (n = 0; n < m ; n++) + mask |= 1 << n; + + *begin = (f4 << 24) | (f3 << 16) | (f2 << 8) | f1; + *end = *begin | ~mask; + + return 0; +} + +//parses ranges like x.x.x.x-y +static int parse2(const char *str, uint32_t *begin, uint32_t *end) +{ + int n, f1, f2, f3, f4, m; + + n = sscanf(str, "%u.%u.%u.%u-%u",&f1, &f2, &f3, &f4, &m); + if (n != 5) + return -1; + if (f1 > 255) + return -1; + if (f2 > 255) + return -1; + if (f3 > 255) + return -1; + if (f4 > 255) + return -1; + if (m < f4 || m > 255) + return -1; + + *begin = (f4 << 24) | (f3 << 16) | (f2 << 8) | f1; + *end = (m << 24) | (f3 << 16) | (f2 << 8) | f1; + + return 0; +} + +static void add_range(struct list_head *list, const char *name) +{ + uint32_t i,startip, endip; + struct ipaddr_t *ip; + + if (parse1(name, &startip, &endip)) + if (parse2(name, &startip, &endip)) { + fprintf(stderr, "ippool: cann't parse '%s'\n", name); + _exit(EXIT_FAILURE); + } + + for (i = ntohl(startip); i <= ntohl(endip); i++) { + ip = malloc(sizeof(*ip)); + ip->addr = htonl(i); + list_add_tail(&ip->entry, list); + cnt++; + } +} + +static void generate_pool(void) +{ + struct ippool_item_t *it; + struct ipaddr_t *addr = NULL; + struct ipaddr_t *peer_addr; + + while (1) { + if (list_empty(&tunnel_list)) + break; + else { + peer_addr = list_entry(tunnel_list.next, typeof(*peer_addr), entry); + list_del(&peer_addr->entry); + } + + if (!conf_gw_ip_address) { + if (list_empty(&gw_list)) + break; + else { + addr = list_entry(gw_list.next, typeof(*addr), entry); + list_del(&addr->entry); + } + } + + it = malloc(sizeof(*it)); + if (!it) { + fprintf(stderr, "ippool: out of memory\n"); + break; + } + + it->it.owner = &ipdb; + if (conf_gw_ip_address) + it->it.addr = conf_gw_ip_address; + else + it->it.addr = addr->addr; + + it->it.peer_addr = peer_addr->addr; + + list_add_tail(&it->entry, &ippool); + + free(addr); + free(peer_addr); + } +} + +static struct ipdb_item_t *get_ip(struct ppp_t *ppp) +{ + struct ippool_item_t *it; + + spin_lock(&pool_lock); + if (!list_empty(&ippool)) { + it = list_entry(ippool.next, typeof(*it), entry); + list_del(&it->entry); + } else + it = NULL; + spin_unlock(&pool_lock); + + return it ? &it->it : NULL; +} + +static void put_ip(struct ppp_t *ppp, struct ipdb_item_t *it) +{ + struct ippool_item_t *pit = container_of(it, typeof(*pit), it); + + spin_lock(&pool_lock); + list_add_tail(&pit->entry, &ippool); + spin_unlock(&pool_lock); +} + +static struct ipdb_t ipdb = { + .get = get_ip, + .put = put_ip, +}; + +static void __init ipool_init(void) +{ + struct conf_sect_t *s = conf_get_section("ip-pool"); + struct conf_option_t *opt; + + if (!s) + return; + + list_for_each_entry(opt, &s->items, entry) { + if (!strcmp(opt->name, "gw-ip-address")) + parse_gw_ip_address(opt->val); + else if (!strcmp(opt->name, "gw")) + add_range(&gw_list, opt->val); + else if (!strcmp(opt->name, "tunnel")) + add_range(&tunnel_list, opt->val); + else if (!opt->val) + add_range(&tunnel_list, opt->name); + } + + generate_pool(); + + ipdb_register(&ipdb); +} + diff --git a/accel-pptpd/iprange.c b/accel-pptpd/iprange.c index 000e6e6d..317b66dc 100644 --- a/accel-pptpd/iprange.c +++ b/accel-pptpd/iprange.c @@ -71,7 +71,7 @@ static struct iprange_t *parse2(const char *str) r = malloc(sizeof(*r)); r->prefix = (f4 << 24) | (f3 << 16) | (f2 << 8) | f1; - r->end = (m << 24) | (f2 << 16) | (f3 << 8) | f1; + r->end = (m << 24) | (f3 << 16) | (f2 << 8) | f1; r->mask = 0; return r; diff --git a/accel-pptpd/ppp/ipcp_opt_ipaddr.c b/accel-pptpd/ppp/ipcp_opt_ipaddr.c index 6e52cfab..64f06cd2 100644 --- a/accel-pptpd/ppp/ipcp_opt_ipaddr.c +++ b/accel-pptpd/ppp/ipcp_opt_ipaddr.c @@ -23,8 +23,7 @@ static void ipaddr_print(void (*print)(const char *fmt,...),struct ipcp_option_t struct ipaddr_option_t { struct ipcp_option_t opt; - in_addr_t addr; - in_addr_t peer_addr; + struct ipdb_item_t *ip; }; static struct ipcp_option_handler_t ipaddr_opt_hnd= @@ -51,8 +50,8 @@ static void ipaddr_free(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *opt) { struct ipaddr_option_t *ipaddr_opt=container_of(opt,typeof(*ipaddr_opt),opt); - if (ipaddr_opt->peer_addr) - ipdb_put(ipcp->ppp, ipaddr_opt->addr, ipaddr_opt->peer_addr); + if (ipaddr_opt->ip) + ipdb_put(ipcp->ppp, ipaddr_opt->ip); free(ipaddr_opt); } @@ -62,22 +61,25 @@ static int ipaddr_send_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *o struct ipaddr_option_t *ipaddr_opt=container_of(opt,typeof(*ipaddr_opt),opt); struct ipcp_opt32_t *opt32=(struct ipcp_opt32_t*)ptr; - if (!ipaddr_opt->addr && ipdb_get(ipcp->ppp, &ipaddr_opt->addr, &ipaddr_opt->peer_addr)) { - log_warn("ppp:ipcp: no free IP address\n"); - return -1; + if (!ipaddr_opt->ip) { + ipaddr_opt->ip = ipdb_get(ipcp->ppp); + if (!ipaddr_opt->ip) { + log_warn("ppp:ipcp: no free IP address\n"); + return -1; + } } - if (!iprange_client_check(ipaddr_opt->peer_addr)) { + if (!iprange_client_check(ipaddr_opt->ip->peer_addr)) { log_warn("ppp:ipcp: to avoid hard loops requested IP cannot be assigned (%i.%i.%i.%i)\n", - ipaddr_opt->peer_addr&0xff, - (ipaddr_opt->peer_addr >> 8)&0xff, - (ipaddr_opt->peer_addr >> 16)&0xff, - (ipaddr_opt->peer_addr >> 24)&0xff); + ipaddr_opt->ip->peer_addr&0xff, + (ipaddr_opt->ip->peer_addr >> 8)&0xff, + (ipaddr_opt->ip->peer_addr >> 16)&0xff, + (ipaddr_opt->ip->peer_addr >> 24)&0xff); return -1; } opt32->hdr.id=CI_ADDR; opt32->hdr.len=6; - opt32->val=ipaddr_opt->addr; + opt32->val=ipaddr_opt->ip->addr; return 6; } @@ -87,7 +89,7 @@ static int ipaddr_send_conf_nak(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *o struct ipcp_opt32_t *opt32=(struct ipcp_opt32_t*)ptr; opt32->hdr.id=CI_ADDR; opt32->hdr.len=6; - opt32->val=ipaddr_opt->peer_addr; + opt32->val=ipaddr_opt->ip->peer_addr; return 6; } @@ -99,13 +101,13 @@ static int ipaddr_recv_conf_req(struct ppp_ipcp_t *ipcp, struct ipcp_option_t *o struct sockaddr_in addr; struct npioctl np; - if (ipaddr_opt->peer_addr == opt32->val) + if (ipaddr_opt->ip->peer_addr == opt32->val) goto ack; - if (!ipaddr_opt->peer_addr) { + /*if (!ipaddr_opt->peer_addr) { ipaddr_opt->peer_addr = opt32->val; goto ack; - } + }*/ return IPCP_OPT_NAK; @@ -116,13 +118,13 @@ ack: sprintf(ifr.ifr_name,"ppp%i",ipcp->ppp->unit_idx); addr.sin_family = AF_INET; - addr.sin_addr.s_addr = ipaddr_opt->addr; + addr.sin_addr.s_addr = ipaddr_opt->ip->addr; memcpy(&ifr.ifr_addr,&addr,sizeof(addr)); if (ioctl(sock_fd, SIOCSIFADDR, &ifr)) log_error("\nipcp: failed to set PA address: %s\n", strerror(errno)); - addr.sin_addr.s_addr = ipaddr_opt->peer_addr; + addr.sin_addr.s_addr = ipaddr_opt->ip->peer_addr; memcpy(&ifr.ifr_dstaddr,&addr,sizeof(addr)); if (ioctl(sock_fd, SIOCSIFDSTADDR, &ifr)) @@ -149,10 +151,12 @@ static void ipaddr_print(void (*print)(const char *fmt,...),struct ipcp_option_t { struct ipaddr_option_t *ipaddr_opt=container_of(opt,typeof(*ipaddr_opt),opt); struct ipcp_opt32_t *opt32=(struct ipcp_opt32_t*)ptr; - struct in_addr in; + struct in_addr in = { .s_addr = 0, }; - if (ptr) in.s_addr=opt32->val; - else in.s_addr=ipaddr_opt->addr; + if (ptr) + in.s_addr = opt32->val; + else if (ipaddr_opt->ip) + in.s_addr = ipaddr_opt->ip->addr; print("<addr %s>",inet_ntoa(in)); } diff --git a/accel-pptpd/radius/pd_coa.c b/accel-pptpd/radius/dm_coa.c index 0d2f4050..c337b6af 100644 --- a/accel-pptpd/radius/pd_coa.c +++ b/accel-pptpd/radius/dm_coa.c @@ -24,6 +24,8 @@ struct dm_coa_serv_t struct triton_md_handler_t hnd; }; +static struct dm_coa_serv_t serv; + static int dm_coa_check_RA(struct rad_packet_t *pack, const char *secret) { uint8_t RA[16]; @@ -51,8 +53,77 @@ static void dm_coa_set_RA(struct rad_packet_t *pack, const char *secret) MD5_Final(pack->buf + 4, &ctx); } +static int dm_coa_send_ack(int fd, struct rad_packet_t *req, struct sockaddr_in *addr) +{ + struct rad_packet_t *reply; + uint8_t RA[16]; + + memcpy(RA, req->buf + 4, sizeof(RA)); + + reply = rad_packet_alloc(req->code == CODE_COA_REQUEST ? CODE_COA_ACK : CODE_DISCONNECT_ACK); + if (!reply) + return -1; + + reply->id = req->id; + + if (rad_packet_build(reply, RA)) { + rad_packet_free(reply); + return -1; + } + + dm_coa_set_RA(reply, conf_dm_coa_secret); + + if (conf_verbose) { + log_debug("send "); + rad_packet_print(reply, log_debug); + } + + rad_packet_send(reply, fd, addr); + + rad_packet_free(reply); + + return 0; +} + +static int dm_coa_send_nak(int fd, struct rad_packet_t *req, struct sockaddr_in *addr, int err_code) +{ + struct rad_packet_t *reply; + uint8_t RA[16]; + + memcpy(RA, req->buf + 4, sizeof(RA)); + + reply = rad_packet_alloc(req->code == CODE_COA_REQUEST ? CODE_COA_NAK : CODE_DISCONNECT_NAK); + if (!reply) + return -1; + + reply->id = req->id; + + rad_packet_add_int(reply, "Error-Cause", err_code); + + if (rad_packet_build(reply, RA)) { + rad_packet_free(reply); + return -1; + } + + dm_coa_set_RA(reply, conf_dm_coa_secret); + + if (conf_verbose) { + log_debug("send "); + rad_packet_print(reply, log_debug); + } + + rad_packet_send(reply, fd, addr); + + rad_packet_free(reply); + + return 0; +} + + static void disconnect_request(struct radius_pd_t *rpd) { + dm_coa_send_ack(serv.hnd.fd, rpd->dm_coa_req, &rpd->dm_coa_addr); + rad_packet_free(rpd->dm_coa_req); rpd->dm_coa_req = NULL; @@ -61,19 +132,17 @@ static void disconnect_request(struct radius_pd_t *rpd) static void coa_request(struct radius_pd_t *rpd) { +/// TODO: CoA handling + rad_packet_free(rpd->dm_coa_req); rpd->dm_coa_req = NULL; - -/// TODO: CoA handling } static int dm_coa_read(struct triton_md_handler_t *h) { struct rad_packet_t *pack; - struct rad_packet_t *reply = NULL; struct radius_pd_t *rpd; int err_code; - uint8_t RA[16]; struct sockaddr_in addr; @@ -91,8 +160,6 @@ static int dm_coa_read(struct triton_md_handler_t *h) goto out_err_no_reply; } - memcpy(RA, pack->buf + 4, sizeof(RA)); - if (conf_verbose) { log_debug("recv "); rad_packet_print(pack, log_debug); @@ -112,6 +179,7 @@ static int dm_coa_read(struct triton_md_handler_t *h) } rpd->dm_coa_req = pack; + memcpy(&rpd->dm_coa_addr, &addr, sizeof(addr)); if (pack->code == CODE_DISCONNECT_REQUEST) triton_context_call(rpd->ppp->ctrl->ctx, (void (*)(void *))disconnect_request, rpd); @@ -120,37 +188,13 @@ static int dm_coa_read(struct triton_md_handler_t *h) pthread_mutex_unlock(&rpd->lock); - reply = rad_packet_alloc(pack->code == CODE_COA_REQUEST ? CODE_COA_ACK : CODE_DISCONNECT_ACK); - reply->id = pack->id; - if (rad_packet_build(reply, RA)) - goto out_err_no_reply; - dm_coa_set_RA(reply, conf_dm_coa_secret); - if (conf_verbose) { - log_debug("send "); - rad_packet_print(reply, log_debug); - } - rad_packet_send(reply, h->fd, &addr); - rad_packet_free(reply); - return 0; out_err: - reply = rad_packet_alloc(pack->code == CODE_COA_REQUEST ? CODE_COA_NAK : CODE_DISCONNECT_NAK); - rad_packet_add_int(reply, "Error-Cause", err_code); - reply->id = pack->id; - if (rad_packet_build(reply, RA)) - goto out_err_no_reply; - dm_coa_set_RA(reply, conf_dm_coa_secret); - if (conf_verbose) { - log_debug("send "); - rad_packet_print(reply, log_debug); - } - rad_packet_send(reply, h->fd, &addr); + dm_coa_send_nak(h->fd, pack, &addr, err_code); out_err_no_reply: rad_packet_free(pack); - if (reply) - rad_packet_free(reply); return 0; } diff --git a/accel-pptpd/radius/radius.c b/accel-pptpd/radius/radius.c index d709963e..3fc1171c 100644 --- a/accel-pptpd/radius/radius.c +++ b/accel-pptpd/radius/radius.c @@ -36,15 +36,22 @@ static LIST_HEAD(sessions); static pthread_rwlock_t sessions_lock = PTHREAD_RWLOCK_INITIALIZER; static struct ppp_notified_t notified; +static struct ipdb_t ipdb; void rad_proc_attrs(struct rad_req_t *req) { struct rad_attr_t *attr; list_for_each_entry(attr, &req->reply->attrs, entry) { - if (!strcmp(attr->attr->name, "Framed-IP-Address")) - req->rpd->ipaddr = attr->val.ipaddr; - else if (!strcmp(attr->attr->name, "Acct-Interim-Interval")) + if (!strcmp(attr->attr->name, "Framed-IP-Address")) { + if (!conf_gw_ip_address) + log_warn("radius: gw-ip-address not specified, cann't assign IP address...\n"); + else { + req->rpd->ipaddr.owner = &ipdb; + req->rpd->ipaddr.peer_addr = attr->val.ipaddr; + req->rpd->ipaddr.addr = inet_addr(conf_gw_ip_address); + } + } else if (!strcmp(attr->attr->name, "Acct-Interim-Interval")) req->rpd->acct_interim_interval = attr->val.integer; } } @@ -83,20 +90,13 @@ static int check(struct pwdb_t *pwdb, struct ppp_t *ppp, const char *username, i return r; } -static int get_ip(struct ppp_t *ppp, in_addr_t *addr, in_addr_t *peer_addr) +static struct ipdb_item_t *get_ip(struct ppp_t *ppp) { struct radius_pd_t *rpd = find_pd(ppp); - if (rpd->ipaddr) { - if (!conf_gw_ip_address) { - log_warn("radius: gw-ip-address not specified, cann't assign IP address...\n"); - return -1; - } - *peer_addr = rpd->ipaddr; - *addr = inet_addr(conf_gw_ip_address); - return 0; - } - return -1; + if (rpd->ipaddr.peer_addr) + return &rpd->ipaddr; + return NULL; } static void ppp_starting(struct ppp_notified_t *n, struct ppp_t *ppp) @@ -172,7 +172,7 @@ struct radius_pd_t *rad_find_session(const char *sessionid, const char *username continue; if (port_id >= 0 && port_id != rpd->ppp->unit_idx) continue; - if (ipaddr && ipaddr != rpd->ipaddr) + if (ipaddr && ipaddr != rpd->ipaddr.peer_addr) continue; pthread_mutex_lock(&rpd->lock); pthread_rwlock_unlock(&sessions_lock); @@ -201,6 +201,9 @@ struct radius_pd_t *rad_find_session_pack(struct rad_packet_t *pack) ipaddr = attr->val.ipaddr; } + if (!sessionid && !username && port_id == -1 && ipaddr == 0) + return NULL; + if (username && !sessionid) return NULL; diff --git a/accel-pptpd/radius/radius.h b/accel-pptpd/radius/radius.h index cededbe8..99cb7e42 100644 --- a/accel-pptpd/radius/radius.h +++ b/accel-pptpd/radius/radius.h @@ -7,6 +7,7 @@ #include "triton.h" #include "ppp.h" +#include "ipdb.h" #define REQ_LENGTH_MAX 4096 @@ -40,9 +41,11 @@ struct radius_pd_t struct rad_req_t *acct_req; struct triton_timer_t acct_interim_timer; + struct rad_packet_t *dm_coa_req; + struct sockaddr_in dm_coa_addr; - in_addr_t ipaddr; + struct ipdb_item_t ipaddr; int acct_interim_interval; }; diff --git a/accel-pptpd/triton/triton.c b/accel-pptpd/triton/triton.c index 4ecf0a87..742d4936 100644 --- a/accel-pptpd/triton/triton.c +++ b/accel-pptpd/triton/triton.c @@ -261,6 +261,7 @@ void __export triton_context_wakeup(struct triton_context_t *ud) ctx->sleeping = 0; r = triton_queue_ctx(ctx); spin_unlock(&ctx->lock); + if (r) triton_thread_wakeup(ctx->thread); } @@ -269,6 +270,7 @@ int __export triton_context_call(struct triton_context_t *ud, void (*func)(void { struct _triton_context_t *ctx = (struct _triton_context_t *)ud->tpd; struct _triton_ctx_call_t *call = mempool_alloc(call_pool); + int r; if (!call) return -1; @@ -278,8 +280,12 @@ int __export triton_context_call(struct triton_context_t *ud, void (*func)(void spin_lock(&ctx->lock); list_add_tail(&call->entry, &ctx->pending_calls); + r = triton_queue_ctx(ctx); spin_unlock(&ctx->lock); + if (r) + triton_thread_wakeup(ctx->thread); + return 0; } |