summaryrefslogtreecommitdiff
path: root/accel-pppd
diff options
context:
space:
mode:
authorDmitry Kozlov <xeb@mail.ru>2014-07-11 14:30:43 +0400
committerDmitry Kozlov <xeb@mail.ru>2014-07-11 14:30:43 +0400
commitca96af9c783f0aa01d89f3226e91014a77f7624f (patch)
treed4aa17ce2ff17e6fe2e04a8c1cdb3b87b746a1f7 /accel-pppd
parent1cc4499b0244ccd82c2f99d1a2c3ff6632bd5b40 (diff)
downloadaccel-ppp-ca96af9c783f0aa01d89f3226e91014a77f7624f.tar.gz
accel-ppp-ca96af9c783f0aa01d89f3226e91014a77f7624f.zip
radius: fixed handling socket errors during interim updates
Diffstat (limited to 'accel-pppd')
-rw-r--r--accel-pppd/radius/acct.c31
-rw-r--r--accel-pppd/radius/req.c8
-rw-r--r--accel-pppd/radius/serv.c6
3 files changed, 32 insertions, 13 deletions
diff --git a/accel-pppd/radius/acct.c b/accel-pppd/radius/acct.c
index dc14bccf..0c7a6759 100644
--- a/accel-pppd/radius/acct.c
+++ b/accel-pppd/radius/acct.c
@@ -66,6 +66,8 @@ static int rad_acct_read(struct triton_md_handler_t *h)
struct rad_packet_t *pack;
int r;
unsigned int dt;
+
+ rad_server_req_exit(req);
if (req->reply) {
rad_packet_free(req->reply);
@@ -112,7 +114,7 @@ static int rad_acct_read(struct triton_md_handler_t *h)
return 1;
}
-static void __rad_req_send(struct rad_req_t *req)
+static int __rad_req_send(struct rad_req_t *req)
{
while (1) {
if (rad_server_req_enter(req)) {
@@ -121,34 +123,41 @@ static void __rad_req_send(struct rad_req_t *req)
log_ppp_warn("radius:acct: no servers available, terminating session...\n");
ap_session_terminate(req->rpd->ses, TERM_NAS_ERROR, 0);
}
- break;
+ return -1;
}
continue;
}
- rad_req_send(req, conf_interim_verbose ? log_ppp_info2 : NULL);
+ 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);
}
- rad_server_req_exit(req);
-
break;
}
+
+ return 0;
}
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;
+
+ rad_server_req_exit(req);
+ rad_server_timeout(req->serv);
__sync_add_and_fetch(&req->serv->stat_interim_lost, 1);
stat_accm_add(req->serv->stat_interim_lost_1m, 1);
stat_accm_add(req->serv->stat_interim_lost_5m, 1);
if (conf_acct_timeout == 0) {
- rad_server_timeout(req->serv);
triton_timer_del(t);
triton_md_unregister_handler(&req->hnd, 1);
return;
@@ -183,7 +192,8 @@ static void rad_acct_timeout(struct triton_timer_t *t)
req_set_RA(req, req->serv->secret);
}
- __rad_req_send(req);
+ if (__rad_req_send(req))
+ return;
__sync_add_and_fetch(&req->serv->stat_interim_sent, 1);
}
@@ -211,7 +221,9 @@ static void rad_acct_interim_update(struct triton_timer_t *t)
rad_packet_change_int(rpd->acct_req->pack, NULL, "Acct-Delay-Time", 0);
req_set_RA(rpd->acct_req, rpd->acct_req->serv->secret);
- __rad_req_send(rpd->acct_req);
+ if (__rad_req_send(rpd->acct_req))
+ return;
+
/* 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;
@@ -367,8 +379,9 @@ void rad_acct_stop(struct radius_pd_t *rpd)
if (!rpd->acct_req || !rpd->acct_req->serv)
return;
- if (rpd->acct_interim_timer.tpd)
+ if (rpd->acct_interim_timer.tpd) {
triton_timer_del(&rpd->acct_interim_timer);
+ }
if (rpd->acct_req) {
if (rpd->acct_req->hnd.tpd)
diff --git a/accel-pppd/radius/req.c b/accel-pppd/radius/req.c
index d688f58a..27a33f25 100644
--- a/accel-pppd/radius/req.c
+++ b/accel-pppd/radius/req.c
@@ -261,8 +261,12 @@ static int make_socket(struct rad_req_t *req)
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;
+ }
return -1;
}
diff --git a/accel-pppd/radius/serv.c b/accel-pppd/radius/serv.c
index 46d064a0..3d01057a 100644
--- a/accel-pppd/radius/serv.c
+++ b/accel-pppd/radius/serv.c
@@ -6,6 +6,7 @@
#include <unistd.h>
#include <sched.h>
#include <time.h>
+#include <assert.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
@@ -151,6 +152,7 @@ void rad_server_req_exit(struct rad_req_t *req)
pthread_mutex_lock(&req->serv->lock);
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);
list_del(&r->entry);
@@ -200,8 +202,8 @@ void rad_server_fail(struct rad_server_t *s)
pthread_mutex_lock(&s->lock);
- if (ts.tv_sec > s->fail_time) {
- s->fail_time = ts.tv_sec + s->conf_fail_time;
+ if (ts.tv_sec >= s->fail_time) {
+ s->fail_time = ts.tv_sec + s->conf_fail_time + 1;
log_ppp_warn("radius: server(%i) not responding\n", s->id);
log_warn("radius: server(%i) not responding\n", s->id);
}