summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2014-09-20 12:18:49 +0400
committerDmitry Kozlov <xeb@mail.ru>2014-09-20 12:18:49 +0400
commit62e89248160d3592c2d754fcaa15e37586a5b091 (patch)
treea6513cfd1e8ef6c6079ea2436e8573b122cc1ec6
parent0a58c20b44136c1fba996becea18696b3f67a1f9 (diff)
downloadaccel-ppp-62e89248160d3592c2d754fcaa15e37586a5b091.tar.gz
accel-ppp-62e89248160d3592c2d754fcaa15e37586a5b091.zip
rewrite of authentication/accounting procedures
This patch gets rid of synchronuos style of authentication/accounting. Synchronous style of authentication/accounting produced sleeping threads which becomes a problem when lots of sessions started/stopped and all they want authorization/accounting.
-rw-r--r--accel-pppd/auth/auth_chap_md5.c101
-rw-r--r--accel-pppd/auth/auth_mschap_v1.c126
-rw-r--r--accel-pppd/auth/auth_mschap_v2.c142
-rw-r--r--accel-pppd/auth/auth_pap.c91
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.c96
-rw-r--r--accel-pppd/ctrl/ipoe/ipoe.h1
-rw-r--r--accel-pppd/ctrl/pppoe/pppoe.c4
-rw-r--r--accel-pppd/extra/chap-secrets.c2
-rw-r--r--accel-pppd/ifcfg.c19
-rw-r--r--accel-pppd/include/ap_session.h2
-rw-r--r--accel-pppd/ppp/ppp.c6
-rw-r--r--accel-pppd/pwdb.c6
-rw-r--r--accel-pppd/pwdb.h12
-rw-r--r--accel-pppd/radius/acct.c654
-rw-r--r--accel-pppd/radius/auth.c492
-rw-r--r--accel-pppd/radius/packet.c11
-rw-r--r--accel-pppd/radius/radius.c70
-rw-r--r--accel-pppd/radius/radius_p.h47
-rw-r--r--accel-pppd/radius/req.c173
-rw-r--r--accel-pppd/radius/serv.c205
-rw-r--r--accel-pppd/session.c2
-rw-r--r--accel-pppd/triton/mempool.c80
-rw-r--r--accel-pppd/triton/mempool.h7
-rw-r--r--accel-pppd/triton/triton.c4
24 files changed, 1299 insertions, 1054 deletions
diff --git a/accel-pppd/auth/auth_chap_md5.c b/accel-pppd/auth/auth_chap_md5.c
index 9a52581c..5be8b875 100644
--- a/accel-pppd/auth/auth_chap_md5.c
+++ b/accel-pppd/auth/auth_chap_md5.c
@@ -30,39 +30,39 @@
#define MSG_FAILURE "Authentication failed"
#define MSG_SUCCESS "Authentication succeeded"
-#define HDR_LEN (sizeof(struct chap_hdr_t)-2)
+#define HDR_LEN (sizeof(struct chap_hdr)-2)
static int conf_timeout = 5;
static int conf_interval = 0;
static int conf_max_failure = 3;
static int conf_any_login = 0;
-struct chap_hdr_t {
+struct chap_hdr {
uint16_t proto;
uint8_t code;
uint8_t id;
uint16_t len;
} __attribute__((packed));
-struct chap_challenge_t {
- struct chap_hdr_t hdr;
+struct chap_challenge {
+ struct chap_hdr hdr;
uint8_t val_size;
uint8_t val[VALUE_SIZE];
char name[0];
} __attribute__((packed));
-struct chap_failure_t {
- struct chap_hdr_t hdr;
+struct chap_failure {
+ struct chap_hdr hdr;
char message[sizeof(MSG_FAILURE)];
} __attribute__((packed));
-struct chap_success_t {
- struct chap_hdr_t hdr;
+struct chap_success {
+ struct chap_hdr hdr;
char message[sizeof(MSG_SUCCESS)];
} __attribute__((packed));
-struct chap_auth_data_t {
+struct chap_auth_data {
struct auth_data_t auth;
struct ppp_handler_t h;
struct ppp_t *ppp;
@@ -71,10 +71,12 @@ struct chap_auth_data_t {
struct triton_timer_t timeout;
struct triton_timer_t interval;
int failure;
+ char *name;
+ char *mschap_error;
int started:1;
};
-static void chap_send_challenge(struct chap_auth_data_t *ad, int new);
+static void chap_send_challenge(struct chap_auth_data *ad, int new);
static void chap_recv(struct ppp_handler_t *h);
static void chap_timeout_timer(struct triton_timer_t *t);
static void chap_restart_timer(struct triton_timer_t *t);
@@ -94,7 +96,7 @@ static void print_str(const char *buf, int size)
static struct auth_data_t* auth_data_init(struct ppp_t *ppp)
{
- struct chap_auth_data_t *d = _malloc(sizeof(*d));
+ struct chap_auth_data *d = _malloc(sizeof(*d));
memset(d, 0, sizeof(*d));
d->auth.proto = PPP_CHAP;
@@ -105,7 +107,7 @@ static struct auth_data_t* auth_data_init(struct ppp_t *ppp)
static void auth_data_free(struct ppp_t *ppp, struct auth_data_t *auth)
{
- struct chap_auth_data_t *d = container_of(auth, typeof(*d), auth);
+ struct chap_auth_data *d = container_of(auth, typeof(*d), auth);
if (d->timeout.tpd)
triton_timer_del(&d->timeout);
@@ -118,7 +120,7 @@ static void auth_data_free(struct ppp_t *ppp, struct auth_data_t *auth)
static int chap_start(struct ppp_t *ppp, struct auth_data_t *auth)
{
- struct chap_auth_data_t *d = container_of(auth, typeof(*d), auth);
+ struct chap_auth_data *d = container_of(auth, typeof(*d), auth);
d->h.proto = PPP_CHAP;
d->h.recv = chap_recv;
@@ -127,6 +129,7 @@ static int chap_start(struct ppp_t *ppp, struct auth_data_t *auth)
d->interval.expire = chap_restart_timer;
d->interval.period = conf_interval * 1000;
d->id = 1;
+ d->name = NULL;
ppp_register_chan_handler(ppp, &d->h);
@@ -137,13 +140,16 @@ static int chap_start(struct ppp_t *ppp, struct auth_data_t *auth)
static int chap_finish(struct ppp_t *ppp, struct auth_data_t *auth)
{
- struct chap_auth_data_t *d = container_of(auth, typeof(*d), auth);
+ struct chap_auth_data *d = container_of(auth, typeof(*d), auth);
if (d->timeout.tpd)
triton_timer_del(&d->timeout);
if (d->interval.tpd)
triton_timer_del(&d->interval);
+
+ if (d->name)
+ _free(d->name);
ppp_unregister_handler(ppp, &d->h);
@@ -152,7 +158,7 @@ static int chap_finish(struct ppp_t *ppp, struct auth_data_t *auth)
static void chap_timeout_timer(struct triton_timer_t *t)
{
- struct chap_auth_data_t *d = container_of(t, typeof(*d), timeout);
+ struct chap_auth_data *d = container_of(t, typeof(*d), timeout);
if (conf_ppp_verbose)
log_ppp_warn("chap-md5: timeout\n");
@@ -168,7 +174,7 @@ static void chap_timeout_timer(struct triton_timer_t *t)
static void chap_restart_timer(struct triton_timer_t *t)
{
- struct chap_auth_data_t *d = container_of(t, typeof(*d), interval);
+ struct chap_auth_data *d = container_of(t, typeof(*d), interval);
chap_send_challenge(d, 1);
}
@@ -186,9 +192,9 @@ static int lcp_recv_conf_req(struct ppp_t *ppp, struct auth_data_t *d, uint8_t *
return LCP_OPT_NAK;
}
-static void chap_send_failure(struct chap_auth_data_t *ad)
+static void chap_send_failure(struct chap_auth_data *ad)
{
- struct chap_failure_t msg = {
+ struct chap_failure msg = {
.hdr.proto = htons(PPP_CHAP),
.hdr.code = CHAP_FAILURE,
.hdr.id = ad->id,
@@ -202,9 +208,9 @@ static void chap_send_failure(struct chap_auth_data_t *ad)
ppp_chan_send(ad->ppp, &msg, ntohs(msg.hdr.len) + 2);
}
-static void chap_send_success(struct chap_auth_data_t *ad, int id)
+static void chap_send_success(struct chap_auth_data *ad, int id)
{
- struct chap_success_t msg = {
+ struct chap_success msg = {
.hdr.proto = htons(PPP_CHAP),
.hdr.code = CHAP_SUCCESS,
.hdr.id = id,
@@ -218,9 +224,9 @@ static void chap_send_success(struct chap_auth_data_t *ad, int id)
ppp_chan_send(ad->ppp, &msg, ntohs(msg.hdr.len) + 2);
}
-static void chap_send_challenge(struct chap_auth_data_t *ad, int new)
+static void chap_send_challenge(struct chap_auth_data *ad, int new)
{
- struct chap_challenge_t msg = {
+ struct chap_challenge msg = {
.hdr.proto = htons(PPP_CHAP),
.hdr.code = CHAP_CHALLENGE,
.hdr.id = ad->id,
@@ -245,14 +251,45 @@ static void chap_send_challenge(struct chap_auth_data_t *ad, int new)
triton_timer_add(ad->ppp->ses.ctrl->ctx, &ad->timeout, 0);
}
-static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *hdr)
+static void auth_result(struct chap_auth_data *ad, int res)
+{
+ char *name = ad->name;
+
+ ad->name = NULL;
+
+ if (res == PWDB_DENIED) {
+ chap_send_failure(ad);
+ if (ad->started)
+ ap_session_terminate(&ad->ppp->ses, TERM_AUTH_ERROR, 0);
+ else
+ ppp_auth_failed(ad->ppp, name);
+ } else {
+ if (ppp_auth_succeeded(ad->ppp, name)) {
+ chap_send_failure(ad);
+ ap_session_terminate(&ad->ppp->ses, TERM_AUTH_ERROR, 0);
+ } else {
+ chap_send_success(ad, ad->id);
+ ad->started = 1;
+ if (conf_interval)
+ triton_timer_add(ad->ppp->ses.ctrl->ctx, &ad->interval, 0);
+ name = NULL;
+ }
+ }
+
+ ad->id++;
+
+ if (name)
+ _free(name);
+}
+
+static void chap_recv_response(struct chap_auth_data *ad, struct chap_hdr *hdr)
{
MD5_CTX md5_ctx;
uint8_t md5[MD5_DIGEST_LENGTH];
char *passwd;
char *name;
int r;
- struct chap_challenge_t *msg = (struct chap_challenge_t*)hdr;
+ struct chap_challenge *msg = (struct chap_challenge*)hdr;
if (ad->timeout.tpd)
triton_timer_del(&ad->timeout);
@@ -270,6 +307,9 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
return;
}
+ if (ad->name)
+ return;
+
if (msg->hdr.id != ad->id) {
if (conf_ppp_verbose)
log_ppp_warn("chap-md5: id mismatch\n");
@@ -301,7 +341,12 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
return;
}
- r = pwdb_check(&ad->ppp->ses, name, PPP_CHAP, CHAP_MD5, ad->id, ad->val, VALUE_SIZE, msg->val);
+ r = pwdb_check(&ad->ppp->ses, (pwdb_callback)auth_result, ad, name, PPP_CHAP, CHAP_MD5, ad->id, ad->val, VALUE_SIZE, msg->val);
+
+ if (r == PWDB_WAIT) {
+ ad->name = name;
+ return;
+ }
if (r == PWDB_NO_IMPL) {
passwd = pwdb_get_passwd(&ad->ppp->ses, name);
@@ -383,7 +428,7 @@ static int chap_check(uint8_t *ptr)
static int chap_restart(struct ppp_t *ppp, struct auth_data_t *auth)
{
- struct chap_auth_data_t *d = container_of(auth, typeof(*d), auth);
+ struct chap_auth_data *d = container_of(auth, typeof(*d), auth);
chap_send_challenge(d, 1);
@@ -405,8 +450,8 @@ static struct ppp_auth_handler_t chap=
static void chap_recv(struct ppp_handler_t *h)
{
- struct chap_auth_data_t *d = container_of(h, typeof(*d), h);
- struct chap_hdr_t *hdr = (struct chap_hdr_t *)d->ppp->buf;
+ struct chap_auth_data *d = container_of(h, typeof(*d), h);
+ struct chap_hdr *hdr = (struct chap_hdr *)d->ppp->buf;
if (d->ppp->buf_size < sizeof(*hdr) || ntohs(hdr->len) < HDR_LEN || ntohs(hdr->len) > d->ppp->buf_size - 2) {
log_ppp_warn("chap-md5: short packet received\n");
diff --git a/accel-pppd/auth/auth_mschap_v1.c b/accel-pppd/auth/auth_mschap_v1.c
index 1576c837..d9232cc9 100644
--- a/accel-pppd/auth/auth_mschap_v1.c
+++ b/accel-pppd/auth/auth_mschap_v1.c
@@ -29,7 +29,7 @@
#define VALUE_SIZE 8
#define RESPONSE_VALUE_SIZE (24+24+1)
-#define HDR_LEN (sizeof(struct chap_hdr_t)-2)
+#define HDR_LEN (sizeof(struct chap_hdr)-2)
static int conf_timeout = 5;
static int conf_interval = 0;
@@ -38,22 +38,22 @@ static int conf_any_login = 0;
static char *conf_msg_failure = "E=691 R=0";
static char *conf_msg_success = "Authentication succeeded";
-struct chap_hdr_t {
+struct chap_hdr {
uint16_t proto;
uint8_t code;
uint8_t id;
uint16_t len;
} __attribute__((packed));
-struct chap_challenge_t {
- struct chap_hdr_t hdr;
+struct chap_challenge {
+ struct chap_hdr hdr;
uint8_t val_size;
uint8_t val[VALUE_SIZE];
char name[0];
} __attribute__((packed));
-struct chap_response_t {
- struct chap_hdr_t hdr;
+struct chap_response {
+ struct chap_hdr hdr;
uint8_t val_size;
uint8_t lm_hash[24];
uint8_t nt_hash[24];
@@ -61,7 +61,7 @@ struct chap_response_t {
char name[0];
} __attribute__((packed));
-struct chap_auth_data_t {
+struct chap_auth_data {
struct auth_data_t auth;
struct ppp_handler_t h;
struct ppp_t *ppp;
@@ -70,15 +70,17 @@ struct chap_auth_data_t {
struct triton_timer_t timeout;
struct triton_timer_t interval;
int failure;
+ char *name;
+ char *mschap_error;
int started:1;
};
-static void chap_send_challenge(struct chap_auth_data_t *ad, int new);
+static void chap_send_challenge(struct chap_auth_data *ad, int new);
static void chap_recv(struct ppp_handler_t *h);
-static int chap_check_response(struct chap_auth_data_t *ad, struct chap_response_t *res, const char *name);
+static int chap_check_response(struct chap_auth_data *ad, struct chap_response *res, const char *name);
static void chap_timeout_timer(struct triton_timer_t *t);
static void chap_restart_timer(struct triton_timer_t *t);
-static void set_mppe_keys(struct chap_auth_data_t *ad, uint8_t *z_hash);
+static void set_mppe_keys(struct chap_auth_data *ad, uint8_t *z_hash);
static void print_buf(const uint8_t *buf,int size)
{
@@ -95,7 +97,7 @@ static void print_str(const char *buf, int size)
static struct auth_data_t* auth_data_init(struct ppp_t *ppp)
{
- struct chap_auth_data_t *d = _malloc(sizeof(*d));
+ struct chap_auth_data *d = _malloc(sizeof(*d));
memset(d, 0, sizeof(*d));
d->auth.proto = PPP_CHAP;
@@ -106,7 +108,7 @@ static struct auth_data_t* auth_data_init(struct ppp_t *ppp)
static void auth_data_free(struct ppp_t *ppp, struct auth_data_t *auth)
{
- struct chap_auth_data_t *d = container_of(auth, typeof(*d), auth);
+ struct chap_auth_data *d = container_of(auth, typeof(*d), auth);
if (d->timeout.tpd)
triton_timer_del(&d->timeout);
@@ -119,7 +121,7 @@ static void auth_data_free(struct ppp_t *ppp, struct auth_data_t *auth)
static int chap_start(struct ppp_t *ppp, struct auth_data_t *auth)
{
- struct chap_auth_data_t *d = container_of(auth, typeof(*d), auth);
+ struct chap_auth_data *d = container_of(auth, typeof(*d), auth);
d->h.proto = PPP_CHAP;
d->h.recv = chap_recv;
@@ -128,6 +130,7 @@ static int chap_start(struct ppp_t *ppp, struct auth_data_t *auth)
d->interval.expire = chap_restart_timer;
d->interval.period = conf_interval * 1000;
d->id = 1;
+ d->name = NULL;
ppp_register_chan_handler(ppp, &d->h);
@@ -138,7 +141,7 @@ static int chap_start(struct ppp_t *ppp, struct auth_data_t *auth)
static int chap_finish(struct ppp_t *ppp, struct auth_data_t *auth)
{
- struct chap_auth_data_t *d = container_of(auth, typeof(*d), auth);
+ struct chap_auth_data *d = container_of(auth, typeof(*d), auth);
if (d->timeout.tpd)
triton_timer_del(&d->timeout);
@@ -146,6 +149,9 @@ static int chap_finish(struct ppp_t *ppp, struct auth_data_t *auth)
if (d->interval.tpd)
triton_timer_del(&d->interval);
+ if (d->name)
+ _free(d->name);
+
ppp_unregister_handler(ppp, &d->h);
return 0;
@@ -153,7 +159,7 @@ static int chap_finish(struct ppp_t *ppp, struct auth_data_t *auth)
static void chap_timeout_timer(struct triton_timer_t *t)
{
- struct chap_auth_data_t *d = container_of(t, typeof(*d), timeout);
+ struct chap_auth_data *d = container_of(t, typeof(*d), timeout);
if (conf_ppp_verbose)
log_ppp_warn("mschap-v1: timeout\n");
@@ -169,7 +175,7 @@ static void chap_timeout_timer(struct triton_timer_t *t)
static void chap_restart_timer(struct triton_timer_t *t)
{
- struct chap_auth_data_t *d = container_of(t, typeof(*d), interval);
+ struct chap_auth_data *d = container_of(t, typeof(*d), interval);
chap_send_challenge(d, 1);
}
@@ -187,9 +193,9 @@ static int lcp_recv_conf_req(struct ppp_t *ppp, struct auth_data_t *d, uint8_t *
return LCP_OPT_NAK;
}
-static void chap_send_failure(struct chap_auth_data_t *ad, char *mschap_error)
+static void chap_send_failure(struct chap_auth_data *ad, char *mschap_error)
{
- struct chap_hdr_t *hdr = _malloc(sizeof(*hdr) + strlen(mschap_error) + 1);
+ struct chap_hdr *hdr = _malloc(sizeof(*hdr) + strlen(mschap_error) + 1);
hdr->proto = htons(PPP_CHAP);
hdr->code = CHAP_FAILURE;
hdr->id = ad->id;
@@ -204,9 +210,9 @@ static void chap_send_failure(struct chap_auth_data_t *ad, char *mschap_error)
_free(hdr);
}
-static void chap_send_success(struct chap_auth_data_t *ad, int id)
+static void chap_send_success(struct chap_auth_data *ad, int id)
{
- struct chap_hdr_t *hdr = _malloc(sizeof(*hdr) + strlen(conf_msg_success) + 1);
+ struct chap_hdr *hdr = _malloc(sizeof(*hdr) + strlen(conf_msg_success) + 1);
hdr->proto = htons(PPP_CHAP);
hdr->code = CHAP_SUCCESS;
hdr->id = id;
@@ -221,9 +227,9 @@ static void chap_send_success(struct chap_auth_data_t *ad, int id)
_free(hdr);
}
-static void chap_send_challenge(struct chap_auth_data_t *ad, int new)
+static void chap_send_challenge(struct chap_auth_data *ad, int new)
{
- struct chap_challenge_t msg = {
+ struct chap_challenge msg = {
.hdr.proto = htons(PPP_CHAP),
.hdr.code = CHAP_CHALLENGE,
.hdr.id = ad->id,
@@ -248,11 +254,46 @@ static void chap_send_challenge(struct chap_auth_data_t *ad, int new)
triton_timer_add(ad->ppp->ses.ctrl->ctx, &ad->timeout, 0);
}
-static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *hdr)
+static void auth_result(struct chap_auth_data *ad, int res)
+{
+ char *name = ad->name;
+
+ ad->name = NULL;
+
+ if (res == PWDB_DENIED) {
+ chap_send_failure(ad, ad->mschap_error);
+ if (ad->started)
+ ap_session_terminate(&ad->ppp->ses, TERM_AUTH_ERROR, 0);
+ else
+ ppp_auth_failed(ad->ppp, name);
+ } else {
+ if (ppp_auth_succeeded(ad->ppp, name)) {
+ chap_send_failure(ad, ad->mschap_error);
+ ap_session_terminate(&ad->ppp->ses, TERM_AUTH_ERROR, 0);
+ } else {
+ chap_send_success(ad, ad->id);
+ ad->started = 1;
+ if (conf_interval)
+ triton_timer_add(ad->ppp->ses.ctrl->ctx, &ad->interval, 0);
+ name = NULL;
+ }
+ }
+
+ ad->id++;
+
+ if (ad->mschap_error != conf_msg_failure) {
+ _free(ad->mschap_error);
+ ad->mschap_error = conf_msg_failure;
+ }
+
+ if (name)
+ _free(name);
+}
+
+static void chap_recv_response(struct chap_auth_data *ad, struct chap_hdr *hdr)
{
- struct chap_response_t *msg = (struct chap_response_t*)hdr;
+ struct chap_response *msg = (struct chap_response*)hdr;
char *name;
- char *mschap_error = conf_msg_failure;
int r;
if (ad->timeout.tpd)
@@ -273,6 +314,9 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
return;
}
+ if (ad->name)
+ return;
+
if (msg->hdr.id != ad->id) {
if (conf_ppp_verbose)
log_ppp_warn("mschap-v1: id mismatch\n");
@@ -300,7 +344,7 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
if (conf_any_login) {
if (ppp_auth_succeeded(ad->ppp, name)) {
- chap_send_failure(ad, mschap_error);
+ chap_send_failure(ad, ad->mschap_error);
ap_session_terminate(&ad->ppp->ses, TERM_AUTH_ERROR, 0);
_free(name);
return;
@@ -311,24 +355,34 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
return;
}
- r = pwdb_check(&ad->ppp->ses, name, PPP_CHAP, MSCHAP_V1, ad->id, ad->val, VALUE_SIZE, msg->lm_hash, msg->nt_hash, msg->flags, &mschap_error);
+ ad->mschap_error = conf_msg_failure;
+
+ r = pwdb_check(&ad->ppp->ses, (pwdb_callback)auth_result, ad, name, PPP_CHAP, MSCHAP_V1, ad->id, ad->val, VALUE_SIZE, msg->lm_hash, msg->nt_hash, msg->flags, &ad->mschap_error);
+
+ if (r == PWDB_WAIT) {
+ ad->name = name;
+ return;
+ }
+
if (r == PWDB_NO_IMPL)
if (chap_check_response(ad, msg, name))
r = PWDB_DENIED;
if (r == PWDB_DENIED) {
- chap_send_failure(ad, mschap_error);
+ chap_send_failure(ad, ad->mschap_error);
if (ad->started)
ap_session_terminate(&ad->ppp->ses, TERM_AUTH_ERROR, 0);
else
ppp_auth_failed(ad->ppp, name);
_free(name);
- if (mschap_error != conf_msg_failure)
- _free(mschap_error);
+ if (ad->mschap_error != conf_msg_failure) {
+ _free(ad->mschap_error);
+ ad->mschap_error = conf_msg_failure;
+ }
} else {
if (!ad->started) {
if (ppp_auth_succeeded(ad->ppp, name)) {
- chap_send_failure(ad, mschap_error);
+ chap_send_failure(ad, ad->mschap_error);
ap_session_terminate(&ad->ppp->ses, TERM_AUTH_ERROR, 0);
_free(name);
} else {
@@ -375,7 +429,7 @@ static void des_encrypt(const uint8_t *input, const uint8_t *key, uint8_t *outpu
memcpy(output, res, 8);
}
-static int chap_check_response(struct chap_auth_data_t *ad, struct chap_response_t *msg, const char *name)
+static int chap_check_response(struct chap_auth_data *ad, struct chap_response *msg, const char *name)
{
MD4_CTX md4_ctx;
uint8_t z_hash[21];
@@ -420,7 +474,7 @@ static int chap_check(uint8_t *ptr)
return *ptr == MSCHAP_V1;
}
-static void set_mppe_keys(struct chap_auth_data_t *ad, uint8_t *z_hash)
+static void set_mppe_keys(struct chap_auth_data *ad, uint8_t *z_hash)
{
MD4_CTX md4_ctx;
SHA_CTX sha_ctx;
@@ -450,7 +504,7 @@ static void set_mppe_keys(struct chap_auth_data_t *ad, uint8_t *z_hash)
static int chap_restart(struct ppp_t *ppp, struct auth_data_t *auth)
{
- struct chap_auth_data_t *d = container_of(auth, typeof(*d), auth);
+ struct chap_auth_data *d = container_of(auth, typeof(*d), auth);
chap_send_challenge(d, 1);
@@ -471,8 +525,8 @@ static struct ppp_auth_handler_t chap = {
static void chap_recv(struct ppp_handler_t *h)
{
- struct chap_auth_data_t *d = container_of(h, typeof(*d), h);
- struct chap_hdr_t *hdr = (struct chap_hdr_t *)d->ppp->buf;
+ struct chap_auth_data *d = container_of(h, typeof(*d), h);
+ struct chap_hdr *hdr = (struct chap_hdr *)d->ppp->buf;
if (d->ppp->buf_size < sizeof(*hdr) || ntohs(hdr->len) < HDR_LEN || ntohs(hdr->len) > d->ppp->buf_size - 2) {
log_ppp_warn("mschap-v1: short packet received\n");
diff --git a/accel-pppd/auth/auth_mschap_v2.c b/accel-pppd/auth/auth_mschap_v2.c
index 29f37495..0235ddf0 100644
--- a/accel-pppd/auth/auth_mschap_v2.c
+++ b/accel-pppd/auth/auth_mschap_v2.c
@@ -29,7 +29,7 @@
#define VALUE_SIZE 16
#define RESPONSE_VALUE_SIZE (16+8+24+1)
-#define HDR_LEN (sizeof(struct chap_hdr_t)-2)
+#define HDR_LEN (sizeof(struct chap_hdr)-2)
static int conf_timeout = 5;
static int conf_interval = 0;
@@ -38,7 +38,7 @@ static char *conf_msg_failure = "E=691 R=0 V=3";
static char *conf_msg_failure2 = "Authentication failure";
static char *conf_msg_success = "Authentication succeeded";
-struct chap_hdr_t {
+struct chap_hdr {
uint16_t proto;
uint8_t code;
uint8_t id;
@@ -46,14 +46,14 @@ struct chap_hdr_t {
} __attribute__((packed));
struct chap_challenge_t {
- struct chap_hdr_t hdr;
+ struct chap_hdr hdr;
uint8_t val_size;
uint8_t val[VALUE_SIZE];
char name[0];
} __attribute__((packed));
-struct chap_response_t {
- struct chap_hdr_t hdr;
+struct chap_response {
+ struct chap_hdr hdr;
uint8_t val_size;
uint8_t peer_challenge[16];
uint8_t reserved[8];
@@ -62,7 +62,7 @@ struct chap_response_t {
char name[0];
} __attribute__((packed));
-struct chap_auth_data_t {
+struct chap_auth_data {
struct auth_data_t auth;
struct ppp_handler_t h;
struct ppp_t *ppp;
@@ -71,16 +71,19 @@ struct chap_auth_data_t {
struct triton_timer_t timeout;
struct triton_timer_t interval;
char authenticator[41];
+ char *name;
+ char *mschap_error;
+ char *reply_msg;
int failure;
int started:1;
};
-static void chap_send_challenge(struct chap_auth_data_t *ad, int new);
+static void chap_send_challenge(struct chap_auth_data *ad, int new);
static void chap_recv(struct ppp_handler_t *h);
-static int chap_check_response(struct chap_auth_data_t *ad, struct chap_response_t *msg, const char *name);
+static int chap_check_response(struct chap_auth_data *ad, struct chap_response *msg, const char *name);
static void chap_timeout_timer(struct triton_timer_t *t);
static void chap_restart_timer(struct triton_timer_t *t);
-static void set_mppe_keys(struct chap_auth_data_t *ad, uint8_t *z_hash, uint8_t *nt_hash);
+static void set_mppe_keys(struct chap_auth_data *ad, uint8_t *z_hash, uint8_t *nt_hash);
static void print_buf(const uint8_t *buf, int size)
{
@@ -98,7 +101,7 @@ static void print_str(const char *buf, int size)
static struct auth_data_t* auth_data_init(struct ppp_t *ppp)
{
- struct chap_auth_data_t *d = _malloc(sizeof(*d));
+ struct chap_auth_data *d = _malloc(sizeof(*d));
memset(d, 0, sizeof(*d));
d->auth.proto = PPP_CHAP;
@@ -109,7 +112,7 @@ static struct auth_data_t* auth_data_init(struct ppp_t *ppp)
static void auth_data_free(struct ppp_t *ppp, struct auth_data_t *auth)
{
- struct chap_auth_data_t *d = container_of(auth, typeof(*d), auth);
+ struct chap_auth_data *d = container_of(auth, typeof(*d), auth);
if (d->timeout.tpd)
triton_timer_del(&d->timeout);
@@ -122,7 +125,7 @@ static void auth_data_free(struct ppp_t *ppp, struct auth_data_t *auth)
static int chap_start(struct ppp_t *ppp, struct auth_data_t *auth)
{
- struct chap_auth_data_t *d = container_of(auth, typeof(*d), auth);
+ struct chap_auth_data *d = container_of(auth, typeof(*d), auth);
d->h.proto = PPP_CHAP;
d->h.recv = chap_recv;
@@ -131,6 +134,7 @@ static int chap_start(struct ppp_t *ppp, struct auth_data_t *auth)
d->interval.expire = chap_restart_timer;
d->interval.period = conf_interval * 1000;
d->id = 1;
+ d->name = NULL;
ppp_register_chan_handler(ppp, &d->h);
@@ -141,7 +145,7 @@ static int chap_start(struct ppp_t *ppp, struct auth_data_t *auth)
static int chap_finish(struct ppp_t *ppp, struct auth_data_t *auth)
{
- struct chap_auth_data_t *d = container_of(auth, typeof(*d), auth);
+ struct chap_auth_data *d = container_of(auth, typeof(*d), auth);
if (d->timeout.tpd)
triton_timer_del(&d->timeout);
@@ -156,7 +160,7 @@ static int chap_finish(struct ppp_t *ppp, struct auth_data_t *auth)
static void chap_timeout_timer(struct triton_timer_t *t)
{
- struct chap_auth_data_t *d = container_of(t, typeof(*d), timeout);
+ struct chap_auth_data *d = container_of(t, typeof(*d), timeout);
if (conf_ppp_verbose)
log_ppp_warn("mschap-v2: timeout\n");
@@ -172,7 +176,7 @@ static void chap_timeout_timer(struct triton_timer_t *t)
static void chap_restart_timer(struct triton_timer_t *t)
{
- struct chap_auth_data_t *d = container_of(t, typeof(*d), interval);
+ struct chap_auth_data *d = container_of(t, typeof(*d), interval);
chap_send_challenge(d, 1);
}
@@ -190,9 +194,9 @@ static int lcp_recv_conf_req(struct ppp_t *ppp, struct auth_data_t *d, uint8_t *
return LCP_OPT_NAK;
}
-static void chap_send_failure(struct chap_auth_data_t *ad, char *mschap_error, char *reply_msg)
+static void chap_send_failure(struct chap_auth_data *ad, char *mschap_error, char *reply_msg)
{
- struct chap_hdr_t *hdr = _malloc(sizeof(*hdr) + strlen(mschap_error) + strlen(reply_msg) + 4);
+ struct chap_hdr *hdr = _malloc(sizeof(*hdr) + strlen(mschap_error) + strlen(reply_msg) + 4);
hdr->proto = htons(PPP_CHAP);
hdr->code = CHAP_FAILURE;
hdr->id = ad->id;
@@ -208,9 +212,9 @@ static void chap_send_failure(struct chap_auth_data_t *ad, char *mschap_error, c
_free(hdr);
}
-static void chap_send_success(struct chap_auth_data_t *ad, int id, const char *authenticator)
+static void chap_send_success(struct chap_auth_data *ad, int id, const char *authenticator)
{
- struct chap_hdr_t *hdr = _malloc(sizeof(*hdr) + strlen(conf_msg_success) + 1 + 45);
+ struct chap_hdr *hdr = _malloc(sizeof(*hdr) + strlen(conf_msg_success) + 1 + 45);
hdr->proto = htons(PPP_CHAP),
hdr->code = CHAP_SUCCESS,
hdr->id = id,
@@ -226,7 +230,7 @@ static void chap_send_success(struct chap_auth_data_t *ad, int id, const char *a
_free(hdr);
}
-static int generate_response(struct chap_auth_data_t *ad, struct chap_response_t *msg, const char *name, char *authenticator)
+static int generate_response(struct chap_auth_data *ad, struct chap_response *msg, const char *name, char *authenticator)
{
MD4_CTX md4_ctx;
SHA_CTX sha_ctx;
@@ -296,7 +300,7 @@ static int generate_response(struct chap_auth_data_t *ad, struct chap_response_t
return 0;
}
-static void chap_send_challenge(struct chap_auth_data_t *ad, int new)
+static void chap_send_challenge(struct chap_auth_data *ad, int new)
{
struct chap_challenge_t msg = {
.hdr.proto = htons(PPP_CHAP),
@@ -323,14 +327,54 @@ static void chap_send_challenge(struct chap_auth_data_t *ad, int new)
triton_timer_add(ad->ppp->ses.ctrl->ctx, &ad->timeout, 0);
}
-static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *hdr)
+static void auth_result(struct chap_auth_data *ad, int res)
+{
+ char *name = ad->name;
+
+ ad->name = NULL;
+
+ if (res == PWDB_DENIED) {
+ chap_send_failure(ad, ad->mschap_error, ad->reply_msg);
+ if (ad->started)
+ ap_session_terminate(&ad->ppp->ses, TERM_AUTH_ERROR, 0);
+ else
+ ppp_auth_failed(ad->ppp, name);
+ } else {
+ if (ppp_auth_succeeded(ad->ppp, name)) {
+ chap_send_failure(ad, ad->mschap_error, ad->reply_msg);
+ ap_session_terminate(&ad->ppp->ses, TERM_AUTH_ERROR, 0);
+ } else {
+ chap_send_success(ad, ad->id, ad->authenticator);
+ ad->started = 1;
+ if (conf_interval)
+ triton_timer_add(ad->ppp->ses.ctrl->ctx, &ad->interval, 0);
+ name = NULL;
+ }
+ }
+
+ ad->id++;
+
+ if (ad->mschap_error != conf_msg_failure) {
+ _free(ad->mschap_error);
+ ad->mschap_error = conf_msg_failure;
+ }
+
+ if (ad->reply_msg != conf_msg_failure2) {
+ _free(ad->reply_msg);
+ ad->reply_msg = conf_msg_failure2;
+ }
+
+ if (name)
+ _free(name);
+}
+
+
+static void chap_recv_response(struct chap_auth_data *ad, struct chap_hdr *hdr)
{
- struct chap_response_t *msg = (struct chap_response_t*)hdr;
+ struct chap_response *msg = (struct chap_response*)hdr;
char *name;
- char authenticator[41];
+ char *authenticator = ad->authenticator;
int r;
- char *mschap_error = conf_msg_failure;
- char *reply_msg = conf_msg_failure2;
authenticator[40] = 0;
@@ -352,6 +396,12 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
return;
}
+ if (ad->name)
+ return;
+
+ ad->mschap_error = conf_msg_failure;
+ ad->reply_msg = conf_msg_failure2;
+
if (msg->hdr.id != ad->id) {
if (conf_ppp_verbose)
log_ppp_warn("mschap-v2: id mismatch\n");
@@ -360,7 +410,7 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
if (msg->val_size != RESPONSE_VALUE_SIZE) {
log_ppp_error("mschap-v2: incorrect value-size (%i)\n", msg->val_size);
- chap_send_failure(ad, mschap_error, reply_msg);
+ chap_send_failure(ad, ad->mschap_error, ad->reply_msg);
if (ad->started)
ap_session_terminate(&ad->ppp->ses, TERM_USER_ERROR, 0);
else
@@ -378,7 +428,12 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
return;
}
- r = pwdb_check(&ad->ppp->ses, name, PPP_CHAP, MSCHAP_V2, ad->id, ad->val, msg->peer_challenge, msg->reserved, msg->nt_hash, msg->flags, authenticator, &mschap_error, &reply_msg);
+ r = pwdb_check(&ad->ppp->ses, (pwdb_callback)auth_result, ad, name, PPP_CHAP, MSCHAP_V2, ad->id, ad->val, msg->peer_challenge, msg->reserved, msg->nt_hash, msg->flags, authenticator, &ad->mschap_error, &ad->reply_msg);
+
+ if (r == PWDB_WAIT) {
+ ad->name = name;
+ return;
+ }
if (r == PWDB_NO_IMPL) {
r = chap_check_response(ad, msg, name);
@@ -389,20 +444,27 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
}
if (r == PWDB_DENIED) {
- chap_send_failure(ad, mschap_error, reply_msg);
+ chap_send_failure(ad, ad->mschap_error, ad->reply_msg);
if (ad->started)
ap_session_terminate(&ad->ppp->ses, TERM_AUTH_ERROR, 0);
else
ppp_auth_failed(ad->ppp, name);
+
_free(name);
- if (mschap_error != conf_msg_failure)
- _free(mschap_error);
- if (reply_msg != conf_msg_failure2)
- _free(reply_msg);
+
+ if (ad->mschap_error != conf_msg_failure) {
+ _free(ad->mschap_error);
+ ad->mschap_error = conf_msg_failure;
+ }
+
+ if (ad->reply_msg != conf_msg_failure2) {
+ _free(ad->reply_msg);
+ ad->reply_msg = conf_msg_failure2;
+ }
} else {
if (!ad->started) {
if (ppp_auth_succeeded(ad->ppp, name)) {
- chap_send_failure(ad, mschap_error, reply_msg);
+ chap_send_failure(ad, ad->mschap_error, ad->reply_msg);
ap_session_terminate(&ad->ppp->ses, TERM_AUTH_ERROR, 0);
_free(name);
} else {
@@ -416,8 +478,6 @@ static void chap_recv_response(struct chap_auth_data_t *ad, struct chap_hdr_t *h
_free(name);
}
- memcpy(ad->authenticator, authenticator, 41);
-
ad->id++;
}
}
@@ -451,7 +511,7 @@ static void des_encrypt(const uint8_t *input, const uint8_t *key, uint8_t *outpu
memcpy(output,res,8);
}
-static int chap_check_response(struct chap_auth_data_t *ad, struct chap_response_t *msg, const char *name)
+static int chap_check_response(struct chap_auth_data *ad, struct chap_response *msg, const char *name)
{
MD4_CTX md4_ctx;
SHA_CTX sha_ctx;
@@ -499,7 +559,7 @@ static int chap_check_response(struct chap_auth_data_t *ad, struct chap_response
return memcmp(nt_hash, msg->nt_hash, 24);
}
-static void set_mppe_keys(struct chap_auth_data_t *ad, uint8_t *z_hash, uint8_t *nt_hash)
+static void set_mppe_keys(struct chap_auth_data *ad, uint8_t *z_hash, uint8_t *nt_hash)
{
MD4_CTX md4_ctx;
SHA_CTX sha_ctx;
@@ -591,7 +651,7 @@ static int chap_check(uint8_t *ptr)
static int chap_restart(struct ppp_t *ppp, struct auth_data_t *auth)
{
- struct chap_auth_data_t *d = container_of(auth, typeof(*d), auth);
+ struct chap_auth_data *d = container_of(auth, typeof(*d), auth);
chap_send_challenge(d, 1);
@@ -613,8 +673,8 @@ static struct ppp_auth_handler_t chap=
static void chap_recv(struct ppp_handler_t *h)
{
- struct chap_auth_data_t *d = container_of(h, typeof(*d), h);
- struct chap_hdr_t *hdr = (struct chap_hdr_t *)d->ppp->buf;
+ struct chap_auth_data *d = container_of(h, typeof(*d), h);
+ struct chap_hdr *hdr = (struct chap_hdr *)d->ppp->buf;
if (d->ppp->buf_size < sizeof(*hdr) || ntohs(hdr->len) < HDR_LEN || ntohs(hdr->len) > d->ppp->buf_size - 2) {
log_ppp_warn("mschap-v2: short packet received\n");
diff --git a/accel-pppd/auth/auth_pap.c b/accel-pppd/auth/auth_pap.c
index 5f073370..9aab3775 100644
--- a/accel-pppd/auth/auth_pap.c
+++ b/accel-pppd/auth/auth_pap.c
@@ -15,12 +15,14 @@
#define MSG_FAILED "Authentication failed"
#define MSG_SUCCESSED "Authentication succeeded"
-#define HDR_LEN (sizeof(struct pap_hdr_t)-2)
+#define HDR_LEN (sizeof(struct pap_hdr)-2)
#define PAP_REQ 1
#define PAP_ACK 2
#define PAP_NAK 3
+struct pap_auth_data;
+
static int conf_timeout = 5;
static int conf_any_login = 0;
@@ -32,33 +34,32 @@ static int pap_start(struct ppp_t*, struct auth_data_t*);
static int pap_finish(struct ppp_t*, struct auth_data_t*);
static void pap_recv(struct ppp_handler_t*h);
static void pap_timeout(struct triton_timer_t *t);
+static void pap_auth_result(struct pap_auth_data *, int);
-struct pap_auth_data_t
-{
+struct pap_auth_data {
struct auth_data_t auth;
struct ppp_handler_t h;
struct ppp_t *ppp;
- int started:1;
struct triton_timer_t timeout;
+ char *peer_id;
+ int req_id;
+ int started:1;
};
-struct pap_hdr_t
-{
+struct pap_hdr {
uint16_t proto;
uint8_t code;
uint8_t id;
uint16_t len;
} __attribute__((packed));
-struct pap_ack_t
-{
- struct pap_hdr_t hdr;
+struct pap_ack {
+ struct pap_hdr hdr;
uint8_t msg_len;
char msg[0];
} __attribute__((packed));
-static struct ppp_auth_handler_t pap=
-{
+static struct ppp_auth_handler_t pap= {
.name = "PAP",
.init = auth_data_init,
.free = auth_data_free,
@@ -70,7 +71,7 @@ static struct ppp_auth_handler_t pap=
static struct auth_data_t* auth_data_init(struct ppp_t *ppp)
{
- struct pap_auth_data_t *d = _malloc(sizeof(*d));
+ struct pap_auth_data *d = _malloc(sizeof(*d));
memset(d, 0, sizeof(*d));
d->auth.proto = PPP_PAP;
@@ -81,14 +82,14 @@ static struct auth_data_t* auth_data_init(struct ppp_t *ppp)
static void auth_data_free(struct ppp_t *ppp, struct auth_data_t *auth)
{
- struct pap_auth_data_t *d = container_of(auth, typeof(*d), auth);
+ struct pap_auth_data *d = container_of(auth, typeof(*d), auth);
_free(d);
}
static int pap_start(struct ppp_t *ppp, struct auth_data_t *auth)
{
- struct pap_auth_data_t *d = container_of(auth, typeof(*d), auth);
+ struct pap_auth_data *d = container_of(auth, typeof(*d), auth);
d->h.proto = PPP_PAP;
d->h.recv = pap_recv;
@@ -103,10 +104,13 @@ static int pap_start(struct ppp_t *ppp, struct auth_data_t *auth)
}
static int pap_finish(struct ppp_t *ppp, struct auth_data_t *auth)
{
- struct pap_auth_data_t *d = container_of(auth, typeof(*d), auth);
+ struct pap_auth_data *d = container_of(auth, typeof(*d), auth);
if (d->timeout.tpd)
triton_timer_del(&d->timeout);
+
+ if (d->peer_id)
+ _free(d->peer_id);
ppp_unregister_handler(ppp, &d->h);
@@ -115,7 +119,7 @@ static int pap_finish(struct ppp_t *ppp, struct auth_data_t *auth)
static void pap_timeout(struct triton_timer_t *t)
{
- struct pap_auth_data_t *d = container_of(t, typeof(*d), timeout);
+ struct pap_auth_data *d = container_of(t, typeof(*d), timeout);
if (conf_ppp_verbose)
log_ppp_warn("pap: timeout\n");
@@ -133,10 +137,10 @@ static int lcp_recv_conf_req(struct ppp_t *ppp, struct auth_data_t *d, uint8_t *
return LCP_OPT_ACK;
}
-static void pap_send_ack(struct pap_auth_data_t *p, int id)
+static void pap_send_ack(struct pap_auth_data *p, int id)
{
uint8_t buf[128];
- struct pap_ack_t *msg = (struct pap_ack_t*)buf;
+ struct pap_ack *msg = (struct pap_ack*)buf;
msg->hdr.proto = htons(PPP_PAP);
msg->hdr.code = PAP_ACK;
msg->hdr.id = id;
@@ -150,10 +154,10 @@ static void pap_send_ack(struct pap_auth_data_t *p, int id)
ppp_chan_send(p->ppp, msg, ntohs(msg->hdr.len) + 2);
}
-static void pap_send_nak(struct pap_auth_data_t *p, int id)
+static void pap_send_nak(struct pap_auth_data *p, int id)
{
uint8_t buf[128];
- struct pap_ack_t *msg = (struct pap_ack_t*)buf;
+ struct pap_ack *msg = (struct pap_ack*)buf;
msg->hdr.proto = htons(PPP_PAP);
msg->hdr.code = PAP_NAK;
msg->hdr.id = id;
@@ -167,7 +171,33 @@ static void pap_send_nak(struct pap_auth_data_t *p, int id)
ppp_chan_send(p->ppp, msg, ntohs(msg->hdr.len) + 2);
}
-static int pap_recv_req(struct pap_auth_data_t *p, struct pap_hdr_t *hdr)
+static void pap_auth_result(struct pap_auth_data *p, int res)
+{
+ char *peer_id = p->peer_id;
+
+ p->peer_id = NULL;
+
+ if (res == PWDB_DENIED) {
+ pap_send_nak(p, p->req_id);
+ if (p->started)
+ ap_session_terminate(&p->ppp->ses, TERM_AUTH_ERROR, 0);
+ else
+ ppp_auth_failed(p->ppp, peer_id);
+ } else {
+ if (ppp_auth_succeeded(p->ppp, peer_id)) {
+ pap_send_nak(p, p->req_id);
+ ap_session_terminate(&p->ppp->ses, TERM_AUTH_ERROR, 0);
+ } else {
+ pap_send_ack(p, p->req_id);
+ p->started = 1;
+ return;
+ }
+ }
+
+ _free(peer_id);
+}
+
+static int pap_recv_req(struct pap_auth_data *p, struct pap_hdr *hdr)
{
int ret, r;
char *peer_id;
@@ -182,17 +212,21 @@ static int pap_recv_req(struct pap_auth_data_t *p, struct pap_hdr_t *hdr)
if (conf_ppp_verbose)
log_ppp_info2("recv [PAP AuthReq id=%x]\n", hdr->id);
-
+
if (p->started) {
pap_send_ack(p, hdr->id);
return 0;
}
+ if (p->peer_id)
+ return 0;
+
peer_id_len = *(uint8_t*)ptr; ptr++;
if (peer_id_len > ntohs(hdr->len) - sizeof(*hdr) + 2 - 1) {
log_ppp_warn("PAP: short packet received\n");
return -1;
}
+
peer_id = (char*)ptr; ptr += peer_id_len;
passwd_len = *(uint8_t*)ptr; ptr++;
@@ -217,7 +251,14 @@ static int pap_recv_req(struct pap_auth_data_t *p, struct pap_hdr_t *hdr)
passwd = _strndup((const char*)ptr, passwd_len);
- r = pwdb_check(&p->ppp->ses, peer_id, PPP_PAP, passwd);
+ r = pwdb_check(&p->ppp->ses, (pwdb_callback)pap_auth_result, p, peer_id, PPP_PAP, passwd);
+ if (r == PWDB_WAIT) {
+ p->peer_id = peer_id;
+ p->req_id = hdr->id;
+ _free(passwd);
+ return 0;
+ }
+
if (r == PWDB_NO_IMPL) {
passwd2 = pwdb_get_passwd(&p->ppp->ses, peer_id);
if (!passwd2) {
@@ -268,8 +309,8 @@ failed:
static void pap_recv(struct ppp_handler_t *h)
{
- struct pap_auth_data_t *d = container_of(h, typeof(*d), h);
- struct pap_hdr_t *hdr = (struct pap_hdr_t *)d->ppp->buf;
+ struct pap_auth_data *d = container_of(h, typeof(*d), h);
+ struct pap_hdr *hdr = (struct pap_hdr *)d->ppp->buf;
if (d->ppp->buf_size < sizeof(*hdr) || ntohs(hdr->len) < HDR_LEN || ntohs(hdr->len) < d->ppp->buf_size - 2) {
log_ppp_warn("PAP: short packet received\n");
diff --git a/accel-pppd/ctrl/ipoe/ipoe.c b/accel-pppd/ctrl/ipoe/ipoe.c
index 9c6075e1..f30d46fd 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.c
+++ b/accel-pppd/ctrl/ipoe/ipoe.c
@@ -498,6 +498,52 @@ static int ipoe_create_interface(struct ipoe_session *ses)
return 0;
}
+static void auth_result(struct ipoe_session *ses, int r)
+{
+ char *username = ses->username;
+
+ ses->username = NULL;
+
+ if (r == PWDB_DENIED) {
+ pthread_rwlock_wrlock(&ses_lock);
+ ses->ses.username = username;
+ ses->ses.terminate_cause = TERM_AUTH_ERROR;
+ pthread_rwlock_unlock(&ses_lock);
+ if (conf_ppp_verbose)
+ log_ppp_warn("authentication failed\n");
+ if (conf_l4_redirect_on_reject && !ses->dhcpv4_request)
+ l4_redirect_list_add(ses->yiaddr);
+ ap_session_terminate(&ses->ses, TERM_AUTH_ERROR, 0);
+ return;
+ }
+
+ ap_session_set_username(&ses->ses, username);
+ log_ppp_info1("%s: authentication succeeded\n", ses->ses.username);
+ triton_event_fire(EV_SES_AUTHORIZED, &ses->ses);
+
+ if (ses->serv->opt_nat)
+ ses->ses.ipv4 = ipdb_get_ipv4(&ses->ses);
+
+ if (ses->serv->opt_shared == 0 && (!ses->ses.ipv4 || ses->ses.ipv4->peer_addr == ses->yiaddr)) {
+ strncpy(ses->ses.ifname, ses->serv->ifname, AP_IFNAME_LEN);
+ ses->ses.ifindex = ses->serv->ifindex;
+ } else if (ses->ifindex == -1) {
+ if (ipoe_create_interface(ses))
+ return;
+ }
+
+ ap_session_set_ifindex(&ses->ses);
+
+ if (ses->dhcpv4_request && ses->serv->dhcpv4_relay) {
+ dhcpv4_relay_send(ses->serv->dhcpv4_relay, ses->dhcpv4_request, ses->relay_server_id, ses->serv->ifname, conf_agent_remote_id);
+
+ ses->timer.expire = ipoe_relay_timeout;
+ ses->timer.period = conf_relay_timeout * 1000;
+ triton_timer_add(&ses->ctx, &ses->timer, 0);
+ } else
+ __ipoe_session_start(ses);
+}
+
static void ipoe_session_start(struct ipoe_session *ses)
{
int r;
@@ -524,7 +570,9 @@ static void ipoe_session_start(struct ipoe_session *ses)
ap_session_starting(&ses->ses);
- if (!conf_noauth) {
+ if (conf_noauth)
+ r = PWDB_SUCCESS;
+ else {
if (ses->serv->opt_shared && ipoe_create_interface(ses))
return;
@@ -536,7 +584,12 @@ static void ipoe_session_start(struct ipoe_session *ses)
}
#endif
- r = pwdb_check(&ses->ses, username, PPP_PAP, conf_password ? conf_password : username);
+ ses->username = username;
+ r = pwdb_check(&ses->ses, (pwdb_callback)auth_result, ses, username, PPP_PAP, conf_password ? conf_password : username);
+
+ if (r == PWDB_WAIT)
+ return;
+
if (r == PWDB_NO_IMPL) {
passwd = pwdb_get_passwd(&ses->ses, ses->ses.username);
if (!passwd)
@@ -546,46 +599,9 @@ static void ipoe_session_start(struct ipoe_session *ses)
_free(passwd);
}
}
-
- if (r == PWDB_DENIED) {
- pthread_rwlock_wrlock(&ses_lock);
- ses->ses.username = username;
- ses->ses.terminate_cause = TERM_AUTH_ERROR;
- pthread_rwlock_unlock(&ses_lock);
- if (conf_ppp_verbose)
- log_ppp_warn("authentication failed\n");
- if (conf_l4_redirect_on_reject && !ses->dhcpv4_request)
- l4_redirect_list_add(ses->yiaddr);
- ap_session_terminate(&ses->ses, TERM_AUTH_ERROR, 0);
- return;
- }
}
-
- ap_session_set_username(&ses->ses, username);
- log_ppp_info1("%s: authentication succeeded\n", ses->ses.username);
- triton_event_fire(EV_SES_AUTHORIZED, &ses->ses);
-
- if (ses->serv->opt_nat)
- ses->ses.ipv4 = ipdb_get_ipv4(&ses->ses);
- if (ses->serv->opt_shared == 0 && (!ses->ses.ipv4 || ses->ses.ipv4->peer_addr == ses->yiaddr)) {
- strncpy(ses->ses.ifname, ses->serv->ifname, AP_IFNAME_LEN);
- ses->ses.ifindex = ses->serv->ifindex;
- } else if (ses->ifindex == -1) {
- if (ipoe_create_interface(ses))
- return;
- }
-
- ap_session_set_ifindex(&ses->ses);
-
- if (ses->dhcpv4_request && ses->serv->dhcpv4_relay) {
- dhcpv4_relay_send(ses->serv->dhcpv4_relay, ses->dhcpv4_request, ses->relay_server_id, ses->serv->ifname, conf_agent_remote_id);
-
- ses->timer.expire = ipoe_relay_timeout;
- ses->timer.period = conf_relay_timeout * 1000;
- triton_timer_add(&ses->ctx, &ses->timer, 0);
- } else
- __ipoe_session_start(ses);
+ auth_result(ses, r);
}
static void find_gw_addr(struct ipoe_session *ses)
diff --git a/accel-pppd/ctrl/ipoe/ipoe.h b/accel-pppd/ctrl/ipoe/ipoe.h
index 7b572c71..b06aa8b5 100644
--- a/accel-pppd/ctrl/ipoe/ipoe.h
+++ b/accel-pppd/ctrl/ipoe/ipoe.h
@@ -80,6 +80,7 @@ struct ipoe_session {
struct dhcpv4_packet *dhcpv4_relay_reply;
int relay_retransmit;
int ifindex;
+ char *username;
struct ipv4db_item_t ipv4;
#ifdef RADIUS
struct rad_plugin_t radius;
diff --git a/accel-pppd/ctrl/pppoe/pppoe.c b/accel-pppd/ctrl/pppoe/pppoe.c
index b1445c24..c1cbdb7b 100644
--- a/accel-pppd/ctrl/pppoe/pppoe.c
+++ b/accel-pppd/ctrl/pppoe/pppoe.c
@@ -33,7 +33,7 @@
#include "memdebug.h"
-#define SID_MAX 128
+#define SID_MAX 65536
struct pppoe_conn_t {
struct list_head entry;
@@ -141,7 +141,6 @@ static void disconnect(struct pppoe_conn_t *conn)
close(conn->disc_sock);
-
triton_event_fire(EV_CTRL_FINISHED, &conn->ppp.ses);
log_ppp_info1("disconnected\n");
@@ -365,6 +364,7 @@ static struct pppoe_conn_t *allocate_channel(struct pppoe_serv_t *serv, const ui
pthread_mutex_lock(&serv->lock);
list_add_tail(&conn->entry, &serv->conn_list);
+ serv->conn_cnt++;
pthread_mutex_unlock(&serv->lock);
return conn;
diff --git a/accel-pppd/extra/chap-secrets.c b/accel-pppd/extra/chap-secrets.c
index 21edcbdb..d48ecf6b 100644
--- a/accel-pppd/extra/chap-secrets.c
+++ b/accel-pppd/extra/chap-secrets.c
@@ -618,7 +618,7 @@ int auth_mschap_v2(struct ap_session *ses, struct cs_pd_t *pd, const char *usern
return PWDB_SUCCESS;
}
-static int check_passwd(struct pwdb_t *pwdb, struct ap_session *ses, const char *username, int type, va_list _args)
+static int check_passwd(struct pwdb_t *pwdb, struct ap_session *ses, pwdb_callback cb, void *cb_arg, const char *username, int type, va_list _args)
{
va_list args;
int r = PWDB_NO_IMPL;
diff --git a/accel-pppd/ifcfg.c b/accel-pppd/ifcfg.c
index d3a8006c..c48011ec 100644
--- a/accel-pppd/ifcfg.c
+++ b/accel-pppd/ifcfg.c
@@ -55,7 +55,6 @@ static void build_addr(struct ipv6db_addr_t *a, uint64_t intf_id, struct in6_add
*(uint64_t *)(addr->s6_addr + 8) |= intf_id & ((1 << (128 - a->prefix_len)) - 1);
}
-static void ifup_continue(struct ap_session *ses);
void ap_session_ifup(struct ap_session *ses)
{
if (ses->ifname_rename) {
@@ -66,12 +65,19 @@ void ap_session_ifup(struct ap_session *ses)
_free(ses->ifname_rename);
ses->ifname_rename = NULL;
}
-
+
triton_event_fire(EV_SES_ACCT_START, ses);
- triton_context_call(ses->ctrl->ctx, (triton_event_func)ifup_continue, ses);
+
+ if (ses->stop_time)
+ return;
+
+ if (!ses->acct_start) {
+ ses->acct_start = 1;
+ ap_session_accounting_started(ses);
+ }
}
-static void ifup_continue(struct ap_session *ses)
+void __export ap_session_accounting_started(struct ap_session *ses)
{
struct ipv6db_addr_t *a;
struct ifreq ifr;
@@ -84,10 +90,13 @@ static void ifup_continue(struct ap_session *ses)
if (ses->stop_time)
return;
+ if (--ses->acct_start)
+ return;
+
triton_event_fire(EV_SES_PRE_UP, ses);
if (ses->stop_time)
return;
-
+
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, ses->ifname);
diff --git a/accel-pppd/include/ap_session.h b/accel-pppd/include/ap_session.h
index f6d92d78..263e2656 100644
--- a/accel-pppd/include/ap_session.h
+++ b/accel-pppd/include/ap_session.h
@@ -103,6 +103,7 @@ struct ap_session
uint32_t acct_tx_packets_i;
uint32_t acct_rx_bytes_i;
uint32_t acct_tx_bytes_i;
+ int acct_start;
};
struct ap_session_stat
@@ -127,6 +128,7 @@ int ap_session_starting(struct ap_session *ses);
void ap_session_finished(struct ap_session *ses);
void ap_session_terminate(struct ap_session *ses, int cause, int hard);
void ap_session_activate(struct ap_session *ses);
+void ap_session_accounting_started(struct ap_session *ses);
int ap_session_set_username(struct ap_session *ses, char *username);
void ap_session_ifup(struct ap_session *ses);
diff --git a/accel-pppd/ppp/ppp.c b/accel-pppd/ppp/ppp.c
index 6e024805..fd572590 100644
--- a/accel-pppd/ppp/ppp.c
+++ b/accel-pppd/ppp/ppp.c
@@ -115,7 +115,7 @@ int __export establish_ppp(struct ppp_t *ppp)
log_ppp_error("open(unit) /dev/ppp: %s\n", strerror(errno));
goto exit_close_chan;
}
-
+
fcntl(ppp->unit_fd, F_SETFD, fcntl(ppp->unit_fd, F_GETFD) | FD_CLOEXEC);
ppp->ses.unit_idx = -1;
@@ -283,7 +283,7 @@ cont:
list_for_each_entry(ppp_h, &ppp->chan_handlers, entry) {
if (ppp_h->proto == proto) {
ppp_h->recv(ppp_h);
- if (ppp->chan_fd == -1) {
+ if (ppp->fd == -1) {
//ppp->ses.ctrl->finished(ppp);
return 1;
}
@@ -331,7 +331,7 @@ cont:
list_for_each_entry(ppp_h, &ppp->unit_handlers, entry) {
if (ppp_h->proto == proto) {
ppp_h->recv(ppp_h);
- if (ppp->unit_fd == -1) {
+ if (ppp->fd == -1) {
//ppp->ses.ctrl->finished(ppp);
return 1;
}
diff --git a/accel-pppd/pwdb.c b/accel-pppd/pwdb.c
index 5626c2c9..f42a3a88 100644
--- a/accel-pppd/pwdb.c
+++ b/accel-pppd/pwdb.c
@@ -8,7 +8,7 @@
static LIST_HEAD(pwdb_handlers);
-int __export pwdb_check(struct ap_session *ses, const char *username, int type, ...)
+int __export pwdb_check(struct ap_session *ses, pwdb_callback cb, void *cb_arg, const char *username, int type, ...)
{
struct pwdb_t *pwdb;
int r, res = PWDB_NO_IMPL;
@@ -19,11 +19,11 @@ int __export pwdb_check(struct ap_session *ses, const char *username, int type,
list_for_each_entry(pwdb, &pwdb_handlers, entry) {
if (!pwdb->check)
continue;
- r = pwdb->check(pwdb, ses, username, type, args);
+ r = pwdb->check(pwdb, ses, cb, cb_arg, username, type, args);
if (r == PWDB_NO_IMPL)
continue;
res = r;
- if (r == PWDB_SUCCESS)
+ if (r == PWDB_SUCCESS || r == PWDB_WAIT)
break;
}
diff --git a/accel-pppd/pwdb.h b/accel-pppd/pwdb.h
index f7d62d6a..7618bbc6 100644
--- a/accel-pppd/pwdb.h
+++ b/accel-pppd/pwdb.h
@@ -12,16 +12,18 @@ struct ap_session;
#define PWDB_SUCCESS 0
#define PWDB_DENIED 1
-#define PWDB_NO_IMPL 2
+#define PWDB_WAIT 2
+#define PWDB_NO_IMPL 3
-struct pwdb_t
-{
+typedef void (*pwdb_callback)(void *arg, int res);
+
+struct pwdb_t {
struct list_head entry;
- int (*check)(struct pwdb_t *, struct ap_session *, const char *username, int type, va_list args);
+ int (*check)(struct pwdb_t *, struct ap_session *, pwdb_callback cb, void *cb_arg, const char *username, int type, va_list args);
char* (*get_passwd)(struct pwdb_t *, struct ap_session *, const char *username);
};
-int pwdb_check(struct ap_session *, const char *username, int type, ...);
+int pwdb_check(struct ap_session *, pwdb_callback cb, void *cb_arg, const char *username, int type, ...);
char *pwdb_get_passwd(struct ap_session *, const char *username);
void pwdb_register(struct pwdb_t *);
diff --git a/accel-pppd/radius/acct.c b/accel-pppd/radius/acct.c
index 9a5e549e..f9919453 100644
--- a/accel-pppd/radius/acct.c
+++ b/accel-pppd/radius/acct.c
@@ -18,7 +18,6 @@
#include "memdebug.h"
-#define STAT_UPDATE_INTERVAL (10 * 60 * 1000)
#define INTERIM_SAFE_TIME 10
static int req_set_RA(struct rad_req_t *req, const char *secret)
@@ -40,13 +39,13 @@ static int req_set_stat(struct rad_req_t *req, struct ap_session *ses)
{
struct rtnl_link_stats stats;
struct radius_pd_t *rpd = req->rpd;
- time_t stop_time;
+ struct timespec ts;
int ret = 0;
if (ses->stop_time)
- stop_time = ses->stop_time;
+ ts.tv_sec = ses->stop_time;
else
- time(&stop_time);
+ clock_gettime(CLOCK_MONOTONIC, &ts);
if (ap_session_read_stats(ses, &stats) == 0) {
rad_packet_change_int(req->pack, NULL, "Acct-Input-Octets", stats.rx_bytes);
@@ -58,99 +57,56 @@ static int req_set_stat(struct rad_req_t *req, struct ap_session *ses)
} else
ret = -1;
- rad_packet_change_int(req->pack, NULL, "Acct-Session-Time", stop_time - ses->start_time);
+ rad_packet_change_int(req->pack, NULL, "Acct-Session-Time", ts.tv_sec - ses->start_time);
return ret;
}
-static int rad_acct_read(struct triton_md_handler_t *h)
+static void rad_acct_sent(struct rad_req_t *req, int res)
{
- struct rad_req_t *req = container_of(h, typeof(*req), hnd);
- struct rad_packet_t *pack;
- int r;
- unsigned int dt;
-
- if (req->reply) {
- rad_packet_free(req->reply);
- req->reply = NULL;
+ if (res) {
+ if (conf_acct_timeout)
+ ap_session_terminate(req->rpd->ses, TERM_NAS_ERROR, 0);
+ else
+ triton_timer_del(&req->timeout);
+ return;
}
-
- while (1) {
- r = rad_packet_recv(h->fd, &pack, NULL);
-
- if (pack) {
- rad_server_reply(req->serv);
- if (req->reply)
- rad_packet_free(req->reply);
- req->reply = pack;
- if (conf_interim_verbose) {
- log_ppp_info2("recv ");
- rad_packet_print(req->reply, req->serv, log_ppp_info2);
- }
- }
-
- if (r)
- break;
+
+ __sync_add_and_fetch(&req->serv->stat_interim_sent, 1);
+
+ if (!req->hnd.tpd) {
+ triton_md_register_handler(req->rpd->ses->ctrl->ctx, &req->hnd);
+ triton_md_enable_handler(&req->hnd, MD_MODE_READ);
}
- if (!req->reply)
- return 0;
-
- if (req->reply->id != req->pack->id)
- return 0;
-
- rad_server_req_exit(req);
+ if (req->timeout.tpd)
+ triton_timer_mod(&req->timeout, 0);
+ else
+ triton_timer_add(req->rpd->ses->ctrl->ctx, &req->timeout, 0);
+}
- dt = (req->reply->tv.tv_sec - req->pack->tv.tv_sec) * 1000 +
+static void rad_acct_recv(struct rad_req_t *req)
+{
+ int dt = (req->reply->tv.tv_sec - req->pack->tv.tv_sec) * 1000 +
(req->reply->tv.tv_nsec - req->pack->tv.tv_nsec) / 1000000;
stat_accm_add(req->serv->stat_interim_query_1m, dt);
stat_accm_add(req->serv->stat_interim_query_5m, dt);
- if (req->reply->code != CODE_ACCOUNTING_RESPONSE || req->reply->id != req->pack->id) {
- rad_packet_free(req->reply);
- req->reply = NULL;
- } else {
- if (req->timeout.tpd)
- triton_timer_del(&req->timeout);
- }
-
- triton_md_unregister_handler(h, 1);
-
- return 1;
-}
-
-static int __rad_req_send(struct rad_req_t *req)
-{
- while (1) {
- if (rad_server_req_enter(req)) {
- if (rad_server_realloc(req))
- return -1;
- continue;
- }
-
- if (rad_req_send(req, conf_interim_verbose ? log_ppp_info2 : NULL)) {
- rad_server_req_exit(req);
- rad_server_fail(req->serv);
- continue;
- }
-
- if (!req->hnd.tpd) {
- triton_md_register_handler(req->rpd->ses->ctrl->ctx, &req->hnd);
- triton_md_enable_handler(&req->hnd, MD_MODE_READ);
- }
+ triton_timer_del(&req->timeout);
- break;
- }
-
- return 0;
+ triton_md_unregister_handler(&req->hnd, 1);
+
+ rad_packet_free(req->reply);
+ req->reply = NULL;
}
static void rad_acct_timeout(struct triton_timer_t *t)
{
struct rad_req_t *req = container_of(t, typeof(*req), timeout);
- time_t ts, dt;
-
+ time_t dt;
+ struct timespec ts;
+
rad_server_req_exit(req);
rad_server_timeout(req->serv);
@@ -164,9 +120,9 @@ static void rad_acct_timeout(struct triton_timer_t *t)
return;
}
- time(&ts);
+ clock_gettime(CLOCK_MONOTONIC, &ts);
- dt = ts - req->rpd->acct_timestamp;
+ dt = ts.tv_sec - req->ts;
if (dt > conf_acct_timeout) {
rad_server_fail(req->serv);
@@ -176,42 +132,30 @@ static void rad_acct_timeout(struct triton_timer_t *t)
ap_session_terminate(req->rpd->ses, TERM_NAS_ERROR, 0);
return;
}
- time(&req->rpd->acct_timestamp);
}
- if (dt > conf_acct_timeout / 2) {
- req->timeout.period += 1000;
- triton_timer_mod(&req->timeout, 0);
- } else if (dt > conf_acct_timeout / 3) {
- if (req->timeout.period != conf_timeout * 2000) {
- req->timeout.period = conf_timeout * 2000;
- triton_timer_mod(&req->timeout, 0);
- }
+ if (dt > conf_acct_timeout / 2)
+ req->timeout.expire_tv.tv_sec++;
+ else if (dt > conf_acct_timeout / 4) {
+ if (req->timeout.expire_tv.tv_sec < conf_timeout * 2)
+ req->timeout.expire_tv.tv_sec = conf_timeout * 2;
}
- if (conf_acct_delay_time) {
+ if (conf_acct_delay_time)
req->pack->id++;
- rad_packet_change_int(req->pack, NULL, "Acct-Delay-Time", dt);
- req_set_RA(req, req->serv->secret);
- }
-
- if (__rad_req_send(req)) {
- triton_timer_del(t);
-
- if (conf_acct_timeout) {
- log_ppp_warn("radius:acct: no servers available, terminating session...\n");
- ap_session_terminate(req->rpd->ses, TERM_NAS_ERROR, 0);
- }
+
+ req->try = 0;
- return;
+ if (rad_req_send(req) && conf_acct_timeout) {
+ log_ppp_warn("radius:acct: no servers available, terminating session...\n");
+ ap_session_terminate(req->rpd->ses, TERM_NAS_ERROR, 0);
}
-
- __sync_add_and_fetch(&req->serv->stat_interim_sent, 1);
}
static void rad_acct_interim_update(struct triton_timer_t *t)
{
struct radius_pd_t *rpd = container_of(t, typeof(*rpd), acct_interim_timer);
+ struct timespec ts;
if (rpd->acct_req->timeout.tpd)
return;
@@ -228,281 +172,313 @@ static void rad_acct_interim_update(struct triton_timer_t *t)
if (!rpd->acct_interim_interval)
return;
- time(&rpd->acct_timestamp);
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ rpd->acct_req->ts = ts.tv_sec;
rpd->acct_req->pack->id++;
- rad_packet_change_val(rpd->acct_req->pack, NULL, "Acct-Status-Type", "Interim-Update");
- if (conf_acct_delay_time)
- rad_packet_change_int(rpd->acct_req->pack, NULL, "Acct-Delay-Time", 0);
- req_set_RA(rpd->acct_req, rpd->acct_req->serv->secret);
+ if (!rpd->acct_req->before_send)
+ req_set_RA(rpd->acct_req, rpd->acct_req->serv->secret);
+
+ rpd->acct_req->timeout.expire_tv.tv_sec = conf_timeout;
+ rpd->acct_req->try = 0;
- if (__rad_req_send(rpd->acct_req))
- return;
+ if (rad_req_send(rpd->acct_req) && conf_acct_timeout) {
+ log_ppp_warn("radius:acct: no servers available, terminating session...\n");
+ ap_session_terminate(rpd->ses, TERM_NAS_ERROR, 0);
+ }
+}
- /* The above call may set rpd->acct_req to NULL in the following chain of events:
- 1. __rad_req_send fails (on rad_server_realloc) and calls ppp_terminate;
- 2. As a result, an EV_PPP_FINISHING event is fired;
- 3. ppp_finishing calls rad_acct_stop that cleans up the request. */
- if (!rpd->acct_req)
- return;
+static int rad_acct_before_send(struct rad_req_t *req)
+{
+ struct timespec ts;
- __sync_add_and_fetch(&rpd->acct_req->serv->stat_interim_sent, 1);
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+
+ rad_packet_change_int(req->pack, NULL, "Acct-Delay-Time", ts.tv_sec - req->ts);
+ req_set_RA(req, req->serv->secret);
- rpd->acct_req->timeout.period = conf_timeout * 1000;
- triton_timer_add(rpd->ses->ctrl->ctx, &rpd->acct_req->timeout, 0);
+ return 0;
}
-int rad_acct_start(struct radius_pd_t *rpd)
+static void rad_acct_start_sent(struct rad_req_t *req, int res)
{
- int i;
- time_t ts;
- unsigned int dt;
+ if (res) {
+ ap_session_terminate(req->rpd->ses, TERM_NAS_ERROR, 0);
+ return;
+ }
- if (!conf_accounting)
- return 0;
+ __sync_add_and_fetch(&req->serv->stat_acct_sent, 1);
- if (!rpd->acct_req)
- rpd->acct_req = rad_req_alloc(rpd, CODE_ACCOUNTING_REQUEST, rpd->ses->username);
+ if (!req->hnd.tpd) {
+ triton_md_register_handler(req->rpd->ses->ctrl->ctx, &req->hnd);
+ triton_md_enable_handler(&req->hnd, MD_MODE_READ);
+ }
- if (!rpd->acct_req)
- return -1;
+ if (req->timeout.tpd)
+ triton_timer_mod(&req->timeout, 0);
+ else
+ triton_timer_add(req->rpd->ses->ctrl->ctx, &req->timeout, 0);
+}
- if (rad_req_acct_fill(rpd->acct_req)) {
- log_ppp_error("radius:acct: failed to fill accounting attributes\n");
- goto out_err;
- }
+static void rad_acct_start_recv(struct rad_req_t *req)
+{
+ struct radius_pd_t *rpd = req->rpd;
+ int dt = (req->reply->tv.tv_sec - req->pack->tv.tv_sec) * 1000 +
+ (req->reply->tv.tv_nsec - req->pack->tv.tv_nsec) / 1000000;
+
+ stat_accm_add(req->serv->stat_acct_query_1m, dt);
+ stat_accm_add(req->serv->stat_acct_query_5m, dt);
- //if (rad_req_add_val(rpd->acct_req, "Acct-Status-Type", "Start", 4))
- // goto out_err;
- //if (rad_req_add_str(rpd->acct_req, "Acct-Session-Id", rpd->ses->ionid, PPP_SESSIONID_LEN, 1))
- // goto out_err;
+ triton_timer_del(&req->timeout);
- if (rpd->acct_req->reply) {
- rad_packet_free(rpd->acct_req->reply);
- rpd->acct_req->reply = NULL;
+ triton_md_unregister_handler(&req->hnd, 1);
+
+ if (rpd->acct_interim_interval) {
+ rad_packet_free(req->reply);
+ req->reply = NULL;
+
+ rad_packet_change_val(req->pack, NULL, "Acct-Status-Type", "Interim-Update");
+ rpd->acct_interim_timer.expire = rad_acct_interim_update;
+ rpd->acct_interim_timer.period = rpd->acct_interim_interval * 1000;
+ triton_timer_add(rpd->ses->ctrl->ctx, &rpd->acct_interim_timer, 0);
+
+ req->timeout.expire = rad_acct_timeout;
+ req->recv = rad_acct_recv;
+ req->sent = rad_acct_sent;
+ req->log = conf_interim_verbose ? log_ppp_info2 : NULL;
+ } else {
+ rad_req_free(rpd->acct_req);
+ rpd->acct_req = NULL;
}
- time(&rpd->acct_timestamp);
+ rpd->acct_started = 1;
- if (req_set_RA(rpd->acct_req, rpd->acct_req->serv->secret))
- goto out_err;
+ ap_session_accounting_started(rpd->ses);
+}
-#ifdef USE_BACKUP
- if (rpd->ses->state != AP_STATE_RESTORE || !rpd->ses->backup->internal) {
-#endif
- while (1) {
-
- if (rad_server_req_enter(rpd->acct_req)) {
- if (rad_server_realloc(rpd->acct_req)) {
- log_ppp_warn("radius:acct_start: no servers available\n");
- goto out_err;
- }
- if (req_set_RA(rpd->acct_req, rpd->acct_req->serv->secret))
- goto out_err;
- continue;
- }
-
- for (i = 0; i < conf_max_try; i++) {
- if (conf_acct_delay_time) {
- time(&ts);
- rad_packet_change_int(rpd->acct_req->pack, NULL, "Acct-Delay-Time", ts - rpd->acct_timestamp);
- if (req_set_RA(rpd->acct_req, rpd->acct_req->serv->secret)) {
- rad_server_req_exit(rpd->acct_req);
- goto out_err;
- }
- }
-
- if (rad_req_send(rpd->acct_req, conf_verbose ? log_ppp_info1 : NULL))
- goto out;
-
- __sync_add_and_fetch(&rpd->acct_req->serv->stat_acct_sent, 1);
-
- rad_req_wait(rpd->acct_req, conf_timeout);
-
- if (!rpd->acct_req->reply) {
- if (conf_acct_delay_time)
- rpd->acct_req->pack->id++;
- __sync_add_and_fetch(&rpd->acct_req->serv->stat_acct_lost, 1);
- stat_accm_add(rpd->acct_req->serv->stat_acct_lost_1m, 1);
- stat_accm_add(rpd->acct_req->serv->stat_acct_lost_5m, 1);
- continue;
- }
-
- dt = (rpd->acct_req->reply->tv.tv_sec - rpd->acct_req->pack->tv.tv_sec) * 1000 +
- (rpd->acct_req->reply->tv.tv_nsec - rpd->acct_req->pack->tv.tv_nsec) / 1000000;
- stat_accm_add(rpd->acct_req->serv->stat_acct_query_1m, dt);
- stat_accm_add(rpd->acct_req->serv->stat_acct_query_5m, dt);
-
- if (rpd->acct_req->reply->id != rpd->acct_req->pack->id || rpd->acct_req->reply->code != CODE_ACCOUNTING_RESPONSE) {
- rad_packet_free(rpd->acct_req->reply);
- rpd->acct_req->reply = NULL;
- __sync_add_and_fetch(&rpd->acct_req->serv->stat_acct_lost, 1);
- stat_accm_add(rpd->acct_req->serv->stat_acct_lost_1m, 1);
- stat_accm_add(rpd->acct_req->serv->stat_acct_lost_5m, 1);
- } else
- break;
- }
-
-out:
- rad_server_req_exit(rpd->acct_req);
-
- if (rpd->acct_req->reply)
- break;
-
- rad_server_fail(rpd->acct_req->serv);
- if (rad_server_realloc(rpd->acct_req)) {
- log_ppp_warn("radius:acct_start: no servers available\n");
- goto out_err;
- }
- if (req_set_RA(rpd->acct_req, rpd->acct_req->serv->secret))
- goto out_err;
- }
-#ifdef USE_BACKUP
+static void rad_acct_start_timeout(struct triton_timer_t *t)
+{
+ struct rad_req_t *req = container_of(t, typeof(*req), timeout);
+
+ __sync_add_and_fetch(&req->serv->stat_acct_lost, 1);
+ stat_accm_add(req->serv->stat_acct_lost_1m, 1);
+ stat_accm_add(req->serv->stat_acct_lost_5m, 1);
+
+ if (req->before_send)
+ req->pack->id++;
+
+ if (rad_req_send(req))
+ ap_session_terminate(req->rpd->ses, TERM_NAS_ERROR, 0);
+}
+
+int rad_acct_start(struct radius_pd_t *rpd)
+{
+ struct rad_req_t *req = rad_req_alloc(rpd, CODE_ACCOUNTING_REQUEST, rpd->ses->username);
+
+ if (!req)
+ return -1;
+
+ if (rad_req_acct_fill(req)) {
+ log_ppp_error("radius:acct: failed to fill accounting attributes\n");
+ goto out_err;
}
-#endif
- close(rpd->acct_req->hnd.fd);
- rpd->acct_req->hnd.fd = -1;
- rpd->acct_req->hnd.read = rad_acct_read;
+ if (conf_acct_delay_time)
+ req->before_send = rad_acct_before_send;
+ else if (req_set_RA(req, req->serv->secret))
+ goto out_err;
+
+ req->recv = rad_acct_start_recv;
+ req->timeout.expire = rad_acct_start_timeout;
+ req->timeout.expire_tv.tv_sec = conf_timeout;
+ req->sent = rad_acct_start_sent;
+ req->log = conf_verbose ? log_ppp_info1 : NULL;
- rpd->acct_req->timeout.expire = rad_acct_timeout;
- rpd->acct_req->timeout.period = conf_timeout * 1000;
+ if (rad_req_send(req))
+ goto out_err;
+
+ rpd->acct_req = req;
- rpd->acct_interim_timer.expire = rad_acct_interim_update;
- rpd->acct_interim_timer.period = rpd->acct_interim_interval ? rpd->acct_interim_interval * 1000 : STAT_UPDATE_INTERVAL;
- if (rpd->acct_interim_interval)
- triton_timer_add(rpd->ses->ctrl->ctx, &rpd->acct_interim_timer, 0);
return 0;
out_err:
- rad_req_free(rpd->acct_req);
- rpd->acct_req = NULL;
+ rad_req_free(req);
return -1;
}
-void rad_acct_stop(struct radius_pd_t *rpd)
+static void rad_acct_stop_sent(struct rad_req_t *req, int res)
{
- int i;
- time_t ts;
- unsigned int dt;
-
- if (!rpd->acct_req || !rpd->acct_req->serv)
+ if (res) {
+ if (req->rpd)
+ rad_acct_stop_defer(req->rpd);
+ else {
+ if (ap_shutdown)
+ rad_req_free(req);
+ else
+ req->try = 0;
+ }
+
return;
+ }
+
+ __sync_add_and_fetch(&req->serv->stat_acct_sent, 1);
+
+ if (!req->hnd.tpd) {
+ triton_md_register_handler(req->rpd ? req->rpd->ses->ctrl->ctx : NULL, &req->hnd);
+ triton_md_enable_handler(&req->hnd, MD_MODE_READ);
+ }
- if (rpd->acct_interim_timer.tpd)
- triton_timer_del(&rpd->acct_interim_timer);
+ if (req->timeout.tpd)
+ triton_timer_mod(&req->timeout, 0);
+ else
+ triton_timer_add(req->rpd ? req->rpd->ses->ctrl->ctx : NULL, &req->timeout, 0);
+}
- if (rpd->acct_req->timeout.tpd)
- rad_server_req_exit(rpd->acct_req);
+static void rad_acct_stop_recv(struct rad_req_t *req)
+{
+ struct radius_pd_t *rpd = req->rpd;
+ int dt = (req->reply->tv.tv_sec - req->pack->tv.tv_sec) * 1000 +
+ (req->reply->tv.tv_nsec - req->pack->tv.tv_nsec) / 1000000;
+
+ stat_accm_add(req->serv->stat_acct_query_1m, dt);
+ stat_accm_add(req->serv->stat_acct_query_5m, dt);
+
+ rad_req_free(req);
- if (rpd->acct_req->hnd.tpd)
- triton_md_unregister_handler(&rpd->acct_req->hnd, 0);
+ if (rpd)
+ rpd->acct_req = NULL;
+}
+
+static void rad_acct_stop_timeout(struct triton_timer_t *t)
+{
+ struct rad_req_t *req = container_of(t, typeof(*req), timeout);
+
+ if (req->active) {
+ rad_server_req_exit(req);
+ rad_server_timeout(req->serv);
+
+ __sync_add_and_fetch(&req->serv->stat_acct_lost, 1);
+ stat_accm_add(req->serv->stat_acct_lost_1m, 1);
+ stat_accm_add(req->serv->stat_acct_lost_5m, 1);
- if (rpd->acct_req->timeout.tpd)
- triton_timer_del(&rpd->acct_req->timeout);
-
- switch (rpd->ses->terminate_cause) {
- case TERM_USER_REQUEST:
- rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "User-Request");
- break;
- case TERM_SESSION_TIMEOUT:
- rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "Session-Timeout");
- break;
- case TERM_ADMIN_RESET:
- rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "Admin-Reset");
- break;
- case TERM_USER_ERROR:
- case TERM_AUTH_ERROR:
- rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "User-Error");
- break;
- case TERM_NAS_ERROR:
- rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "NAS-Error");
- break;
- case TERM_NAS_REQUEST:
- rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "NAS-Request");
- break;
- case TERM_NAS_REBOOT:
- rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "NAS-Reboot");
- break;
- case TERM_LOST_CARRIER:
- rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "Lost-Carrier");
- break;
- case TERM_IDLE_TIMEOUT:
- rad_packet_add_val(rpd->acct_req->pack, NULL, "Acct-Terminate-Cause", "Idle-Timeout");
- break;
+ if (req->before_send)
+ req->pack->id++;
+ }
+
+ if (req->try == conf_max_try) {
+ rad_req_free(req);
+ return;
+ }
+
+ if (rad_req_send(req)) {
+ if (ap_shutdown) {
+ rad_req_free(req);
+ return;
}
- rad_packet_change_val(rpd->acct_req->pack, NULL, "Acct-Status-Type", "Stop");
- req_set_stat(rpd->acct_req, rpd->ses);
- req_set_RA(rpd->acct_req, rpd->acct_req->serv->secret);
- /// !!! rad_req_add_val(rpd->acct_req, "Acct-Terminate-Cause", "");
+ req->try = 0;
+ }
+}
+
+static void start_deferred(struct rad_req_t *req)
+{
+ if (req->hnd.fd != -1) {
+ triton_md_register_handler(NULL, &req->hnd);
+ triton_md_enable_handler(&req->hnd, MD_MODE_READ);
+ if (rad_req_read(&req->hnd))
+ return;
+ }
+
+ triton_timer_add(NULL, &req->timeout, 0);
+}
+
+void rad_acct_stop_defer(struct radius_pd_t *rpd)
+{
+ struct rad_req_t *req = rpd->acct_req;
+ rad_server_req_cancel(req);
+ if (req->hnd.tpd)
+ triton_md_unregister_handler(&req->hnd, 0);
+ rpd->acct_req = NULL;
+
+ req->rpd = NULL;
+ req->log = conf_verbose ? log_info1 : NULL;
+ req->timeout.expire = rad_acct_stop_timeout;
+
+ triton_context_call(NULL, (triton_event_func)start_deferred, req);
+}
+
+int rad_acct_stop(struct radius_pd_t *rpd)
+{
+ struct rad_req_t *req = rpd->acct_req;
+ struct timespec ts;
+
+ if (req) {
+ triton_timer_del(&rpd->acct_interim_timer);
- if (rpd->acct_req->reply) {
- rad_packet_free(rpd->acct_req->reply);
- rpd->acct_req->reply = NULL;
- }
+ rad_server_req_cancel(req);
+
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ req->ts = ts.tv_sec;
+ req->try = 0;
+ } else {
+ req = rad_req_alloc(rpd, CODE_ACCOUNTING_REQUEST, rpd->ses->username);
+ if (!req)
+ return -1;
- time(&rpd->acct_timestamp);
-
- while (1) {
-
- if (rad_server_req_enter(rpd->acct_req)) {
- if (rad_server_realloc(rpd->acct_req)) {
- log_ppp_warn("radius:acct_stop: no servers available\n");
- break;
- }
- req_set_RA(rpd->acct_req, rpd->acct_req->serv->secret);
- continue;
- }
-
- for(i = 0; i < conf_max_try; i++) {
- if (conf_acct_delay_time) {
- time(&ts);
- rad_packet_change_int(rpd->acct_req->pack, NULL, "Acct-Delay-Time", ts - rpd->acct_timestamp);
- rpd->acct_req->pack->id++;
- if (req_set_RA(rpd->acct_req, rpd->acct_req->serv->secret))
- break;
- }
- if (rad_req_send(rpd->acct_req, conf_verbose ? log_ppp_info1 : NULL))
- goto out;
- __sync_add_and_fetch(&rpd->acct_req->serv->stat_acct_sent, 1);
- rad_req_wait(rpd->acct_req, conf_timeout);
- if (!rpd->acct_req->reply) {
- __sync_add_and_fetch(&rpd->acct_req->serv->stat_acct_lost, 1);
- stat_accm_add(rpd->acct_req->serv->stat_acct_lost_1m, 1);
- stat_accm_add(rpd->acct_req->serv->stat_acct_lost_5m, 1);
- continue;
- }
-
- dt = (rpd->acct_req->reply->tv.tv_sec - rpd->acct_req->pack->tv.tv_sec) * 1000 +
- (rpd->acct_req->reply->tv.tv_nsec - rpd->acct_req->pack->tv.tv_nsec) / 1000000;
- stat_accm_add(rpd->acct_req->serv->stat_acct_query_1m, dt);
- stat_accm_add(rpd->acct_req->serv->stat_acct_query_5m, dt);
-
- if (rpd->acct_req->reply->id != rpd->acct_req->pack->id || rpd->acct_req->reply->code != CODE_ACCOUNTING_RESPONSE) {
- rad_packet_free(rpd->acct_req->reply);
- rpd->acct_req->reply = NULL;
- __sync_add_and_fetch(&rpd->acct_req->serv->stat_acct_lost, 1);
- stat_accm_add(rpd->acct_req->serv->stat_acct_lost_1m, 1);
- stat_accm_add(rpd->acct_req->serv->stat_acct_lost_5m, 1);
- } else
- break;
- }
-
-out:
- rad_server_req_exit(rpd->acct_req);
-
- if (rpd->acct_req->reply)
- break;
-
- rad_server_fail(rpd->acct_req->serv);
- if (rad_server_realloc(rpd->acct_req)) {
- log_ppp_warn("radius:acct_stop: no servers available\n");
- break;
- }
- req_set_RA(rpd->acct_req, rpd->acct_req->serv->secret);
+ if (rad_req_acct_fill(req)) {
+ log_ppp_error("radius:acct: failed to fill accounting attributes\n");
+ rad_req_free(req);
+ return -1;
}
- rad_req_free(rpd->acct_req);
- rpd->acct_req = NULL;
+ rpd->acct_req = req;
+ }
+
+ switch (rpd->ses->terminate_cause) {
+ case TERM_USER_REQUEST:
+ rad_packet_add_val(req->pack, NULL, "Acct-Terminate-Cause", "User-Request");
+ break;
+ case TERM_SESSION_TIMEOUT:
+ rad_packet_add_val(req->pack, NULL, "Acct-Terminate-Cause", "Session-Timeout");
+ break;
+ case TERM_ADMIN_RESET:
+ rad_packet_add_val(req->pack, NULL, "Acct-Terminate-Cause", "Admin-Reset");
+ break;
+ case TERM_USER_ERROR:
+ case TERM_AUTH_ERROR:
+ rad_packet_add_val(req->pack, NULL, "Acct-Terminate-Cause", "User-Error");
+ break;
+ case TERM_NAS_ERROR:
+ rad_packet_add_val(req->pack, NULL, "Acct-Terminate-Cause", "NAS-Error");
+ break;
+ case TERM_NAS_REQUEST:
+ rad_packet_add_val(req->pack, NULL, "Acct-Terminate-Cause", "NAS-Request");
+ break;
+ case TERM_NAS_REBOOT:
+ rad_packet_add_val(req->pack, NULL, "Acct-Terminate-Cause", "NAS-Reboot");
+ break;
+ case TERM_LOST_CARRIER:
+ rad_packet_add_val(req->pack, NULL, "Acct-Terminate-Cause", "Lost-Carrier");
+ break;
+ case TERM_IDLE_TIMEOUT:
+ rad_packet_add_val(req->pack, NULL, "Acct-Terminate-Cause", "Idle-Timeout");
+ break;
+ }
+
+ rad_packet_change_val(req->pack, NULL, "Acct-Status-Type", "Stop");
+ req_set_stat(req, rpd->ses);
+ req_set_RA(req, req->serv->secret);
+
+ req->recv = rad_acct_stop_recv;
+ req->timeout.expire = rad_acct_start_timeout;
+ req->timeout.expire_tv.tv_sec = conf_timeout;
+ req->sent = rad_acct_stop_sent;
+ req->log = conf_verbose ? log_ppp_info1 : NULL;
+
+ if (rad_req_send(req)) {
+ rad_acct_stop_defer(rpd);
+ return -1;
+ }
+
+ return 0;
}
diff --git a/accel-pppd/radius/auth.c b/accel-pppd/radius/auth.c
index f4efe3b9..b73f2597 100644
--- a/accel-pppd/radius/auth.c
+++ b/accel-pppd/radius/auth.c
@@ -4,6 +4,7 @@
#include "crypto.h"
#include "triton.h"
+#include "mempool.h"
#include "events.h"
#include "log.h"
#include "pwdb.h"
@@ -142,193 +143,179 @@ static uint8_t* encrypt_password(const char *passwd, const char *secret, const u
return epasswd;
}
-static int rad_auth_send(struct rad_req_t *req)
+static void rad_auth_finalize(struct radius_pd_t *rpd, int r)
{
- int i;
- struct timespec tv, tv2;
+ hold_pd(rpd);
+
+ rpd->auth_ctx->cb(rpd->auth_ctx->cb_arg, r);
+
+ if (rpd->auth_ctx) {
+ rad_req_free(rpd->auth_ctx->req);
+ mempool_free(rpd->auth_ctx);
+ rpd->auth_ctx = NULL;
+ }
+
+ release_pd(rpd);
+}
+
+static void rad_auth_recv(struct rad_req_t *req)
+{
+ struct rad_packet_t *pack = req->reply;
unsigned int dt;
- int timeout;
- while (1) {
- if (rad_server_req_enter(req)) {
- if (rad_server_realloc(req)) {
- log_ppp_warn("radius: no available servers\n");
- break;
- }
- continue;
+ triton_timer_del(&req->timeout);
+
+ dt = (req->reply->tv.tv_sec - req->pack->tv.tv_sec) * 1000 + (req->reply->tv.tv_nsec - req->pack->tv.tv_nsec) / 1000000;
+ stat_accm_add(req->serv->stat_auth_query_1m, dt);
+ stat_accm_add(req->serv->stat_auth_query_5m, dt);
+
+ if (pack->code == CODE_ACCESS_ACCEPT) {
+ if (rad_proc_attrs(req)) {
+ rad_auth_finalize(req->rpd, PWDB_DENIED);
+ return;
}
+
+ struct ev_radius_t ev = {
+ .ses = req->rpd->ses,
+ .request = req->pack,
+ .reply = pack,
+ };
+ triton_event_fire(EV_RADIUS_ACCESS_ACCEPT, &ev);
+ }
+
+ if (req->rpd->auth_ctx->recv && req->rpd->auth_ctx->recv(req)) {
+ rad_auth_finalize(req->rpd, PWDB_DENIED);
+ return;
+ }
+
+ req->rpd->authenticated = 1;
+
+ rad_auth_finalize(req->rpd, PWDB_SUCCESS);
+}
- for(i = 0; i < conf_max_try; i++) {
- __sync_add_and_fetch(&req->serv->stat_auth_sent, 1);
- clock_gettime(CLOCK_MONOTONIC, &tv);
- if (rad_req_send(req, conf_verbose ? log_ppp_info1 : NULL))
- goto out;
+static void rad_auth_timeout(struct triton_timer_t *t)
+{
+ struct rad_req_t *req = container_of(t, typeof(*req), timeout);
+
+ __sync_add_and_fetch(&req->serv->stat_auth_lost, 1);
+ stat_accm_add(req->serv->stat_auth_lost_1m, 1);
+ stat_accm_add(req->serv->stat_auth_lost_5m, 1);
- timeout = conf_timeout;
+ if (rad_req_send(req))
+ rad_auth_finalize(req->rpd, PWDB_DENIED);
+}
- while (timeout > 0) {
+static void rad_auth_sent(struct rad_req_t *req, int res)
+{
+ if (res) {
+ rad_auth_finalize(req->rpd, PWDB_DENIED);
+ return;
+ }
+
+ __sync_add_and_fetch(&req->serv->stat_auth_sent, 1);
+
+ if (!req->hnd.tpd) {
+ triton_md_register_handler(req->rpd->ses->ctrl->ctx, &req->hnd);
+ triton_md_enable_handler(&req->hnd, MD_MODE_READ);
+ }
+
+ if (req->timeout.tpd)
+ triton_timer_mod(&req->timeout, 0);
+ else
+ triton_timer_add(req->rpd->ses->ctrl->ctx, &req->timeout, 0);
+}
+
+static struct rad_req_t *rad_auth_req_alloc(struct radius_pd_t *rpd, const char *username, int (*recv)(struct rad_req_t *))
+{
+ struct rad_req_t *req = rad_req_alloc(rpd, CODE_ACCESS_REQUEST, username);
+
+ if (!req)
+ return NULL;
+
+ if (conf_sid_in_auth) {
+ if (rad_packet_add_str(req->pack, NULL, "Acct-Session-Id", rpd->ses->sessionid))
+ goto out;
+ }
- rad_req_wait(req, timeout);
+ if (rpd->attr_state) {
+ if (rad_packet_add_octets(req->pack, NULL, "State", rpd->attr_state, rpd->attr_state_len))
+ goto out;
+ }
- if (req->reply) {
- if (req->reply->id != req->pack->id) {
- rad_packet_free(req->reply);
- req->reply = NULL;
- clock_gettime(CLOCK_MONOTONIC, &tv2);
- timeout = conf_timeout - ((tv2.tv_sec - tv.tv_sec) * 1000 + (tv2.tv_nsec - tv.tv_nsec) / 1000000);
- } else
- break;
- } else
- break;
- }
+ req->hnd.read = rad_req_read;
+ req->timeout.expire = rad_auth_timeout;
+ req->timeout.expire_tv.tv_sec = conf_timeout;
+ req->recv = rad_auth_recv;
+ req->sent = rad_auth_sent;
+ if (conf_verbose)
+ req->log = log_ppp_info1;
- if (req->reply) {
- dt = (req->reply->tv.tv_sec - tv.tv_sec) * 1000 + (req->reply->tv.tv_nsec - tv.tv_nsec) / 1000000;
- stat_accm_add(req->serv->stat_auth_query_1m, dt);
- stat_accm_add(req->serv->stat_auth_query_5m, dt);
- break;
- } else {
- __sync_add_and_fetch(&req->serv->stat_auth_lost, 1);
- stat_accm_add(req->serv->stat_auth_lost_1m, 1);
- stat_accm_add(req->serv->stat_auth_lost_5m, 1);
- }
- }
-out:
- rad_server_req_exit(req);
+ rpd->auth_ctx->recv = recv;
+ rpd->auth_ctx->req = req;
- if (!req->reply) {
- rad_server_fail(req->serv);
- if (rad_server_realloc(req)) {
- log_ppp_warn("radius: no available servers\n");
- break;
- }
- } else {
- if (req->reply->code == CODE_ACCESS_ACCEPT) {
- if (rad_proc_attrs(req))
- return PWDB_DENIED;
- return PWDB_SUCCESS;
- } else
- break;
- }
- }
+ return req;
- return PWDB_DENIED;
+out:
+ rad_req_free(req);
+ return NULL;
}
int rad_auth_pap(struct radius_pd_t *rpd, const char *username, va_list args)
{
- struct rad_req_t *req;
- int r = PWDB_DENIED;
- //int id = va_arg(args, int);
+ struct rad_req_t *req = rad_auth_req_alloc(rpd, username, NULL);
+ int r;
const char *passwd = va_arg(args, const char *);
uint8_t *epasswd;
int epasswd_len;
- req = rad_req_alloc(rpd, CODE_ACCESS_REQUEST, username);
if (!req)
return PWDB_DENIED;
epasswd = encrypt_password(passwd, req->serv->secret, req->RA, &epasswd_len);
if (!epasswd)
- goto out;
-
- if (rad_packet_add_octets(req->pack, NULL, "User-Password", epasswd, epasswd_len)) {
- if (epasswd_len)
- _free(epasswd);
- goto out;
- }
+ return PWDB_DENIED;
+ r = rad_packet_add_octets(req->pack, NULL, "User-Password", epasswd, epasswd_len);
if (epasswd_len)
_free(epasswd);
+
+ if (r)
+ return PWDB_DENIED;
- if (conf_sid_in_auth)
- if (rad_packet_add_str(req->pack, NULL, "Acct-Session-Id", rpd->ses->sessionid))
- return -1;
-
- r = rad_auth_send(req);
- if (r == PWDB_SUCCESS) {
- struct ev_radius_t ev = {
- .ses = rpd->ses,
- .request = req->pack,
- .reply = req->reply,
- };
- triton_event_fire(EV_RADIUS_ACCESS_ACCEPT, &ev);
- }
-
-out:
- rad_req_free(req);
+ if (rad_req_send(req))
+ return PWDB_DENIED;
- return r;
+ return PWDB_WAIT;
}
int rad_auth_chap_md5(struct radius_pd_t *rpd, const char *username, va_list args)
{
- int r = PWDB_DENIED;
+ struct rad_req_t *req = rad_auth_req_alloc(rpd, username, NULL);
uint8_t chap_password[17];
-
int id = va_arg(args, int);
uint8_t *challenge = va_arg(args, uint8_t *);
int challenge_len = va_arg(args, int);
uint8_t *response = va_arg(args, uint8_t *);
+
+ if (!req)
+ return PWDB_DENIED;
chap_password[0] = id;
memcpy(chap_password + 1, response, 16);
- if (!rpd->auth_req) {
- rpd->auth_req = rad_req_alloc(rpd, CODE_ACCESS_REQUEST, username);
- if (!rpd->auth_req)
- return PWDB_DENIED;
-
- if (challenge_len == 16)
- memcpy(rpd->auth_req->RA, challenge, 16);
- if (rad_packet_add_octets(rpd->auth_req->pack, NULL, "CHAP-Challenge", challenge, challenge_len))
- goto out;
+ if (challenge_len == 16)
+ memcpy(req->RA, challenge, 16);
- if (rad_packet_add_octets(rpd->auth_req->pack, NULL, "CHAP-Password", chap_password, 17))
- goto out;
- } else {
- if (challenge_len == 16)
- memcpy(rpd->auth_req->RA, challenge, 16);
- if (rad_packet_change_octets(rpd->auth_req->pack, NULL, "CHAP-Challenge", challenge, challenge_len))
- goto out;
+ if (rad_packet_add_octets(req->pack, NULL, "CHAP-Challenge", challenge, challenge_len))
+ return PWDB_DENIED;
- if (rad_packet_change_octets(rpd->auth_req->pack, NULL, "CHAP-Password", chap_password, 17))
- goto out;
-
- if (rpd->attr_state) {
- if (rad_packet_find_attr(rpd->auth_req->pack, NULL, "State")) {
- if (rad_packet_change_octets(rpd->auth_req->pack, NULL, "State", rpd->attr_state, rpd->attr_state_len))
- goto out;
- } else {
- if (rad_packet_add_octets(rpd->auth_req->pack, NULL, "State", rpd->attr_state, rpd->attr_state_len))
- goto out;
- }
- }
-
- if (rad_packet_build(rpd->auth_req->pack, rpd->auth_req->RA))
- return -1;
- }
+ if (rad_packet_add_octets(req->pack, NULL, "CHAP-Password", chap_password, 17))
+ return PWDB_DENIED;
- if (conf_sid_in_auth)
- if (rad_packet_add_str(rpd->auth_req->pack, NULL, "Acct-Session-Id", rpd->ses->sessionid))
- goto out;
-
- r = rad_auth_send(rpd->auth_req);
- if (r == PWDB_SUCCESS) {
- struct ev_radius_t ev = {
- .ses = rpd->ses,
- .request = rpd->auth_req->pack,
- .reply = rpd->auth_req->reply,
- };
- triton_event_fire(EV_RADIUS_ACCESS_ACCEPT, &ev);
- rpd->auth_req->pack->id++;
- }
-
-out:
- rad_req_free(rpd->auth_req);
- rpd->auth_req = NULL;
+ if (rad_req_send(req))
+ return PWDB_DENIED;
- return r;
+ return PWDB_WAIT;
}
static void setup_mppe(struct rad_req_t *req, const uint8_t *challenge)
@@ -376,11 +363,26 @@ static void setup_mppe(struct rad_req_t *req, const uint8_t *challenge)
triton_event_fire(EV_MPPE_KEYS, &ev_mppe);
}
+static int rad_auth_mschap_v1_recv(struct rad_req_t *req)
+{
+ if (req->reply->code == CODE_ACCESS_ACCEPT)
+ setup_mppe(req, req->rpd->auth_ctx->challenge);
+ else {
+ struct rad_attr_t *ra = rad_packet_find_attr(req->reply, "Microsoft", "MS-CHAP-Error");
+ if (ra) {
+ char **mschap_error = req->rpd->auth_ctx->mschap_error;
+ *mschap_error = _malloc(ra->len + 1);
+ memcpy(*mschap_error, ra->val.string, ra->len);
+ (*mschap_error)[ra->len] = 0;
+ }
+ }
+
+ return 0;
+}
+
int rad_auth_mschap_v1(struct radius_pd_t *rpd, const char *username, va_list args)
{
- int r = PWDB_DENIED;
uint8_t response[50];
- struct rad_attr_t *ra;
int id = va_arg(args, int);
const uint8_t *challenge = va_arg(args, const uint8_t *);
@@ -388,80 +390,70 @@ int rad_auth_mschap_v1(struct radius_pd_t *rpd, const char *username, va_list ar
const uint8_t *lm_response = va_arg(args, const uint8_t *);
const uint8_t *nt_response = va_arg(args, const uint8_t *);
int flags = va_arg(args, int);
- char **mschap_error = va_arg(args, char **);
+ rpd->auth_ctx->mschap_error = va_arg(args, char **);
+ struct rad_req_t *req = rad_auth_req_alloc(rpd, username, rad_auth_mschap_v1_recv);
+
+ if (!req)
+ return PWDB_DENIED;
+
+ rpd->auth_ctx->challenge = challenge;
response[0] = id;
response[1] = flags;
memcpy(response + 2, lm_response, 24);
memcpy(response + 2 + 24, nt_response, 24);
- if (!rpd->auth_req) {
- rpd->auth_req = rad_req_alloc(rpd, CODE_ACCESS_REQUEST, username);
- if (!rpd->auth_req)
- return PWDB_DENIED;
-
- if (rad_packet_add_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, challenge_len))
- goto out;
-
- if (rad_packet_add_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Response", response, sizeof(response)))
- goto out;
- } else {
- if (rad_packet_change_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, challenge_len))
- goto out;
-
- if (rad_packet_change_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Response", response, sizeof(response)))
- goto out;
+ if (rad_packet_add_octets(req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, challenge_len))
+ return PWDB_DENIED;
+
+ if (rad_packet_add_octets(req->pack, "Microsoft", "MS-CHAP-Response", response, sizeof(response)))
+ return PWDB_DENIED;
+
+ if (rad_req_send(req))
+ return PWDB_DENIED;
- if (rpd->attr_state) {
- if (rad_packet_find_attr(rpd->auth_req->pack, NULL, "State")) {
- if (rad_packet_change_octets(rpd->auth_req->pack, NULL, "State", rpd->attr_state, rpd->attr_state_len))
- goto out;
- } else {
- if (rad_packet_add_octets(rpd->auth_req->pack, NULL, "State", rpd->attr_state, rpd->attr_state_len))
- goto out;
- }
- }
-
- if (rad_packet_build(rpd->auth_req->pack, rpd->auth_req->RA))
- return -1;
- }
+ return PWDB_WAIT;
+}
- if (conf_sid_in_auth)
- if (rad_packet_add_str(rpd->auth_req->pack, NULL, "Acct-Session-Id", rpd->ses->sessionid))
- goto out;
+static int rad_auth_mschap_v2_recv(struct rad_req_t *req)
+{
+ struct radius_pd_t *rpd = req->rpd;
+ struct rad_attr_t *ra;
+ if (req->reply->code == CODE_ACCESS_ACCEPT) {
+ ra = rad_packet_find_attr(req->reply, "Microsoft", "MS-CHAP2-Success");
+ if (!ra) {
+ log_error("radius:auth:mschap-v2: 'MS-CHAP-Success' not found in radius response\n");
+ return -1;
+ } else
+ memcpy(rpd->auth_ctx->authenticator, ra->val.octets + 3, 40);
- r = rad_auth_send(rpd->auth_req);
- if (r == PWDB_SUCCESS) {
- struct ev_radius_t ev = {
- .ses = rpd->ses,
- .request = rpd->auth_req->pack,
- .reply = rpd->auth_req->reply,
- };
- triton_event_fire(EV_RADIUS_ACCESS_ACCEPT, &ev);
- setup_mppe(rpd->auth_req, challenge);
- rpd->auth_req->pack->id++;
- } else if (rpd->auth_req->reply) {
- ra = rad_packet_find_attr(rpd->auth_req->reply, "Microsoft", "MS-CHAP-Error");
+ setup_mppe(rpd->auth_ctx->req, NULL);
+ } else {
+ ra = rad_packet_find_attr(req->reply, "Microsoft", "MS-CHAP-Error");
if (ra) {
+ char **mschap_error = req->rpd->auth_ctx->mschap_error;
*mschap_error = _malloc(ra->len + 1);
memcpy(*mschap_error, ra->val.string, ra->len);
(*mschap_error)[ra->len] = 0;
}
- }
-out:
- rad_req_free(rpd->auth_req);
- rpd->auth_req = NULL;
+ ra = rad_packet_find_attr(req->reply, NULL, "Reply-Message");
+ if (ra) {
+ char **reply_msg = req->rpd->auth_ctx->reply_msg;
+ *reply_msg = _malloc(ra->len + 1);
+ memcpy(*reply_msg, ra->val.string, ra->len);
+ (*reply_msg)[ra->len] = 0;
+ }
+ }
- return r;
+ return 0;
}
int rad_auth_mschap_v2(struct radius_pd_t *rpd, const char *username, va_list args)
{
- int r = PWDB_DENIED;
- struct rad_attr_t *ra;
uint8_t mschap_response[50];
+ struct rad_req_t *req = rad_auth_req_alloc(rpd, username, rad_auth_mschap_v2_recv);
int id = va_arg(args, int);
const uint8_t *challenge = va_arg(args, const uint8_t *);
@@ -469,9 +461,12 @@ int rad_auth_mschap_v2(struct radius_pd_t *rpd, const char *username, va_list ar
const uint8_t *reserved = va_arg(args, const uint8_t *);
const uint8_t *response = va_arg(args, const uint8_t *);
int flags = va_arg(args, int);
- uint8_t *authenticator = va_arg(args, uint8_t *);
- char **mschap_error = va_arg(args, char **);
- char **reply_msg = va_arg(args, char **);
+ rpd->auth_ctx->authenticator = va_arg(args, uint8_t *);
+ rpd->auth_ctx->mschap_error = va_arg(args, char **);
+ rpd->auth_ctx->reply_msg = va_arg(args, char **);
+
+ if (!req)
+ return PWDB_DENIED;
mschap_response[0] = id;
mschap_response[1] = flags;
@@ -479,107 +474,28 @@ int rad_auth_mschap_v2(struct radius_pd_t *rpd, const char *username, va_list ar
memcpy(mschap_response + 2 + 16, reserved, 8);
memcpy(mschap_response + 2 + 16 + 8, response, 24);
- if (!rpd->auth_req) {
- rpd->auth_req = rad_req_alloc(rpd, CODE_ACCESS_REQUEST, username);
- if (!rpd->auth_req)
- return PWDB_DENIED;
-
- if (rad_packet_add_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, 16))
- goto out;
-
- if (rad_packet_add_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP2-Response", mschap_response, sizeof(mschap_response)))
- goto out;
- } else {
- if (rad_packet_change_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, 16))
- goto out;
+ if (rad_packet_add_octets(req->pack, "Microsoft", "MS-CHAP-Challenge", challenge, 16))
+ return PWDB_DENIED;
- if (rad_packet_change_octets(rpd->auth_req->pack, "Microsoft", "MS-CHAP2-Response", mschap_response, sizeof(mschap_response)))
- goto out;
-
- if (rpd->attr_state) {
- if (rad_packet_find_attr(rpd->auth_req->pack, NULL, "State")) {
- if (rad_packet_change_octets(rpd->auth_req->pack, NULL, "State", rpd->attr_state, rpd->attr_state_len))
- goto out;
- } else {
- if (rad_packet_add_octets(rpd->auth_req->pack, NULL, "State", rpd->attr_state, rpd->attr_state_len))
- goto out;
- }
- }
+ if (rad_packet_add_octets(req->pack, "Microsoft", "MS-CHAP2-Response", mschap_response, sizeof(mschap_response)))
+ return PWDB_DENIED;
- if (rad_packet_build(rpd->auth_req->pack, rpd->auth_req->RA))
- return -1;
- }
-
- if (conf_sid_in_auth)
- if (rad_packet_add_str(rpd->auth_req->pack, NULL, "Acct-Session-Id", rpd->ses->sessionid))
- goto out;
-
- r = rad_auth_send(rpd->auth_req);
- if (r == PWDB_SUCCESS) {
- ra = rad_packet_find_attr(rpd->auth_req->reply, "Microsoft", "MS-CHAP2-Success");
- if (!ra) {
- log_error("radius:auth:mschap-v2: 'MS-CHAP-Success' not found in radius response\n");
- r = PWDB_DENIED;
- } else
- memcpy(authenticator, ra->val.octets + 3, 40);
- }
- if (r == PWDB_SUCCESS) {
- struct ev_radius_t ev = {
- .ses = rpd->ses,
- .request = rpd->auth_req->pack,
- .reply = rpd->auth_req->reply,
- };
- triton_event_fire(EV_RADIUS_ACCESS_ACCEPT, &ev);
- setup_mppe(rpd->auth_req, NULL);
- rpd->auth_req->pack->id++;
- } else if (rpd->auth_req->reply) {
- ra = rad_packet_find_attr(rpd->auth_req->reply, "Microsoft", "MS-CHAP-Error");
- if (ra) {
- *mschap_error = _malloc(ra->len + 1);
- memcpy(*mschap_error, ra->val.string, ra->len);
- (*mschap_error)[ra->len] = 0;
- }
- ra = rad_packet_find_attr(rpd->auth_req->reply, NULL, "Reply-Message");
- if (ra) {
- *reply_msg = _malloc(ra->len + 1);
- memcpy(*reply_msg, ra->val.string, ra->len);
- (*reply_msg)[ra->len] = 0;
- }
- }
-
-out:
- rad_req_free(rpd->auth_req);
- rpd->auth_req = NULL;
+ if (rad_req_send(req))
+ return PWDB_DENIED;
- return r;
+ return PWDB_WAIT;
}
-
int rad_auth_null(struct radius_pd_t *rpd, const char *username, va_list args)
{
- struct rad_req_t *req;
- int r = PWDB_DENIED;
-
- req = rad_req_alloc(rpd, CODE_ACCESS_REQUEST, username);
+ struct rad_req_t *req = rad_auth_req_alloc(rpd, username, NULL);
+
if (!req)
return PWDB_DENIED;
-
- if (conf_sid_in_auth)
- if (rad_packet_add_str(req->pack, NULL, "Acct-Session-Id", rpd->ses->sessionid))
- return -1;
- r = rad_auth_send(req);
- if (r == PWDB_SUCCESS) {
- struct ev_radius_t ev = {
- .ses = rpd->ses,
- .request = req->pack,
- .reply = req->reply,
- };
- triton_event_fire(EV_RADIUS_ACCESS_ACCEPT, &ev);
- }
-
- rad_req_free(req);
+ if (rad_req_send(req))
+ return PWDB_DENIED;
- return r;
+ return PWDB_WAIT;
}
diff --git a/accel-pppd/radius/packet.c b/accel-pppd/radius/packet.c
index 5bff60af..87c337fe 100644
--- a/accel-pppd/radius/packet.c
+++ b/accel-pppd/radius/packet.c
@@ -143,13 +143,14 @@ int rad_packet_recv(int fd, struct rad_packet_t **p, struct sockaddr_in *addr)
else
n = read(fd, pack->buf, REQ_LENGTH_MAX);
if (n < 0) {
- if (errno == EAGAIN) {
- rad_packet_free(pack);
- return -1;
- }
+ rad_packet_free(pack);
+ if (errno == EAGAIN)
+ return 1;
+
if (errno != ECONNREFUSED)
log_ppp_error("radius:packet:read: %s\n", strerror(errno));
- goto out_err;
+
+ return -1;
}
break;
}
diff --git a/accel-pppd/radius/radius.c b/accel-pppd/radius/radius.c
index a3b211ea..ec7d9119 100644
--- a/accel-pppd/radius/radius.c
+++ b/accel-pppd/radius/radius.c
@@ -54,6 +54,7 @@ static void *pd_key;
static struct ipdb_t ipdb;
static mempool_t rpd_pool;
+static mempool_t auth_ctx_pool;
int rad_proc_attrs(struct rad_req_t *req)
{
@@ -159,7 +160,7 @@ int rad_proc_attrs(struct rad_req_t *req)
return res;
}
-static int rad_pwdb_check(struct pwdb_t *pwdb, struct ap_session *ses, const char *username, int type, va_list _args)
+static int rad_pwdb_check(struct pwdb_t *pwdb, struct ap_session *ses, pwdb_callback cb, void *cb_arg, const char *username, int type, va_list _args)
{
int r = PWDB_NO_IMPL;
va_list args;
@@ -180,6 +181,12 @@ static int rad_pwdb_check(struct pwdb_t *pwdb, struct ap_session *ses, const cha
username1[len + 1 + conf_default_realm_len] = 0;
username = username1;
}
+
+ rpd->auth_ctx = mempool_alloc(auth_ctx_pool);
+ memset(rpd->auth_ctx, 0, sizeof(rpd->auth_ctx));
+
+ rpd->auth_ctx->cb = cb;
+ rpd->auth_ctx->cb_arg = cb_arg;
va_copy(args, _args);
@@ -208,8 +215,12 @@ static int rad_pwdb_check(struct pwdb_t *pwdb, struct ap_session *ses, const cha
va_end(args);
- if (r == PWDB_SUCCESS)
- rpd->authenticated = 1;
+ if (r == PWDB_DENIED) {
+ if (rpd->auth_ctx->req)
+ rad_req_free(rpd->auth_ctx->req);
+ mempool_free(rpd->auth_ctx);
+ rpd->auth_ctx = NULL;
+ }
return r;
}
@@ -247,8 +258,6 @@ static struct ipv6db_prefix_t *get_ipv6_prefix(struct ap_session *ses)
return NULL;
}
-
-
static void session_timeout(struct triton_timer_t *t)
{
struct radius_pd_t *rpd = container_of(t, typeof(*rpd), session_timeout);
@@ -290,6 +299,7 @@ static void ses_starting(struct ap_session *ses)
memset(rpd, 0, sizeof(*rpd));
rpd->pd.key = &pd_key;
rpd->ses = ses;
+ rpd->refs = 1;
pthread_mutex_init(&rpd->lock, NULL);
INIT_LIST_HEAD(&rpd->plugin_list);
INIT_LIST_HEAD(&rpd->ipv6_addr.addr_list);
@@ -315,6 +325,9 @@ static void ses_acct_start(struct ap_session *ses)
{
struct radius_pd_t *rpd = find_pd(ses);
+ if (!conf_accounting)
+ return;
+
if (!rpd->authenticated)
return;
@@ -322,26 +335,35 @@ static void ses_acct_start(struct ap_session *ses)
ap_session_terminate(rpd->ses, TERM_NAS_ERROR, 0);
return;
}
-
+
+ ses->acct_start++;
+}
+
+static void ses_started(struct ap_session *ses)
+{
+ struct radius_pd_t *rpd = find_pd(ses);
+
if (rpd->session_timeout.expire_tv.tv_sec) {
rpd->session_timeout.expire = session_timeout;
triton_timer_add(ses->ctrl->ctx, &rpd->session_timeout, 0);
}
-
+
if (rpd->idle_timeout.period) {
rpd->idle_timeout.expire = idle_timeout;
triton_timer_add(ses->ctrl->ctx, &rpd->idle_timeout, 0);
}
}
+
static void ses_finishing(struct ap_session *ses)
{
struct radius_pd_t *rpd = find_pd(ses);
- if (!rpd->authenticated)
+ if (!rpd->acct_started)
return;
rad_acct_stop(rpd);
}
+
static void ses_finished(struct ap_session *ses)
{
struct radius_pd_t *rpd = find_pd(ses);
@@ -353,11 +375,19 @@ static void ses_finished(struct ap_session *ses)
pthread_mutex_unlock(&rpd->lock);
pthread_rwlock_unlock(&sessions_lock);
- if (rpd->auth_req)
- rad_req_free(rpd->auth_req);
+ if (rpd->auth_ctx) {
+ rad_server_req_cancel(rpd->auth_ctx->req);
+ rad_req_free(rpd->auth_ctx->req);
+ mempool_free(rpd->auth_ctx);
+ rpd->auth_ctx = NULL;
+ }
- if (rpd->acct_req)
- rad_req_free(rpd->acct_req);
+ if (rpd->acct_req) {
+ if (rpd->acct_started)
+ rad_acct_stop_defer(rpd);
+ else
+ rad_req_free(rpd->acct_req);
+ }
if (rpd->dm_coa_req)
dm_coa_cancel(rpd);
@@ -373,7 +403,7 @@ static void ses_finished(struct ap_session *ses)
if (rpd->attr_state)
_free(rpd->attr_state);
-
+
while (!list_empty(&rpd->ipv6_addr.addr_list)) {
a = list_entry(rpd->ipv6_addr.addr_list.next, typeof(*a), entry);
list_del(&a->entry);
@@ -388,7 +418,7 @@ static void ses_finished(struct ap_session *ses)
list_del(&rpd->pd.entry);
- mempool_free(rpd);
+ release_pd(rpd);
}
struct radius_pd_t *find_pd(struct ap_session *ses)
@@ -406,6 +436,16 @@ struct radius_pd_t *find_pd(struct ap_session *ses)
abort();
}
+void hold_pd(struct radius_pd_t *rpd)
+{
+ rpd->refs++;
+}
+
+void release_pd(struct radius_pd_t *rpd)
+{
+ if (--rpd->refs == 0)
+ mempool_free(rpd);
+}
struct radius_pd_t *rad_find_session(const char *sessionid, const char *username, const char *port_id, int port, in_addr_t ipaddr, const char *csid)
{
@@ -650,6 +690,7 @@ static void radius_init(void)
struct conf_option_t *opt1;
rpd_pool = mempool_create(sizeof(struct radius_pd_t));
+ auth_ctx_pool = mempool_create(sizeof(struct radius_auth_ctx));
if (load_config())
_exit(EXIT_FAILURE);
@@ -670,6 +711,7 @@ static void radius_init(void)
ipdb_register(&ipdb);
triton_event_register_handler(EV_SES_STARTING, (triton_event_func)ses_starting);
+ triton_event_register_handler(EV_SES_STARTED, (triton_event_func)ses_started);
triton_event_register_handler(EV_SES_ACCT_START, (triton_event_func)ses_acct_start);
triton_event_register_handler(EV_SES_FINISHING, (triton_event_func)ses_finishing);
triton_event_register_handler(EV_SES_FINISHED, (triton_event_func)ses_finished);
diff --git a/accel-pppd/radius/radius_p.h b/accel-pppd/radius/radius_p.h
index 8ad69da0..cfb92cd6 100644
--- a/accel-pppd/radius/radius_p.h
+++ b/accel-pppd/radius/radius_p.h
@@ -9,18 +9,32 @@
#include "radius.h"
#include "ppp.h"
#include "ipdb.h"
+#include "pwdb.h"
struct rad_server_t;
+struct radius_auth_ctx {
+ struct rad_req_t *req;
+ pwdb_callback cb;
+ void *cb_arg;
+ int (*recv)(struct rad_req_t *);
+
+ const uint8_t *challenge;
+ uint8_t *authenticator;
+ char **mschap_error;
+ char **reply_msg;
+};
+
struct radius_pd_t {
struct list_head entry;
struct ap_private pd;
struct ap_session *ses;
pthread_mutex_t lock;
+ int refs:8;
int authenticated:1;
+ int acct_started:1;
int ipv6_dp_assigned:1;
- struct rad_req_t *auth_req;
struct rad_req_t *acct_req;
struct triton_timer_t acct_interim_timer;
@@ -34,7 +48,6 @@ struct radius_pd_t {
struct ipv6db_item_t ipv6_addr;
struct ipv6db_prefix_t ipv6_dp;
int acct_interim_interval;
- time_t acct_timestamp;
uint8_t *attr_class;
int attr_class_len;
@@ -42,12 +55,13 @@ struct radius_pd_t {
int attr_state_len;
int termination_action;
+ struct radius_auth_ctx *auth_ctx;
+
struct list_head plugin_list;
};
struct rad_req_t {
struct list_head entry;
- struct triton_context_t ctx;
struct triton_md_handler_t hnd;
struct triton_timer_t timeout;
uint8_t RA[16];
@@ -56,11 +70,21 @@ struct rad_req_t {
struct radius_pd_t *rpd;
struct rad_server_t *serv;
- struct triton_context_t *wait_ctx;
in_addr_t server_addr;
- int server_port;
- int type;
+
+ int server_port:16;
+ int type:8;
+ int try:6;
+ int active:1;
+ int async:1;
+
+ time_t ts;
+
+ void (*recv)(struct rad_req_t *);
+ int (*before_send)(struct rad_req_t *);
+ int (*send)(struct rad_req_t *, int async);
+ void (*sent)(struct rad_req_t *, int res);
void (*log)(const char *fmt, ...);
};
@@ -149,13 +173,16 @@ void rad_dict_free(struct rad_dict_t *dict);
struct rad_req_t *rad_req_alloc(struct radius_pd_t *rpd, int code, const char *username);
struct rad_req_t *rad_req_alloc2(struct radius_pd_t *rpd, int code, const char *username, in_addr_t addr, int port);
+struct rad_req_t *rad_req_alloc_empty();
int rad_req_acct_fill(struct rad_req_t *);
void rad_req_free(struct rad_req_t *);
-int rad_req_send(struct rad_req_t *req, void (*log)(const char *fmt, ...));
-int rad_req_wait(struct rad_req_t *, int);
+int rad_req_send(struct rad_req_t *req);
+int rad_req_read(struct triton_md_handler_t *h);
struct radius_pd_t *find_pd(struct ap_session *ses);
int rad_proc_attrs(struct rad_req_t *req);
+void hold_pd(struct radius_pd_t *rpd);
+void release_pd(struct radius_pd_t *rpd);
int rad_auth_pap(struct radius_pd_t *rpd, const char *username, va_list args);
int rad_auth_chap_md5(struct radius_pd_t *rpd, const char *username, va_list args);
@@ -164,7 +191,8 @@ int rad_auth_mschap_v2(struct radius_pd_t *rpd, const char *username, va_list ar
int rad_auth_null(struct radius_pd_t *rpd, const char *username, va_list args);
int rad_acct_start(struct radius_pd_t *rpd);
-void rad_acct_stop(struct radius_pd_t *rpd);
+int rad_acct_stop(struct radius_pd_t *rpd);
+void rad_acct_stop_defer(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);
@@ -180,6 +208,7 @@ struct rad_server_t *rad_server_get2(int, in_addr_t, int);
void rad_server_put(struct rad_server_t *, int);
int rad_server_req_enter(struct rad_req_t *);
void rad_server_req_exit(struct rad_req_t *);
+int rad_server_req_cancel(struct rad_req_t *);
int rad_server_realloc(struct rad_req_t *);
void rad_server_fail(struct rad_server_t *);
void rad_server_timeout(struct rad_server_t *);
diff --git a/accel-pppd/radius/req.c b/accel-pppd/radius/req.c
index 27a33f25..172fb1c9 100644
--- a/accel-pppd/radius/req.c
+++ b/accel-pppd/radius/req.c
@@ -4,25 +4,26 @@
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
-#include <sched.h>
+#include <assert.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "log.h"
#include "radius_p.h"
+#include "mempool.h"
#include "memdebug.h"
-static int rad_req_read(struct triton_md_handler_t *h);
-static void rad_req_timeout(struct triton_timer_t *t);
static int make_socket(struct rad_req_t *req);
+static mempool_t req_pool;
static struct rad_req_t *__rad_req_alloc(struct radius_pd_t *rpd, int code, const char *username, in_addr_t addr, int port)
{
struct rad_plugin_t *plugin;
struct ppp_t *ppp = NULL;
- struct rad_req_t *req = _malloc(sizeof(*req));
+ struct rad_req_t *req = mempool_alloc(req_pool);
+ struct timespec ts;
if (!req) {
log_emerg("radius: out of memory\n");
@@ -32,10 +33,13 @@ static struct rad_req_t *__rad_req_alloc(struct radius_pd_t *rpd, int code, cons
if (rpd->ses->ctrl->ppp)
ppp = container_of(rpd->ses, typeof(*ppp), ses);
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+
memset(req, 0, sizeof(*req));
req->rpd = rpd;
req->hnd.fd = -1;
- req->ctx.before_switch = log_switch;
+ req->hnd.read = rad_req_read;
+ req->ts = ts.tv_sec;
req->type = code == CODE_ACCESS_REQUEST ? RAD_SERV_AUTH : RAD_SERV_ACCT;
@@ -161,6 +165,21 @@ struct rad_req_t *rad_req_alloc2(struct radius_pd_t *rpd, int code, const char *
return req;
}
+struct rad_req_t *rad_req_alloc_empty()
+{
+ struct rad_req_t *req = mempool_alloc(req_pool);
+
+ if (!req) {
+ log_emerg("radius: out of memory\n");
+ return NULL;
+ }
+
+ memset(req, 0, sizeof(*req));
+ req->hnd.fd = -1;
+
+ return req;
+}
+
int rad_req_acct_fill(struct rad_req_t *req)
{
struct ipv6db_addr_t *a;
@@ -211,15 +230,26 @@ int rad_req_acct_fill(struct rad_req_t *req)
void rad_req_free(struct rad_req_t *req)
{
+ assert(!req->active);
+
if (req->serv)
rad_server_put(req->serv, req->type);
- if (req->hnd.fd >= 0 )
+
+ if (req->hnd.tpd)
+ triton_md_unregister_handler(&req->hnd, 1);
+ else if (req->hnd.fd != -1)
close(req->hnd.fd);
+
+ if (req->timeout.tpd)
+ triton_timer_del(&req->timeout);
+
if (req->pack)
rad_packet_free(req->pack);
+
if (req->reply)
rad_packet_free(req->reply);
- _free(req);
+
+ mempool_free(req);
}
static int make_socket(struct rad_req_t *req)
@@ -231,7 +261,7 @@ static int make_socket(struct rad_req_t *req)
log_ppp_error("radius:socket: %s\n", strerror(errno));
return -1;
}
-
+
fcntl(req->hnd.fd, F_SETFD, fcntl(req->hnd.fd, F_GETFD) | FD_CLOEXEC);
memset(&addr, 0, sizeof(addr));
@@ -270,95 +300,120 @@ out_err:
return -1;
}
-int rad_req_send(struct rad_req_t *req, void (*log)(const char *fmt, ...))
+static int __rad_req_send(struct rad_req_t *req, int async)
{
+ if (async == -1) {
+ req->try = conf_max_try - 1;
+ rad_req_send(req);
+ return 0;
+ }
+
if (req->hnd.fd == -1 && make_socket(req))
return -1;
+
+ if (req->before_send && req->before_send(req))
+ goto out_err;
if (!req->pack->buf && rad_packet_build(req->pack, req->RA))
goto out_err;
- if (log) {
- log("send ");
- rad_packet_print(req->pack, req->serv, log);
+ if (req->log) {
+ req->log("send ");
+ rad_packet_print(req->pack, req->serv, req->log);
}
+
+ if (req->sent)
+ req->sent(req, 0);
rad_packet_send(req->pack, req->hnd.fd, NULL);
return 0;
out_err:
- close(req->hnd.fd);
- req->hnd.fd = -1;
+ if (req->hnd.tpd)
+ triton_md_unregister_handler(&req->hnd, 1);
+ else {
+ close(req->hnd.fd);
+ req->hnd.fd = -1;
+ }
+
+ if (async && req->sent)
+ req->sent(req, -1);
+
return -1;
}
-static void req_wakeup(struct rad_req_t *req)
-{
- struct triton_context_t *ctx = req->wait_ctx;
- if (req->timeout.tpd)
- triton_timer_del(&req->timeout);
- triton_md_unregister_handler(&req->hnd, 0);
- triton_context_unregister(&req->ctx);
- triton_context_wakeup(ctx);
-}
-static int rad_req_read(struct triton_md_handler_t *h)
+int rad_req_send(struct rad_req_t *req)
{
- 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;
+ req->send = __rad_req_send;
+
+ if (req->try++ == conf_max_try) {
+ rad_server_req_exit(req);
+ rad_server_fail(req->serv);
+
+ if (rad_server_realloc(req)) {
+ if (req->rpd)
+ log_ppp_warn("radius: no available servers\n");
+ return -1;
}
- if (r)
- break;
+ req->try = 1;
}
- req_wakeup(req);
-
- return 1;
-}
-static void rad_req_timeout(struct triton_timer_t *t)
-{
- struct rad_req_t *req = container_of(t, typeof(*req), timeout);
-
- req_wakeup(req);
+ if (!req->active) {
+ while (1) {
+ r = rad_server_req_enter(req);
+
+ if (r >= 0)
+ break;
+
+ if (rad_server_realloc(req)) {
+ if (req->rpd)
+ log_ppp_warn("radius: no available servers\n");
+ return -1;
+ }
+ }
+ } else
+ r = __rad_req_send(req, 0);
+
+ return r;
}
-int rad_req_wait(struct rad_req_t *req, int timeout)
+int rad_req_read(struct triton_md_handler_t *h)
{
- req->wait_ctx = triton_context_self();
- req->hnd.read = rad_req_read;
- req->timeout.expire = rad_req_timeout;
-
- triton_context_register(&req->ctx, req->rpd ? req->rpd->ses : NULL);
- triton_context_set_priority(&req->ctx, 1);
- triton_md_register_handler(&req->ctx, &req->hnd);
- triton_md_enable_handler(&req->hnd, MD_MODE_READ);
+ struct rad_req_t *req = container_of(h, typeof(*req), hnd);
+ struct rad_packet_t *pack;
- req->timeout.period = timeout * 1000;
- triton_timer_add(&req->ctx, &req->timeout, 0);
+ while (1) {
+ if (rad_packet_recv(h->fd, &pack, NULL))
+ return 0;
+
+ if (pack->id == req->pack->id)
+ break;
+
+ rad_packet_free(req->reply);
+ }
- triton_context_wakeup(&req->ctx);
+ req->reply = pack;
- triton_context_schedule();
+ rad_server_req_exit(req);
- if (req->log && req->reply) {
+ if (req->log) {
req->log("recv ");
rad_packet_print(req->reply, req->serv, req->log);
}
- return 0;
+
+ if (req->recv)
+ req->recv(req);
+
+ return 1;
}
static void req_init(void)
{
+ req_pool = mempool_create(sizeof(struct rad_req_t));
}
DEFINE_INIT(50, req_init);
diff --git a/accel-pppd/radius/serv.c b/accel-pppd/radius/serv.c
index 0910314a..6c01a886 100644
--- a/accel-pppd/radius/serv.c
+++ b/accel-pppd/radius/serv.c
@@ -100,6 +100,48 @@ void rad_server_put(struct rad_server_t *s, int type)
}
}
+static void req_wakeup(struct rad_req_t *req)
+{
+ struct timespec ts;
+
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+
+ pthread_mutex_lock(&req->serv->lock);
+
+ if (ts.tv_sec < req->serv->fail_time || req->serv->need_free) {
+ req->active = 0;
+ req->serv->req_cnt--;
+ pthread_mutex_unlock(&req->serv->lock);
+
+ req->send(req, -1);
+
+ return;
+ }
+ pthread_mutex_unlock(&req->serv->lock);
+
+ req->send(req, 1);
+}
+
+int rad_server_req_cancel(struct rad_req_t *req)
+{
+ int r = 0;
+
+ pthread_mutex_lock(&req->serv->lock);
+ if (req->entry.next) {
+ list_del(&req->entry);
+ req->serv->queue_cnt--;
+ r = 1;
+ }
+ pthread_mutex_unlock(&req->serv->lock);
+
+ rad_server_req_exit(req);
+
+ if (req->timeout.tpd)
+ triton_timer_del(&req->timeout);
+
+ return r;
+}
+
int rad_server_req_enter(struct rad_req_t *req)
{
struct timespec ts;
@@ -112,8 +154,13 @@ int rad_server_req_enter(struct rad_req_t *req)
if (ts.tv_sec < req->serv->fail_time)
return -1;
- if (!req->serv->req_limit)
+ if (!req->serv->req_limit) {
+ if (req->send)
+ return req->send(req, 0);
return 0;
+ }
+
+ assert(!req->active);
pthread_mutex_lock(&req->serv->lock);
@@ -123,46 +170,47 @@ int rad_server_req_enter(struct rad_req_t *req)
}
if (req->serv->req_cnt >= req->serv->req_limit) {
- list_add_tail(&req->entry, &req->serv->req_queue);
- req->serv->queue_cnt++;
-
- pthread_mutex_unlock(&req->serv->lock);
- triton_context_schedule();
- pthread_mutex_lock(&req->serv->lock);
-
- req->serv->queue_cnt--;
- if (ts.tv_sec < req->serv->fail_time || req->serv->need_free) {
+ if (req->send) {
+ list_add_tail(&req->entry, &req->serv->req_queue);
+ req->serv->queue_cnt++;
pthread_mutex_unlock(&req->serv->lock);
- return -1;
+ return 0;
}
+
+ pthread_mutex_unlock(&req->serv->lock);
+ return 1;
}
req->serv->req_cnt++;
log_ppp_debug("radius(%i): req_enter %i\n", req->serv->id, req->serv->req_cnt);
pthread_mutex_unlock(&req->serv->lock);
+
+ req->active = 1;
return 0;
}
void rad_server_req_exit(struct rad_req_t *req)
{
- struct rad_req_t *r = NULL;
-
if (!req->serv->req_limit)
return;
+ assert(req->active);
+
+ req->active = 0;
+
pthread_mutex_lock(&req->serv->lock);
req->serv->req_cnt--;
log_ppp_debug("radius(%i): req_exit %i\n", req->serv->id, req->serv->req_cnt);
assert(req->serv->req_cnt >= 0);
if (req->serv->req_cnt < req->serv->req_limit && !list_empty(&req->serv->req_queue)) {
- r = list_entry(req->serv->req_queue.next, typeof(*r), entry);
+ struct rad_req_t *r = list_entry(req->serv->req_queue.next, typeof(*r), entry);
list_del(&r->entry);
+ req->serv->queue_cnt--;
+ req->active = 1;
+ triton_context_call(r->rpd->ses->ctrl->ctx, (triton_event_func)req_wakeup, r);
}
pthread_mutex_unlock(&req->serv->lock);
-
- if (r)
- triton_context_wakeup(r->rpd->ses->ctrl->ctx);
}
int rad_server_realloc(struct rad_req_t *req)
@@ -214,7 +262,7 @@ void rad_server_fail(struct rad_server_t *s)
while (!list_empty(&s->req_queue)) {
r = list_entry(s->req_queue.next, typeof(*r), entry);
list_del(&r->entry);
- triton_context_wakeup(r->rpd->ses->ctrl->ctx);
+ triton_context_call(r->rpd->ses->ctrl->ctx, (triton_event_func)req_wakeup, r);
}
}
@@ -223,7 +271,7 @@ void rad_server_fail(struct rad_server_t *s)
void rad_server_timeout(struct rad_server_t *s)
{
- if (__sync_add_and_fetch(&s->timeout_cnt, 1) >= conf_max_try)
+ if (__sync_add_and_fetch(&s->timeout_cnt, 1) >= conf_max_try * 3)
rad_server_fail(s);
}
@@ -248,13 +296,49 @@ static int req_set_RA(struct rad_req_t *req, const char *secret)
return 0;
}
+static void acct_on_sent(struct rad_req_t *req, int res)
+{
+ if (!res && !req->hnd.tpd) {
+ triton_md_register_handler(&req->serv->ctx, &req->hnd);
+ triton_md_enable_handler(&req->hnd, MD_MODE_READ);
+ }
+}
+
+static void acct_on_recv(struct rad_req_t *req)
+{
+ struct rad_server_t *s = req->serv;
+
+ rad_req_free(req);
+
+ if (req->serv->starting) {
+ req->serv->starting = 0;
+ req->serv->acct_on = 1;
+ } else
+ __free_server(s);
+}
+
+static void acct_on_timeout(struct triton_timer_t *t)
+{
+ struct rad_req_t *req = container_of(t, typeof(*req), timeout);
+ struct rad_server_t *s = req->serv;
+
+ if (!s->starting && ++req->serv->req_cnt == conf_max_try) {
+ rad_req_free(req);
+ __free_server(s);
+ return;
+ }
+
+ req->try = 1;
+
+ rad_req_send(req);
+}
+
static void send_acct_on(struct rad_server_t *s)
{
struct rad_req_t *req = _malloc(sizeof(*req));
- int i;
if (!req)
- goto out_err;
+ return;
memset(req, 0, sizeof(*req));
req->hnd.fd = -1;
@@ -262,6 +346,12 @@ static void send_acct_on(struct rad_server_t *s)
req->server_addr = s->addr;
req->server_port = s->acct_port;
req->serv = s;
+ req->sent = acct_on_sent;
+ req->recv = acct_on_recv;
+ req->hnd.read = rad_req_read;
+ req->timeout.expire = acct_on_timeout;
+ req->timeout.period = conf_timeout * 1000;
+ req->try = 1;
__sync_add_and_fetch(&s->client_cnt[req->type], 1);
if (conf_verbose)
req->log = log_info1;
@@ -284,55 +374,14 @@ static void send_acct_on(struct rad_server_t *s)
if (req_set_RA(req, s->secret))
goto out_err;
- for (i = 0; i < conf_max_try; i++) {
- if (rad_req_send(req, conf_verbose ? log_info1 : NULL))
- goto out_err;
-
- rad_req_wait(req, conf_timeout);
-
- if (!s->starting)
- break;
+ rad_req_send(req);
- if (!req->reply)
- continue;
-
- if (req->reply->id == req->pack->id && req->reply->code == CODE_ACCOUNTING_RESPONSE) {
- s->starting = 0;
- s->acct_on = 1;
- break;
- }
-
- rad_packet_free(req->reply);
- req->reply = NULL;
- }
-
- if (!s->starting) {
- if (s->timer.tpd)
- triton_timer_del(&s->timer);
-
- if (!s->acct_on)
- triton_context_unregister(&s->ctx);
-
- rad_req_free(req);
+ triton_timer_add(&s->ctx, &req->timeout, 0);
- return;
- }
+ return;
out_err:
- if (req)
- rad_req_free(req);
-
- if (s->timer.tpd)
- triton_timer_mod(&s->timer, 0);
- else
- triton_timer_add(&s->ctx, &s->timer, 0);
-}
-
-static void restart_acct_on(struct triton_timer_t *t)
-{
- struct rad_server_t *s = container_of(t, typeof(*s), timer);
-
- send_acct_on(s);
+ rad_req_free(req);
}
static void serv_ctx_close(struct triton_context_t *ctx)
@@ -444,6 +493,14 @@ static void __add_server(struct rad_server_t *s)
s->stat_interim_lost_5m = stat_accm_create(5 * 60);
s->stat_interim_query_1m = stat_accm_create(60);
s->stat_interim_query_5m = stat_accm_create(5 * 60);
+
+ s->ctx.close = serv_ctx_close;
+
+ triton_context_register(&s->ctx, NULL);
+ triton_context_set_priority(&s->ctx, 1);
+ if (conf_acct_on)
+ triton_context_call(&s->ctx, (triton_event_func)send_acct_on, s);
+ triton_context_wakeup(&s->ctx);
}
static void __free_server(struct rad_server_t *s)
@@ -465,6 +522,8 @@ static void __free_server(struct rad_server_t *s)
stat_accm_free(s->stat_interim_query_1m);
stat_accm_free(s->stat_interim_query_5m);
+ triton_context_unregister(&s->ctx);
+
_free(s);
}
@@ -732,7 +791,7 @@ static void load_config(void)
while (!list_empty(&s->req_queue)) {
r = list_entry(s->req_queue.next, typeof(*r), entry);
list_del(&r->entry);
- triton_context_wakeup(r->rpd->ses->ctrl->ctx);
+ triton_context_call(r->rpd->ses->ctrl->ctx, (triton_event_func)req_wakeup, r);
}
if (!s->client_cnt[0] && !s->client_cnt[1]) {
@@ -756,18 +815,8 @@ static void load_config(void)
list_for_each_entry(s, &serv_list, entry) {
if (s->starting) {
- if (!conf_accounting || !s->acct_port)
+ if (!conf_accounting || !s->auth_port)
s->starting = 0;
- else {
- s->ctx.close = serv_ctx_close;
- s->timer.expire = restart_acct_on;
- s->timer.expire_tv.tv_sec = 10;
-
- triton_context_register(&s->ctx, NULL);
- triton_context_set_priority(&s->ctx, 1);
- triton_context_call(&s->ctx, (triton_event_func)send_acct_on, s);
- triton_context_wakeup(&s->ctx);
- }
}
}
}
diff --git a/accel-pppd/session.c b/accel-pppd/session.c
index cff5b302..6616f684 100644
--- a/accel-pppd/session.c
+++ b/accel-pppd/session.c
@@ -227,7 +227,7 @@ void __export ap_session_terminate(struct ap_session *ses, int cause, int hard)
ap_session_read_stats(ses, NULL);
triton_event_fire(EV_SES_FINISHING, ses);
-
+
ses->ctrl->terminate(ses, hard);
}
diff --git a/accel-pppd/triton/mempool.c b/accel-pppd/triton/mempool.c
index 4a3ec8b0..7e5a4ce2 100644
--- a/accel-pppd/triton/mempool.c
+++ b/accel-pppd/triton/mempool.c
@@ -15,7 +15,7 @@
#define DELAY 5
#endif
-//#define MEMPOOL_DISABLE
+#define MEMPOOL_DISABLE
#define MAGIC1 0x2233445566778899llu
#define PAGE_ORDER 5
@@ -136,72 +136,6 @@ void __export *mempool_alloc(mempool_t *pool)
return it->ptr;
}
-#else
-
-void __export *mempool_alloc_md(mempool_t *pool, const char *fname, int line)
-{
- struct _mempool_t *p = (struct _mempool_t *)pool;
- struct _item_t *it;
- uint32_t size = sizeof(*it) + p->size + 8;
-
- spin_lock(&p->lock);
- if (!list_empty(&p->items)) {
- it = list_entry(p->items.next, typeof(*it), entry);
-#ifdef VALGRIND
- if (it->timestamp + DELAY < time(NULL)) {
- VALGRIND_MAKE_MEM_DEFINED(&it->owner, size - sizeof(it->entry) - sizeof(it->timestamp));
- VALGRIND_MAKE_MEM_UNDEFINED(it->ptr, p->size);
-#endif
- list_del(&it->entry);
- list_add(&it->entry, &p->ditems);
- spin_unlock(&p->lock);
-
- it->fname = fname;
- it->line = line;
-
- --p->objects;
- __sync_sub_and_fetch(&triton_stat.mempool_available, size);
-
- it->magic1 = MAGIC1;
-
- return it->ptr;
-#ifdef VALGRIND
- }
-#endif
- }
- spin_unlock(&p->lock);
-
- if (p->mmap) {
- spin_lock(&mmap_lock);
- if (mmap_ptr + size >= mmap_endptr)
- mmap_grow();
- it = (struct _item_t *)mmap_ptr;
- mmap_ptr += size;
- spin_unlock(&mmap_lock);
- __sync_sub_and_fetch(&triton_stat.mempool_available, size);
- } else {
- it = md_malloc(size, fname, line);
- __sync_add_and_fetch(&triton_stat.mempool_allocated, size);
- }
-
- if (!it) {
- triton_log_error("mempool: out of memory");
- return NULL;
- }
- 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);
-
- return it->ptr;
-}
-#endif
void __export mempool_free(void *ptr)
{
@@ -258,6 +192,18 @@ void __export mempool_free(void *ptr)
}
+
+#else
+
+void __export *md_mempool_alloc(mempool_t *pool, const char *fname, int line)
+{
+ struct _mempool_t *p = (struct _mempool_t *)pool;
+
+ return md_malloc(p->size, fname, line);
+}
+#endif
+
+
#ifdef MEMDEBUG
void __export mempool_show(mempool_t *pool)
{
diff --git a/accel-pppd/triton/mempool.h b/accel-pppd/triton/mempool.h
index bdb3e712..53eebfb7 100644
--- a/accel-pppd/triton/mempool.h
+++ b/accel-pppd/triton/mempool.h
@@ -12,14 +12,15 @@ struct mempool_stat_t
typedef void * mempool_t;
mempool_t *mempool_create(int size);
mempool_t *mempool_create2(int size);
-void mempool_free(void*);
struct mempool_stat_t mempool_get_stat(void);
#ifdef MEMDEBUG
-void *mempool_alloc_md(mempool_t*, const char *fname, int line);
-#define mempool_alloc(pool) mempool_alloc_md(pool, __FILE__, __LINE__)
+void *md_mempool_alloc(mempool_t*, const char *fname, int line);
+#define mempool_alloc(pool) md_mempool_alloc(pool, __FILE__, __LINE__)
+#define mempool_free(ptr) md_free(ptr, __FILE__, __LINE__)
#else
void *mempool_alloc(mempool_t*);
+void mempool_free(void*);
#endif
#endif
diff --git a/accel-pppd/triton/triton.c b/accel-pppd/triton/triton.c
index 3c4de31d..5d6f31d1 100644
--- a/accel-pppd/triton/triton.c
+++ b/accel-pppd/triton/triton.c
@@ -569,7 +569,7 @@ static void ru_update(struct triton_timer_t *t)
void __export triton_register_init(int order, void (*func)(void))
{
- struct _triton_init_t *i1, *i = _malloc(sizeof(*i));
+ struct _triton_init_t *i1, *i = malloc(sizeof(*i));
struct list_head *p = init_list.next;
@@ -624,7 +624,7 @@ int __export triton_load_modules(const char *mod_sect)
i = list_entry(init_list.next, typeof(*i), entry);
i->func();
list_del(&i->entry);
- _free(i);
+ free(i);
}
return 0;