summaryrefslogtreecommitdiff
path: root/accel-pppd
diff options
context:
space:
mode:
Diffstat (limited to 'accel-pppd')
-rw-r--r--accel-pppd/accel-ppp.conf3
-rw-r--r--accel-pppd/accel-ppp.conf.511
-rw-r--r--accel-pppd/radius/acct.c20
-rw-r--r--accel-pppd/radius/auth.c10
-rw-r--r--accel-pppd/radius/radius.c5
-rw-r--r--accel-pppd/radius/radius_p.h10
-rw-r--r--accel-pppd/radius/req.c3
-rw-r--r--accel-pppd/radius/serv.c192
8 files changed, 175 insertions, 79 deletions
diff --git a/accel-pppd/accel-ppp.conf b/accel-pppd/accel-ppp.conf
index 7219ba39..b6427c20 100644
--- a/accel-pppd/accel-ppp.conf
+++ b/accel-pppd/accel-ppp.conf
@@ -85,7 +85,8 @@ nas-ip-address=127.0.0.1
gw-ip-address=192.168.100.1
#auth-server=127.0.0.1:1812,testing123 (obsolete)
#acct-server=127.0.0.1:1813,testing123 (obsolete)
-server=127.0.0.1,testing123
+#server=127.0.0.1,testing123 (obsolete)
+server=127.0.0.1,testing123,auth-port=1812,acct-port=1813,req-limit=0,fail-time=0
dae-server=127.0.0.1:3799,testing123
verbose=1
#timeout=3
diff --git a/accel-pppd/accel-ppp.conf.5 b/accel-pppd/accel-ppp.conf.5
index 955f1670..42749652 100644
--- a/accel-pppd/accel-ppp.conf.5
+++ b/accel-pppd/accel-ppp.conf.5
@@ -311,8 +311,15 @@ Specifies IP address, port and secret of authentication RADIUS server. (obsolete
.BI "acct-server=" x.x.x.x:port,secret
Specifies IP address, port and secret of accounting RADIUS server. (obsolete)
.TP
-.BI "server=" address,secret[,auth-port[,acct-port]]
-Specifies IP address, ports and secret of RADIUS server.
+.BI "server=" address,secret[,auth-port=1812][,acct-port=1813][,req-limit=0][,fail-time=0]
+Specifies IP address, secret, ports of RADIUS server.
+.br
+.B req-limit
+- number of simultaneous requests to server (0 - unlimited).
+.br
+.B fail-time
+- if server doesn't responds mark it as unavailable for this time (sec).
+.br
If you want to specify only authentication or accounting server then set auth-port/acct-port to zero.
You may specify multiple radius servers.
.TP
diff --git a/accel-pppd/radius/acct.c b/accel-pppd/radius/acct.c
index e6274741..76ad3299 100644
--- a/accel-pppd/radius/acct.c
+++ b/accel-pppd/radius/acct.c
@@ -185,7 +185,7 @@ static void rad_acct_timeout(struct triton_timer_t *t)
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->acct_secret);
+ req_set_RA(req, req->serv->secret);
}
__rad_req_send(req);
@@ -214,7 +214,7 @@ static void rad_acct_interim_update(struct triton_timer_t *t)
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->acct_secret);
+ req_set_RA(rpd->acct_req, rpd->acct_req->serv->secret);
__rad_req_send(rpd->acct_req);
@@ -254,7 +254,7 @@ int rad_acct_start(struct radius_pd_t *rpd)
time(&rpd->acct_timestamp);
- if (req_set_RA(rpd->acct_req, rpd->acct_req->serv->acct_secret))
+ if (req_set_RA(rpd->acct_req, rpd->acct_req->serv->secret))
goto out_err;
while (1) {
@@ -264,7 +264,7 @@ int rad_acct_start(struct radius_pd_t *rpd)
log_ppp_warn("radius:acct_start: no servers available\n");
goto out_err;
}
- if (req_set_RA(rpd->acct_req, rpd->acct_req->serv->acct_secret))
+ if (req_set_RA(rpd->acct_req, rpd->acct_req->serv->secret))
goto out_err;
continue;
}
@@ -273,7 +273,7 @@ int rad_acct_start(struct radius_pd_t *rpd)
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->acct_secret))
+ if (req_set_RA(rpd->acct_req, rpd->acct_req->serv->secret))
goto out_err;
}
@@ -319,7 +319,7 @@ int rad_acct_start(struct radius_pd_t *rpd)
log_ppp_warn("radius:acct_start: no servers available\n");
goto out_err;
}
- if (req_set_RA(rpd->acct_req, rpd->acct_req->serv->acct_secret))
+ if (req_set_RA(rpd->acct_req, rpd->acct_req->serv->secret))
goto out_err;
}
@@ -393,7 +393,7 @@ void rad_acct_stop(struct radius_pd_t *rpd)
}
rad_packet_change_val(rpd->acct_req->pack, NULL, "Acct-Status-Type", "Stop");
req_set_stat(rpd->acct_req, rpd->ppp);
- req_set_RA(rpd->acct_req, rpd->acct_req->serv->acct_secret);
+ req_set_RA(rpd->acct_req, rpd->acct_req->serv->secret);
/// !!! rad_req_add_val(rpd->acct_req, "Acct-Terminate-Cause", "");
if (rpd->acct_req->reply) {
@@ -410,7 +410,7 @@ void rad_acct_stop(struct radius_pd_t *rpd)
log_ppp_warn("radius:acct_stop: no servers available\n");
break;
}
- req_set_RA(rpd->acct_req, rpd->acct_req->serv->acct_secret);
+ req_set_RA(rpd->acct_req, rpd->acct_req->serv->secret);
continue;
}
@@ -419,7 +419,7 @@ void rad_acct_stop(struct radius_pd_t *rpd)
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->acct_secret))
+ if (req_set_RA(rpd->acct_req, rpd->acct_req->serv->secret))
break;
}
if (rad_req_send(rpd->acct_req, conf_verbose))
@@ -458,7 +458,7 @@ void rad_acct_stop(struct radius_pd_t *rpd)
log_ppp_warn("radius:acct_stop: no servers available\n");
break;
}
- req_set_RA(rpd->acct_req, rpd->acct_req->serv->acct_secret);
+ req_set_RA(rpd->acct_req, rpd->acct_req->serv->secret);
}
rad_req_free(rpd->acct_req);
diff --git a/accel-pppd/radius/auth.c b/accel-pppd/radius/auth.c
index becddf6d..3e5d281d 100644
--- a/accel-pppd/radius/auth.c
+++ b/accel-pppd/radius/auth.c
@@ -30,7 +30,7 @@ static int decrypt_chap_mppe_keys(struct rad_req_t *req, struct rad_attr_t *attr
memcpy(plain, attr->val.octets, 32);
MD5_Init(&md5_ctx);
- MD5_Update(&md5_ctx, req->serv->auth_secret, strlen(req->serv->auth_secret));
+ MD5_Update(&md5_ctx, req->serv->secret, strlen(req->serv->secret));
MD5_Update(&md5_ctx, req->pack->buf + 4, 16);
MD5_Final(md5, &md5_ctx);
@@ -38,7 +38,7 @@ static int decrypt_chap_mppe_keys(struct rad_req_t *req, struct rad_attr_t *attr
plain[i] ^= md5[i];
MD5_Init(&md5_ctx);
- MD5_Update(&md5_ctx, req->serv->auth_secret, strlen(req->serv->auth_secret));
+ MD5_Update(&md5_ctx, req->serv->secret, strlen(req->serv->secret));
MD5_Update(&md5_ctx, attr->val.octets, 16);
MD5_Final(md5, &md5_ctx);
@@ -74,7 +74,7 @@ static int decrypt_mppe_key(struct rad_req_t *req, struct rad_attr_t *attr, uint
}
MD5_Init(&md5_ctx);
- MD5_Update(&md5_ctx, req->serv->auth_secret, strlen(req->serv->auth_secret));
+ MD5_Update(&md5_ctx, req->serv->secret, strlen(req->serv->secret));
MD5_Update(&md5_ctx, req->pack->buf + 4, 16);
MD5_Update(&md5_ctx, attr->val.octets, 2);
MD5_Final(md5, &md5_ctx);
@@ -90,7 +90,7 @@ static int decrypt_mppe_key(struct rad_req_t *req, struct rad_attr_t *attr, uint
}
MD5_Init(&md5_ctx);
- MD5_Update(&md5_ctx, req->serv->auth_secret, strlen(req->serv->auth_secret));
+ MD5_Update(&md5_ctx, req->serv->secret, strlen(req->serv->secret));
MD5_Update(&md5_ctx, attr->val.octets + 2, 16);
MD5_Final(md5, &md5_ctx);
@@ -229,7 +229,7 @@ int rad_auth_pap(struct radius_pd_t *rpd, const char *username, va_list args)
if (!req)
return PWDB_DENIED;
- epasswd = encrypt_password(passwd, req->serv->auth_secret, req->RA, &epasswd_len);
+ epasswd = encrypt_password(passwd, req->serv->secret, req->RA, &epasswd_len);
if (!epasswd)
goto out;
diff --git a/accel-pppd/radius/radius.c b/accel-pppd/radius/radius.c
index 370572ab..c24522dc 100644
--- a/accel-pppd/radius/radius.c
+++ b/accel-pppd/radius/radius.c
@@ -43,6 +43,7 @@ int conf_acct_interim_interval;
int conf_accounting;
int conf_fail_time;
+int conf_req_limit;
static LIST_HEAD(sessions);
static pthread_rwlock_t sessions_lock = PTHREAD_RWLOCK_INITIALIZER;
@@ -535,6 +536,10 @@ static int load_config(void)
if (opt)
conf_fail_time = atoi(opt);
+ opt = conf_get_opt("radius", "req-limit");
+ if (opt)
+ conf_fail_time = atoi(opt);
+
return 0;
}
diff --git a/accel-pppd/radius/radius_p.h b/accel-pppd/radius/radius_p.h
index e038aa84..7422bbf3 100644
--- a/accel-pppd/radius/radius_p.h
+++ b/accel-pppd/radius/radius_p.h
@@ -70,14 +70,13 @@ struct rad_server_t
{
struct list_head entry;
int id;
- in_addr_t auth_addr;
+ in_addr_t addr;
+ char *secret;
int auth_port;
- char *auth_secret;
- in_addr_t acct_addr;
int acct_port;
- char *acct_secret;
- int max_req_cnt;
+ int req_limit;
int req_cnt;
+ int queue_cnt;
struct list_head req_queue;
int client_cnt[2];
time_t fail_time;
@@ -133,6 +132,7 @@ extern int conf_dm_coa_port;
extern int conf_acct_interim_interval;
extern int conf_accounting;
extern int conf_fail_time;
+extern int conf_req_limit;
int rad_check_nas_pack(struct rad_packet_t *pack);
struct radius_pd_t *rad_find_session(const char *sessionid, const char *username, int port_id, in_addr_t ipaddr, const char *csid);
diff --git a/accel-pppd/radius/req.c b/accel-pppd/radius/req.c
index 387cdd14..ed69846f 100644
--- a/accel-pppd/radius/req.c
+++ b/accel-pppd/radius/req.c
@@ -40,7 +40,7 @@ struct rad_req_t *rad_req_alloc(struct radius_pd_t *rpd, int code, const char *u
if (!req->serv)
goto out_err;
- req->server_addr = req->serv->auth_addr;
+ req->server_addr = req->serv->addr;
req->server_port = req->serv->auth_port;
while (1) {
@@ -111,7 +111,6 @@ int rad_req_acct_fill(struct rad_req_t *req)
{
struct ipv6db_addr_t *a;
- req->server_addr = req->serv->acct_addr;
req->server_port = req->serv->acct_port;
memset(req->RA, 0, sizeof(req->RA));
diff --git a/accel-pppd/radius/serv.c b/accel-pppd/radius/serv.c
index 6c283248..30219f75 100644
--- a/accel-pppd/radius/serv.c
+++ b/accel-pppd/radius/serv.c
@@ -38,9 +38,9 @@ static struct rad_server_t *__rad_server_get(int type, struct rad_server_t *excl
if (s->fail_time && ts.tv_sec < s->fail_time)
continue;
- if (type == RAD_SERV_AUTH && !s->auth_addr)
+ if (type == RAD_SERV_AUTH && !s->auth_port)
continue;
- else if (type == RAD_SERV_ACCT && !s->acct_addr)
+ else if (type == RAD_SERV_ACCT && !s->acct_port)
continue;
if (!s0) {
@@ -85,7 +85,7 @@ int rad_server_req_enter(struct rad_req_t *req)
if (ts.tv_sec < req->serv->fail_time)
return -1;
- if (!req->serv->max_req_cnt)
+ if (!req->serv->req_limit)
return 0;
pthread_mutex_lock(&req->serv->lock);
@@ -95,13 +95,15 @@ int rad_server_req_enter(struct rad_req_t *req)
return -1;
}
- if (req->serv->req_cnt >= req->serv->max_req_cnt) {
+ 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) {
pthread_mutex_unlock(&req->serv->lock);
return -1;
@@ -118,12 +120,12 @@ void rad_server_req_exit(struct rad_req_t *req)
{
struct rad_req_t *r = NULL;
- if (!req->serv->max_req_cnt)
+ if (!req->serv->req_limit)
return;
pthread_mutex_lock(&req->serv->lock);
req->serv->req_cnt--;
- if (req->serv->req_cnt < req->serv->max_req_cnt && !list_empty(&req->serv->req_queue)) {
+ 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);
}
@@ -152,13 +154,11 @@ int rad_server_realloc(struct rad_req_t *req)
req->hnd.fd = -1;
}
- if (req->type == RAD_SERV_ACCT) {
- req->server_addr = req->serv->acct_addr;
+ req->server_addr = req->serv->addr;
+ if (req->type == RAD_SERV_ACCT)
req->server_port = req->serv->acct_port;
- } else {
- req->server_addr = req->serv->auth_addr;
+ else
req->server_port = req->serv->auth_port;
- }
return 0;
}
@@ -207,7 +207,7 @@ static void show_stat(struct rad_server_t *s, void *client)
char addr[17];
struct timespec ts;
- u_inet_ntoa(s->auth_addr ? s->auth_addr : s->acct_addr, addr);
+ u_inet_ntoa(s->addr, addr);
clock_gettime(CLOCK_MONOTONIC, &ts);
cli_sendv(client, "radius(%i, %s):\r\n", s->id, addr);
@@ -220,8 +220,11 @@ static void show_stat(struct rad_server_t *s, void *client)
cli_sendv(client, " fail count: %lu\r\n", s->stat_fail_cnt);
}
+
+ cli_sendv(client, " request count: %lu\r\n", s->req_cnt);
+ cli_sendv(client, " queue length: %lu\r\n", s->queue_cnt);
- if (s->auth_addr) {
+ if (s->auth_port) {
cli_sendv(client, " auth sent: %lu\r\n", s->stat_auth_sent);
cli_sendv(client, " auth lost(total/5m/1m): %lu/%lu/%lu\r\n",
s->stat_auth_lost, stat_accm_get_cnt(s->stat_auth_lost_5m), stat_accm_get_cnt(s->stat_auth_lost_1m));
@@ -229,7 +232,7 @@ static void show_stat(struct rad_server_t *s, void *client)
stat_accm_get_avg(s->stat_auth_query_5m), stat_accm_get_avg(s->stat_auth_query_1m));
}
- if (s->acct_addr) {
+ if (s->acct_port) {
cli_sendv(client, " acct sent: %lu\r\n", s->stat_acct_sent);
cli_sendv(client, " acct lost(total/5m/1m): %lu/%lu/%lu\r\n",
s->stat_acct_lost, stat_accm_get_cnt(s->stat_acct_lost_5m), stat_accm_get_cnt(s->stat_acct_lost_1m));
@@ -259,8 +262,9 @@ static void __add_server(struct rad_server_t *s)
struct rad_server_t *s1;
list_for_each_entry(s1, &serv_list, entry) {
- if (s1->auth_addr == s->auth_addr && s1->acct_addr == s->acct_addr) {
- s1->conf_fail_time = conf_fail_time;
+ if (s1->addr == s->addr && s1->auth_port == s->auth_port && s1->acct_port == s->acct_port) {
+ s1->conf_fail_time = s->conf_fail_time;
+ s1->req_limit = s->req_limit;
s1->need_free = 0;
_free(s);
return;
@@ -270,7 +274,6 @@ static void __add_server(struct rad_server_t *s)
s->id = ++num;
INIT_LIST_HEAD(&s->req_queue);
pthread_mutex_init(&s->lock, NULL);
- s->conf_fail_time = conf_fail_time;
list_add_tail(&s->entry, &serv_list);
s->stat_auth_lost_1m = stat_accm_create(60);
@@ -334,12 +337,8 @@ static int parse_server_old(const char *opt, in_addr_t *addr, int *port, char **
return -1;
}
- p1 = _strdup(p2 + 1);
- p2 = *secret;
- *secret = p1;
- if (p2)
- _free(p2);
-
+ *secret = _strdup(p2 + 1);
+
_free(str);
return 0;
@@ -348,37 +347,59 @@ static int parse_server_old(const char *opt, in_addr_t *addr, int *port, char **
static void add_server_old(void)
{
const char *opt;
- struct rad_server_t *s = _malloc(sizeof(*s));
-
- memset(s, 0, sizeof(*s));
+ in_addr_t auth_addr = 0;
+ int auth_port;
+ char *auth_secret;
+ in_addr_t acct_addr = 0;
+ int acct_port;
+ char *acct_secret;
+ struct rad_server_t *s;
opt = conf_get_opt("radius", "auth-server");
if (opt) {
- if (parse_server_old(opt, &s->auth_addr, &s->auth_port, &s->auth_secret)) {
+ if (parse_server_old(opt, &auth_addr, &auth_port, &auth_secret)) {
log_emerg("radius: failed to parse 'auth-server'\n");
- goto out;
+ return;
}
- }
+ } else
+ return;
opt = conf_get_opt("radius", "acct-server");
if (opt) {
- if (parse_server_old(opt, &s->acct_addr, &s->acct_port, &s->acct_secret)) {
+ if (parse_server_old(opt, &acct_addr, &acct_port, &acct_secret)) {
log_emerg("radius: failed to parse 'acct-server'\n");
- goto out;
+ return;
}
conf_accounting = 1;
}
- if (s->auth_addr || s->acct_addr) {
+ s = _malloc(sizeof(*s));
+ memset(s, 0, sizeof(*s));
+ s->addr = auth_addr;
+ s->secret = auth_secret;
+ s->auth_port = auth_port;
+ s->conf_fail_time = conf_fail_time;
+
+ if (auth_addr == acct_addr && !strcmp(auth_secret, acct_secret)) {
+ s->acct_port = acct_port;
__add_server(s);
return;
}
+
+ __add_server(s);
-out:
- _free(s);
+ if (acct_addr) {
+ s = _malloc(sizeof(*s));
+ memset(s, 0, sizeof(*s));
+ s->addr = acct_addr;
+ s->secret = acct_secret;
+ s->acct_port = acct_port;
+ s->conf_fail_time = conf_fail_time;
+ __add_server(s);
+ }
}
-static int parse_server(const char *_opt, struct rad_server_t *s)
+static int parse_server1(const char *_opt, struct rad_server_t *s)
{
char *opt = _strdup(_opt);
char *ptr1, *ptr2, *ptr3, *endptr;
@@ -400,7 +421,7 @@ static int parse_server(const char *_opt, struct rad_server_t *s)
if (ptr3)
*ptr3 = 0;
- s->auth_addr = s->acct_addr = inet_addr(opt);
+ s->addr = inet_addr(opt);
if (ptr2) {
if (ptr2[1]) {
@@ -408,8 +429,6 @@ static int parse_server(const char *_opt, struct rad_server_t *s)
if (*endptr)
goto out;
}
- if (!s->auth_port)
- s->auth_addr = 0;
} else
s->auth_port = 1812;
@@ -419,21 +438,73 @@ static int parse_server(const char *_opt, struct rad_server_t *s)
if (*endptr)
goto out;
}
- if (!s->acct_port)
- s->acct_addr = 0;
} else
s->acct_port = 1813;
- if (!s->auth_addr && !s->acct_addr)
+ s->secret = _strdup(ptr1 + 1);
+ s->conf_fail_time = conf_fail_time;
+
+ return 0;
+
+out:
+ _free(opt);
+
+ return -1;
+}
+
+static int parse_server2(const char *_opt, struct rad_server_t *s)
+{
+ char *opt = _strdup(_opt);
+ char *ptr1, *ptr2, *ptr3, *endptr;
+
+ ptr1 = strchr(opt, ',');
+ if (!ptr1)
goto out;
+
+ ptr2 = strchr(ptr1 + 1, ',');
+
+ *ptr1 = 0;
+
+ s->addr = inet_addr(opt);
+
+ ptr3 = strstr(ptr2, ",auth-port=");
+ if (ptr3) {
+ s->auth_port = strtol(ptr3 + 11, &endptr, 10);
+ if (*endptr != ',' && *endptr != 0)
+ goto out;
+ } else
+ s->auth_port = 1812;
+
+ ptr3 = strstr(ptr2, ",acct-port=");
+ if (ptr3) {
+ s->acct_port = strtol(ptr3 + 11, &endptr, 10);
+ if (*endptr != ',' && *endptr != 0)
+ goto out;
+ } else
+ s->acct_port = 1813;
+
+ ptr3 = strstr(ptr2, ",req-limit=");
+ if (ptr3) {
+ s->req_limit = strtol(ptr3 + 11, &endptr, 10);
+ if (*endptr != ',' && *endptr != 0)
+ goto out;
+ } else
+ s->req_limit = conf_req_limit;
+
+ ptr3 = strstr(ptr2, ",fail-time=");
+ if (ptr3) {
+ s->conf_fail_time = strtol(ptr3 + 11, &endptr, 10);
+ if (*endptr != ',' && *endptr != 0)
+ goto out;
+ } else
+ s->conf_fail_time = conf_fail_time;
+
+ if (ptr2)
+ *ptr2 = 0;
- if (s->auth_addr)
- s->auth_secret = _strdup(ptr1 + 1);
+ s->secret = _strdup(ptr1 + 1);
- if (s->acct_addr) {
- s->acct_secret = _strdup(ptr1 + 1);
- conf_accounting = 1;
- }
+ _free(opt);
return 0;
@@ -449,12 +520,17 @@ static void add_server(const char *opt)
memset(s, 0, sizeof(*s));
- if (parse_server(opt, s)) {
- log_emerg("radius: failed to parse '%s'\n", opt);
- _free(s);
- return;
- }
+ if (!parse_server1(opt,s))
+ goto add;
+
+ if (!parse_server2(opt,s))
+ goto add;
+ log_emerg("radius: failed to parse '%s'\n", opt);
+ _free(s);
+ return;
+
+add:
__add_server(s);
}
@@ -490,12 +566,20 @@ static void load_config(void)
__free_server(s);
}
}
+
+ add_server_old();
+
+ conf_accounting = 0;
+ list_for_each_entry(s, &serv_list, entry) {
+ if (s->acct_port) {
+ conf_accounting = 1;
+ break;
+ }
+ }
}
static void init(void)
{
- add_server_old();
-
load_config();
triton_event_register_handler(EV_CONFIG_RELOAD, (triton_event_func)load_config);