summaryrefslogtreecommitdiff
path: root/accel-pptpd
diff options
context:
space:
mode:
authorKozlov Dmitry <dima@server>2010-09-10 11:58:34 +0400
committerKozlov Dmitry <dima@server>2010-09-10 11:58:34 +0400
commitc471cd62571f654b92bad0bd9f431927758f4d45 (patch)
tree8f08d11522ae9b3d0e2c44d04746ca0f0e5ed22c /accel-pptpd
parent35d38d2c3f3db22216d43604b8750ecb6089e525 (diff)
downloadaccel-ppp-c471cd62571f654b92bad0bd9f431927758f4d45.tar.gz
accel-ppp-c471cd62571f654b92bad0bd9f431927758f4d45.zip
ippool: implemented module ippool which gives IP address from configurable ranges
Diffstat (limited to 'accel-pptpd')
-rw-r--r--accel-pptpd/CMakeLists.txt1
-rw-r--r--accel-pptpd/accel-pptpd.conf4
-rw-r--r--accel-pptpd/ipdb.c23
-rw-r--r--accel-pptpd/ipdb.h15
-rw-r--r--accel-pptpd/ippool.c209
-rw-r--r--accel-pptpd/iprange.c2
-rw-r--r--accel-pptpd/ppp/ipcp_opt_ipaddr.c48
-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.c33
-rw-r--r--accel-pptpd/radius/radius.h5
-rw-r--r--accel-pptpd/triton/triton.c6
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;
}