summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKozlov Dmitry <dima@server>2010-10-14 11:28:17 +0400
committerKozlov Dmitry <dima@server>2010-10-14 11:28:17 +0400
commit763fe9e3ba0faeea25cc423152a065900f901a53 (patch)
treed3772cac139507699746461afc16a26e20065f21
parent80e8ec99aeffcec505165f099f68d0fb2903e12b (diff)
downloadaccel-ppp-763fe9e3ba0faeea25cc423152a065900f901a53.tar.gz
accel-ppp-763fe9e3ba0faeea25cc423152a065900f901a53.zip
various bug fixed and improvements
-rw-r--r--accel-pptpd/ctrl/l2tp/l2tp.c10
-rw-r--r--accel-pptpd/ctrl/l2tp/netlink.c40
-rw-r--r--accel-pptpd/ctrl/l2tp/packet.c7
-rw-r--r--accel-pptpd/extra/shaper_tbf.c135
-rw-r--r--accel-pptpd/radius/acct.c29
-rw-r--r--accel-pptpd/radius/dm_coa.c104
-rw-r--r--accel-pptpd/radius/packet.c17
-rw-r--r--accel-pptpd/radius/radius_p.h2
-rw-r--r--accel-pptpd/radius/req.c16
-rw-r--r--accel-pptpd/triton/mempool.c64
10 files changed, 317 insertions, 107 deletions
diff --git a/accel-pptpd/ctrl/l2tp/l2tp.c b/accel-pptpd/ctrl/l2tp/l2tp.c
index 2996127..2a7687e 100644
--- a/accel-pptpd/ctrl/l2tp/l2tp.c
+++ b/accel-pptpd/ctrl/l2tp/l2tp.c
@@ -137,7 +137,7 @@ static void l2tp_disconnect(struct l2tp_conn_t *conn)
_free(conn->ctrl.calling_station_id);
_free(conn->ctrl.called_station_id);
-
+
mempool_free(conn);
}
@@ -333,6 +333,7 @@ static int l2tp_connect(struct l2tp_conn_t *conn)
pppox_addr.pppol2tp.d_tunnel = conn->peer_tid;
pppox_addr.pppol2tp.d_session = conn->peer_sid;
+ l2tp_nl_delete_tunnel(conn->tid);
l2tp_nl_create_tunnel(conn->hnd.fd, conn->tid, conn->peer_tid);
l2tp_nl_create_session(conn->tid, conn->sid, conn->peer_sid);
@@ -420,7 +421,8 @@ static int l2tp_send(struct l2tp_conn_t *conn, struct l2tp_packet_t *pack)
list_add_tail(&pack->entry, &conn->send_queue);
if (!conn->rtimeout_timer.tpd)
triton_timer_add(&conn->ctx, &conn->rtimeout_timer, 0);
- }
+ } else
+ l2tp_packet_free(pack);
return 0;
@@ -792,8 +794,6 @@ static int l2tp_conn_read(struct triton_md_handler_t *h)
struct l2tp_attr_t *msg_type;
while (1) {
- pack = NULL;
-
if (l2tp_recv(h->fd, &pack))
return 0;
@@ -923,8 +923,6 @@ static int l2tp_udp_read(struct triton_md_handler_t *h)
struct l2tp_attr_t *msg_type;
while (1) {
- pack = NULL;
-
if (l2tp_recv(h->fd, &pack))
break;
diff --git a/accel-pptpd/ctrl/l2tp/netlink.c b/accel-pptpd/ctrl/l2tp/netlink.c
index a50e9b2..0cc5b34 100644
--- a/accel-pptpd/ctrl/l2tp/netlink.c
+++ b/accel-pptpd/ctrl/l2tp/netlink.c
@@ -5,13 +5,18 @@
#include "l2tp_kernel.h"
#include "triton.h"
-static struct nl_handle *nl_sock;
static int family;
void l2tp_nl_delete_tunnel(int tid)
{
- struct nl_msg *msg = nlmsg_alloc();
+ struct nl_handle *nl_sock;
+ struct nl_msg *msg;
+ nl_sock = nl_handle_alloc();
+ msg = nlmsg_alloc();
+
+ genl_connect(nl_sock);
+
genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_REQUEST, L2TP_CMD_TUNNEL_DELETE, L2TP_GENL_VERSION);
nla_put_u32(msg, L2TP_ATTR_CONN_ID, tid);
@@ -19,15 +24,20 @@ void l2tp_nl_delete_tunnel(int tid)
nl_recvmsgs_default(nl_sock);
nlmsg_free(msg);
-
+ nl_close(nl_sock);
+ nl_handle_destroy(nl_sock);
}
void l2tp_nl_create_tunnel(int fd, int tid, int peer_tid)
{
- struct nl_msg *msg = nlmsg_alloc();
-
- l2tp_nl_delete_tunnel(tid);
+ struct nl_handle *nl_sock;
+ struct nl_msg *msg;
+
+ nl_sock = nl_handle_alloc();
+ msg = nlmsg_alloc();
+ genl_connect(nl_sock);
+
genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_REQUEST, L2TP_CMD_TUNNEL_CREATE, L2TP_GENL_VERSION);
nla_put_u16(msg, L2TP_ATTR_ENCAP_TYPE, L2TP_ENCAPTYPE_UDP);
nla_put_u8(msg, L2TP_ATTR_PROTO_VERSION, 2);
@@ -40,12 +50,20 @@ void l2tp_nl_create_tunnel(int fd, int tid, int peer_tid)
nl_recvmsgs_default(nl_sock);
nlmsg_free(msg);
+ nl_close(nl_sock);
+ nl_handle_destroy(nl_sock);
}
void l2tp_nl_create_session(int tid, int sid, int peer_sid)
{
- struct nl_msg *msg = nlmsg_alloc();
+ struct nl_handle *nl_sock;
+ struct nl_msg *msg;
+
+ nl_sock = nl_handle_alloc();
+ msg = nlmsg_alloc();
+ genl_connect(nl_sock);
+
genlmsg_put(msg, NL_AUTO_PID, NL_AUTO_SEQ, family, 0, NLM_F_REQUEST, L2TP_CMD_SESSION_CREATE, L2TP_GENL_VERSION);
nla_put_u32(msg, L2TP_ATTR_CONN_ID, tid);
nla_put_u32(msg, L2TP_ATTR_SESSION_ID, sid);
@@ -58,13 +76,19 @@ void l2tp_nl_create_session(int tid, int sid, int peer_sid)
nl_recvmsgs_default(nl_sock);
nlmsg_free(msg);
+ nl_close(nl_sock);
+ nl_handle_destroy(nl_sock);
}
static void __init init(void)
{
- nl_sock = nl_handle_alloc();
+ struct nl_handle *nl_sock = nl_handle_alloc();
genl_connect(nl_sock);
family = genl_ctrl_resolve(nl_sock, L2TP_GENL_NAME);
+
+ nl_close(nl_sock);
+ nl_handle_destroy(nl_sock);
}
+
diff --git a/accel-pptpd/ctrl/l2tp/packet.c b/accel-pptpd/ctrl/l2tp/packet.c
index c127619..2f1b60f 100644
--- a/accel-pptpd/ctrl/l2tp/packet.c
+++ b/accel-pptpd/ctrl/l2tp/packet.c
@@ -107,6 +107,8 @@ int l2tp_recv(int fd, struct l2tp_packet_t **p)
struct sockaddr_in addr;
socklen_t len = sizeof(addr);
+ *p = NULL;
+
if (!buf) {
log_emerg("l2tp: out of memory\n");
return 0;
@@ -115,10 +117,9 @@ int l2tp_recv(int fd, struct l2tp_packet_t **p)
n = recvfrom(fd, buf, L2TP_MAX_PACKET_SIZE, 0, &addr, &len);
if (n < 0) {
- if (errno == EAGAIN) {
- mempool_free(buf);
+ mempool_free(buf);
+ if (errno == EAGAIN)
return -1;
- }
log_error("l2tp: recv: %s\n", strerror(errno));
return 0;
}
diff --git a/accel-pptpd/extra/shaper_tbf.c b/accel-pptpd/extra/shaper_tbf.c
index 07168d5..7ed68f5 100644
--- a/accel-pptpd/extra/shaper_tbf.c
+++ b/accel-pptpd/extra/shaper_tbf.c
@@ -21,10 +21,11 @@
#include "radius.h"
#include "log.h"
#include "ppp.h"
+#include "memdebug.h"
#define TIME_UNITS_PER_SEC 1000000
-//static int conf_verbose = 0;
+static int conf_verbose = 0;
static int conf_attr_down = 11; //Filter-Id
static int conf_attr_up = 11; //Filter-Id
static double conf_burst_factor = 0.1;
@@ -34,6 +35,15 @@ static int conf_mpu = 0;
static double tick_in_usec = 1;
static double clock_factor = 1;
+struct shaper_pd_t
+{
+ struct ppp_pd_t pd;
+ int down_speed;
+ int up_speed;
+};
+
+static void *pd_key;
+
static unsigned tc_time2tick(unsigned time)
{
return time*tick_in_usec;
@@ -311,7 +321,7 @@ nla_put_failure:
}
-static void install_shaper(const char *ifname, int down_speed, int up_speed)
+static int install_shaper(const char *ifname, int down_speed, int up_speed)
{
struct nl_handle *h;
struct ifreq ifr;
@@ -322,13 +332,13 @@ static void install_shaper(const char *ifname, int down_speed, int up_speed)
if (ioctl(sock_fd, SIOCGIFINDEX, &ifr)) {
log_ppp_error("tbf: ioctl(SIOCGIFINDEX)", strerror(errno));
- return;
+ return -1;
}
h = nl_handle_alloc();
if (!h) {
log_ppp_error("tbf: nl_handle_alloc failed\n");
- return;
+ return -1;
}
err = nl_connect(h, NETLINK_ROUTE);
@@ -338,19 +348,52 @@ static void install_shaper(const char *ifname, int down_speed, int up_speed)
}
if (down_speed)
- install_tbf(h, ifr.ifr_ifindex, down_speed);
+ if (install_tbf(h, ifr.ifr_ifindex, down_speed))
+ return -1;
if (up_speed) {
- install_ingress(h, ifr.ifr_ifindex);
- install_filter(h, ifr.ifr_ifindex, up_speed);
+ if (install_ingress(h, ifr.ifr_ifindex))
+ return -1;
+ if (install_filter(h, ifr.ifr_ifindex, up_speed))
+ return -1;
}
nl_close(h);
out:
nl_handle_destroy(h);
+
+ return 0;
+}
+
+static struct shaper_pd_t *find_pd(struct ppp_t *ppp, int create)
+{
+ struct ppp_pd_t *pd;
+ struct shaper_pd_t *spd;
+
+ list_for_each_entry(pd, &ppp->pd_list, entry) {
+ if (pd->key == &pd_key) {
+ spd = container_of(pd, typeof(*spd), pd);
+ return spd;
+ }
+ }
+
+ if (create) {
+ spd = _malloc(sizeof(*spd));
+ if (!spd) {
+ log_emerg("tbf: out of memory\n");
+ return NULL;
+ }
+
+ memset(spd, 0, sizeof(*spd));
+ list_add_tail(&spd->pd.entry, &ppp->pd_list);
+ spd->pd.key = &pd_key;
+ return spd;
+ }
+
+ return NULL;
}
-static void remove_shaper(const char *ifname)
+static int remove_shaper(const char *ifname)
{
struct nl_handle *h;
struct ifreq ifr;
@@ -362,7 +405,7 @@ static void remove_shaper(const char *ifname)
if (ioctl(sock_fd, SIOCGIFINDEX, &ifr)) {
log_ppp_error("tbf: ioctl(SIOCGIFINDEX)", strerror(errno));
- return;
+ return -1;
}
struct tcmsg tchdr1 = {
@@ -382,13 +425,14 @@ static void remove_shaper(const char *ifname)
h = nl_handle_alloc();
if (!h) {
log_ppp_error("tbf: nl_handle_alloc failed\n");
- return;
+ return -1;
}
err = nl_connect(h, NETLINK_ROUTE);
if (err < 0) {
log_ppp_error("tbf: nl_connect: %s", strerror(errno));
- goto out;
+ nl_handle_destroy(h);
+ return -1;
}
pmsg = nlmsg_alloc_simple(RTM_DELQDISC, NLM_F_CREATE | NLM_F_REPLACE);
@@ -422,18 +466,20 @@ static void remove_shaper(const char *ifname)
nlmsg_free(pmsg);
nl_close(h);
-out:
nl_handle_destroy(h);
- return;
+ return 0;
out_err:
log_ppp_error("tbf: failed to remove shaper\n");
- nlmsg_free(pmsg);
+ if (pmsg)
+ nlmsg_free(pmsg);
+
nl_close(h);
nl_handle_destroy(h);
-}
+ return -1;
+}
static int parse_attr(struct rad_attr_t *attr)
{
@@ -450,6 +496,10 @@ static void ev_radius_access_accept(struct ev_radius_t *ev)
struct rad_attr_t *attr;
int down_speed = 0;
int up_speed = 0;
+ struct shaper_pd_t *pd = find_pd(ev->ppp, 1);
+
+ if (!pd)
+ return;
list_for_each_entry(attr, &ev->reply->attrs, entry) {
if (attr->attr->id == conf_attr_down)
@@ -458,8 +508,14 @@ static void ev_radius_access_accept(struct ev_radius_t *ev)
up_speed = parse_attr(attr);
}
- if (down_speed > 0 && up_speed > 0)
- install_shaper(ev->ppp->ifname, down_speed, up_speed);
+ if (down_speed > 0 && up_speed > 0) {
+ pd->down_speed = down_speed;
+ pd->up_speed = up_speed;
+ if (!install_shaper(ev->ppp->ifname, down_speed, up_speed)) {
+ if (conf_verbose)
+ log_ppp_info("tbf: installed shaper %i/%i (Kbit)\n", down_speed, up_speed);
+ }
+ }
}
static void ev_radius_coa(struct ev_radius_t *ev)
@@ -467,6 +523,12 @@ static void ev_radius_coa(struct ev_radius_t *ev)
struct rad_attr_t *attr;
int down_speed = 0;
int up_speed = 0;
+ struct shaper_pd_t *pd = find_pd(ev->ppp, 1);
+
+ if (!pd) {
+ ev->res = -1;
+ return;
+ }
list_for_each_entry(attr, &ev->request->attrs, entry) {
if (attr->attr->id == conf_attr_down)
@@ -475,10 +537,38 @@ static void ev_radius_coa(struct ev_radius_t *ev)
up_speed = parse_attr(attr);
}
- remove_shaper(ev->ppp->ifname);
+ if (pd->down_speed != down_speed || pd->up_speed != up_speed) {
+ pd->down_speed = down_speed;
+ pd->up_speed = up_speed;
+
+ if (remove_shaper(ev->ppp->ifname)) {
+ ev->res = -1;
+ return;
+ }
+
+ if (down_speed > 0 || up_speed > 0) {
+ if (install_shaper(ev->ppp->ifname, down_speed, up_speed)) {
+ ev->res= -1;
+ return;
+ } else {
+ if (conf_verbose)
+ log_ppp_info("tbf: changed shaper %i/%i (Kbit)\n", down_speed, up_speed);
+ }
+ } else {
+ if (conf_verbose)
+ log_ppp_info("tbf: removed shaper\n");
+ }
+ }
+}
- if (down_speed > 0 && up_speed > 0)
- install_shaper(ev->ppp->ifname, down_speed, up_speed);
+static void ev_ctrl_finished(struct ppp_t *ppp)
+{
+ struct shaper_pd_t *pd = find_pd(ppp, 0);
+
+ if (pd) {
+ list_del(&pd->pd.entry);
+ _free(pd);
+ }
}
static int clock_init(void)
@@ -560,6 +650,10 @@ static void __init init(void)
if (opt && atoi(opt) >= 0)
conf_mpu = atoi(opt);
+ opt = conf_get_opt("tbf", "verbose");
+ if (opt && atoi(opt) > 0)
+ conf_verbose = 1;
+
if (conf_attr_up <= 0 || conf_attr_down <= 0) {
log_emerg("tbf: incorrect attribute(s), tbf disabled...\n");
return;
@@ -567,5 +661,6 @@ static void __init init(void)
triton_event_register_handler(EV_RADIUS_ACCESS_ACCEPT, (triton_event_func)ev_radius_access_accept);
triton_event_register_handler(EV_RADIUS_COA, (triton_event_func)ev_radius_coa);
+ triton_event_register_handler(EV_CTRL_FINISHED, (triton_event_func)ev_ctrl_finished);
}
diff --git a/accel-pptpd/radius/acct.c b/accel-pptpd/radius/acct.c
index d855d12..f612702 100644
--- a/accel-pptpd/radius/acct.c
+++ b/accel-pptpd/radius/acct.c
@@ -64,19 +64,34 @@ static void req_set_stat(struct rad_req_t *req, struct ppp_t *ppp)
static int rad_acct_read(struct triton_md_handler_t *h)
{
struct rad_req_t *req = container_of(h, typeof(*req), hnd);
+ struct rad_packet_t *pack;
+ int r;
- if (req->reply)
+ if (req->reply) {
rad_packet_free(req->reply);
+ req->reply = NULL;
+ }
- req->reply = rad_packet_recv(h->fd, NULL);
- if (!req->reply)
- return 0;
+ while (1) {
+ r = rad_packet_recv(h->fd, &pack, NULL);
+
+ if (pack) {
+ if (req->reply)
+ rad_packet_free(req->reply);
+ req->reply = pack;
+ if (conf_verbose) {
+ log_ppp_info("recv ");
+ rad_packet_print(req->reply, log_ppp_info);
+ }
+ }
- if (conf_verbose) {
- log_ppp_info("recv ");
- rad_packet_print(req->reply, log_ppp_info);
+ if (r)
+ break;
}
+ if (!req->reply)
+ return 0;
+
if (req->reply->code != CODE_ACCOUNTING_RESPONSE || req->reply->id != req->pack->id) {
rad_packet_free(req->reply);
req->reply = NULL;
diff --git a/accel-pptpd/radius/dm_coa.c b/accel-pptpd/radius/dm_coa.c
index 64fe97a..2fb023c 100644
--- a/accel-pptpd/radius/dm_coa.c
+++ b/accel-pptpd/radius/dm_coa.c
@@ -172,62 +172,64 @@ static int dm_coa_read(struct triton_md_handler_t *h)
int err_code;
struct sockaddr_in addr;
+ while (1) {
+ if (rad_packet_recv(h->fd, &pack, &addr))
+ return 0;
+
+ if (!pack)
+ continue;
+
+ if (pack->code != CODE_DISCONNECT_REQUEST && pack->code != CODE_COA_REQUEST) {
+ log_warn("radius:dm_coa: unexpected code (%i) received\n", pack->code);
+ goto out_err_no_reply;
+ }
+
+ if (dm_coa_check_RA(pack, conf_dm_coa_secret)) {
+ log_warn("radius:dm_coa: RA validation failed\n");
+ goto out_err_no_reply;
+ }
+
+ if (conf_verbose) {
+ log_debug("recv ");
+ rad_packet_print(pack, log_debug);
+ }
+
+ if (rad_check_nas_pack(pack)) {
+ log_warn("radius:dm_coa: NAS identification failed\n");
+ err_code = 403;
+ goto out_err;
+ }
+
+ rpd = rad_find_session_pack(pack);
+ if (!rpd) {
+ log_warn("radius:dm_coa: session not found\n");
+ err_code = 503;
+ goto out_err;
+ }
+
+ if (rpd->dm_coa_req) {
+ pthread_mutex_unlock(&rpd->lock);
+ goto out_err_no_reply;
+ }
+
+ 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);
+ else
+ triton_context_call(rpd->ppp->ctrl->ctx, (void (*)(void *))coa_request, rpd);
- pack = rad_packet_recv(h->fd, &addr);
- if (!pack)
- return 0;
-
- if (pack->code != CODE_DISCONNECT_REQUEST && pack->code != CODE_COA_REQUEST) {
- log_warn("radius:dm_coa: unexpected code (%i) received\n", pack->code);
- goto out_err_no_reply;
- }
-
- if (dm_coa_check_RA(pack, conf_dm_coa_secret)) {
- log_warn("radius:dm_coa: RA validation failed\n");
- goto out_err_no_reply;
- }
-
- if (conf_verbose) {
- log_debug("recv ");
- rad_packet_print(pack, log_debug);
- }
-
- if (rad_check_nas_pack(pack)) {
- log_warn("radius:dm_coa: NAS identification failed\n");
- err_code = 403;
- goto out_err;
- }
-
- rpd = rad_find_session_pack(pack);
- if (!rpd) {
- log_warn("radius:dm_coa: session not found\n");
- err_code = 503;
- goto out_err;
- }
-
- if (rpd->dm_coa_req) {
pthread_mutex_unlock(&rpd->lock);
- goto out_err_no_reply;
- }
-
- 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);
- else
- triton_context_call(rpd->ppp->ctrl->ctx, (void (*)(void *))coa_request, rpd);
- pthread_mutex_unlock(&rpd->lock);
-
- return 0;
+ continue;
-out_err:
- dm_coa_send_nak(h->fd, pack, &addr, err_code);
+ out_err:
+ dm_coa_send_nak(h->fd, pack, &addr, err_code);
-out_err_no_reply:
- rad_packet_free(pack);
- return 0;
+ out_err_no_reply:
+ rad_packet_free(pack);
+ }
}
static void dm_coa_close(struct triton_context_t *ctx)
diff --git a/accel-pptpd/radius/packet.c b/accel-pptpd/radius/packet.c
index e3d4cfc..0277e5f 100644
--- a/accel-pptpd/radius/packet.c
+++ b/accel-pptpd/radius/packet.c
@@ -97,7 +97,7 @@ int rad_packet_build(struct rad_packet_t *pack, uint8_t *RA)
return 0;
}
-struct rad_packet_t *rad_packet_recv(int fd, struct sockaddr_in *addr)
+int rad_packet_recv(int fd, struct rad_packet_t **p, struct sockaddr_in *addr)
{
struct rad_packet_t *pack;
struct rad_attr_t *attr;
@@ -107,9 +107,11 @@ struct rad_packet_t *rad_packet_recv(int fd, struct sockaddr_in *addr)
int n, id, len, vendor_id;
socklen_t addr_len = sizeof(*addr);
+ *p = NULL;
+
pack = rad_packet_alloc(0);
if (!pack)
- return NULL;
+ return 0;
pack->buf = _malloc(REQ_LENGTH_MAX);
if (!pack->buf) {
@@ -123,8 +125,9 @@ struct rad_packet_t *rad_packet_recv(int fd, struct sockaddr_in *addr)
else
n = read(fd, pack->buf, REQ_LENGTH_MAX);
if (n < 0) {
- if (errno == EINTR)
- continue;
+ rad_packet_free(pack);
+ if (errno == EAGAIN)
+ return -1;
log_ppp_error("radius:packet:read: %s\n", strerror(errno));
goto out_err;
}
@@ -219,11 +222,13 @@ struct rad_packet_t *rad_packet_recv(int fd, struct sockaddr_in *addr)
n -= 2 + len;
}
- return pack;
+ *p = pack;
+
+ return 0;
out_err:
rad_packet_free(pack);
- return NULL;
+ return 0;
}
void rad_packet_free(struct rad_packet_t *pack)
diff --git a/accel-pptpd/radius/radius_p.h b/accel-pptpd/radius/radius_p.h
index 9537641..e7b6216 100644
--- a/accel-pptpd/radius/radius_p.h
+++ b/accel-pptpd/radius/radius_p.h
@@ -86,7 +86,7 @@ void rad_acct_stop(struct radius_pd_t *rpd);
struct rad_packet_t *rad_packet_alloc(int code);
int rad_packet_build(struct rad_packet_t *pack, uint8_t *RA);
-struct rad_packet_t *rad_packet_recv(int fd, struct sockaddr_in *addr);
+int rad_packet_recv(int fd, struct rad_packet_t **, struct sockaddr_in *addr);
void rad_packet_free(struct rad_packet_t *);
void rad_packet_print(struct rad_packet_t *pack, void (*print)(const char *fmt, ...));
int rad_packet_send(struct rad_packet_t *pck, int fd, struct sockaddr_in *addr);
diff --git a/accel-pptpd/radius/req.c b/accel-pptpd/radius/req.c
index f3f4138..5b1261f 100644
--- a/accel-pptpd/radius/req.c
+++ b/accel-pptpd/radius/req.c
@@ -196,8 +196,22 @@ static void req_wakeup(struct rad_req_t *req)
static int rad_req_read(struct triton_md_handler_t *h)
{
struct rad_req_t *req = container_of(h, typeof(*req), hnd);
+ struct rad_packet_t *pack;
+ int r;
+
+ while (1) {
+ r = rad_packet_recv(h->fd, &pack, NULL);
+
+ if (pack) {
+ if (req->reply)
+ rad_packet_free(req->reply);
+ req->reply = pack;
+ }
+
+ if (r)
+ break;
+ }
- req->reply = rad_packet_recv(h->fd, NULL);
req_wakeup(req);
return 0;
diff --git a/accel-pptpd/triton/mempool.c b/accel-pptpd/triton/mempool.c
index c96c3ba..bd951b4 100644
--- a/accel-pptpd/triton/mempool.c
+++ b/accel-pptpd/triton/mempool.c
@@ -14,6 +14,9 @@ struct _mempool_t
struct list_head entry;
int size;
struct list_head items;
+#ifdef MEMDEBUG
+ struct list_head ditems;
+#endif
spinlock_t lock;
uint64_t magic;
};
@@ -22,6 +25,10 @@ struct _item_t
{
struct _mempool_t *owner;
struct list_head entry;
+#ifdef MEMDEBUG
+ const char *fname;
+ int line;
+#endif
uint64_t magic2;
uint64_t magic1;
char ptr[0];
@@ -30,12 +37,15 @@ struct _item_t
static LIST_HEAD(pools);
static spinlock_t pools_lock = SPINLOCK_INITIALIZER;
-__export mempool_t *mempool_create(int size)
+mempool_t __export *mempool_create(int size)
{
struct _mempool_t *p = _malloc(sizeof(*p));
memset(p, 0, sizeof(*p));
INIT_LIST_HEAD(&p->items);
+#ifdef MEMDEBUG
+ INIT_LIST_HEAD(&p->ditems);
+#endif
spinlock_init(&p->lock);
p->size = size;
p->magic = (uint64_t)random() * (uint64_t)random();
@@ -48,7 +58,7 @@ __export mempool_t *mempool_create(int size)
}
#ifndef MEMDEBUG
-__export void *mempool_alloc(mempool_t *pool)
+void __export *mempool_alloc(mempool_t *pool)
{
struct _mempool_t *p = (struct _mempool_t *)pool;
struct _item_t *it;
@@ -94,7 +104,11 @@ void __export *mempool_alloc_md(mempool_t *pool, const char *fname, int line)
if (!list_empty(&p->items)) {
it = list_entry(p->items.next, typeof(*it), entry);
list_del(&it->entry);
+ list_add(&it->entry, &p->ditems);
spin_unlock(&p->lock);
+
+ it->fname = fname;
+ it->line = line;
__sync_fetch_and_sub(&triton_stat.mempool_available, size);
@@ -112,19 +126,26 @@ void __export *mempool_alloc_md(mempool_t *pool, const char *fname, int line)
it->owner = p;
it->magic2 = p->magic;
it->magic1 = MAGIC1;
+ it->fname = fname;
+ it->line = line;
*(uint64_t*)(it->ptr + p->size) = it->magic2;
+ spin_lock(&p->lock);
+ list_add(&it->entry, &p->ditems);
+ spin_unlock(&p->lock);
+
__sync_fetch_and_add(&triton_stat.mempool_allocated, size);
return it->ptr;
}
-__export void mempool_free(void *ptr)
+void __export mempool_free(void *ptr)
{
struct _item_t *it = container_of(ptr, typeof(*it), ptr);
uint32_t size = sizeof(*it) + it->owner->size + 8;
+#ifdef MEMDEBUG
if (it->magic1 != MAGIC1) {
triton_log_error("mempool: memory corruption detected");
abort();
@@ -141,14 +162,48 @@ __export void mempool_free(void *ptr)
}
it->magic1 = 0;
+#endif
spin_lock(&it->owner->lock);
+#ifdef MEMDEBUG
+ list_del(&it->entry);
+#endif
list_add_tail(&it->entry,&it->owner->items);
spin_unlock(&it->owner->lock);
__sync_fetch_and_add(&triton_stat.mempool_available, size);
}
+void __export mempool_clean(mempool_t *pool)
+{
+ struct _mempool_t *p = (struct _mempool_t *)pool;
+ struct _item_t *it;
+ uint32_t size = sizeof(*it) + p->size + 8;
+
+ spin_lock(&p->lock);
+ while (!list_empty(&p->items)) {
+ it = list_entry(p->items.next, typeof(*it), entry);
+ list_del(&it->entry);
+ _free(it);
+ __sync_fetch_and_sub(&triton_stat.mempool_allocated, size);
+ __sync_fetch_and_sub(&triton_stat.mempool_available, size);
+ }
+ spin_unlock(&p->lock);
+}
+
+#ifdef MEMDEBUG
+void __export mempool_show(mempool_t *pool)
+{
+ struct _mempool_t *p = (struct _mempool_t *)pool;
+ struct _item_t *it;
+
+ spin_lock(&p->lock);
+ list_for_each_entry(it, &p->ditems, entry)
+ triton_log_error("%s:%i %p\n", it->fname, it->line, it->ptr);
+ spin_unlock(&p->lock);
+}
+#endif
+
void sigclean(int num)
{
struct _mempool_t *p;
@@ -159,7 +214,7 @@ void sigclean(int num)
spin_lock(&pools_lock);
list_for_each_entry(p, &pools, entry) {
- size = sizeof(*it) + p->size;
+ size = sizeof(*it) + p->size + 8;
spin_lock(&p->lock);
while (!list_empty(&p->items)) {
it = list_entry(p->items.next, typeof(*it), entry);
@@ -177,3 +232,4 @@ static void __init init(void)
{
signal(35, sigclean);
}
+