提交 dc9638c5 编写于 作者: D Dmitry Kozlov

radius: split request queue to 2 subqueues

1 - is high priority queue for Access-Request and Account-Request(Start)
2 - is low priority queue for Account-Request(Alive) and Account-Request(Stop)
This patch intended to prioritize sessions connecting requests over disconnects and interim updates.
上级 f6bf7222
......@@ -262,6 +262,7 @@ static void rad_acct_start_recv(struct rad_req_t *req)
req->recv = rad_acct_recv;
req->sent = rad_acct_sent;
req->log = conf_interim_verbose ? log_ppp_info2 : NULL;
req->prio = 1;
} else {
rad_req_free(rpd->acct_req);
rpd->acct_req = NULL;
......@@ -291,7 +292,7 @@ static void rad_acct_start_timeout(struct triton_timer_t *t)
int rad_acct_start(struct radius_pd_t *rpd)
{
struct rad_req_t *req = rad_req_alloc(rpd, CODE_ACCOUNTING_REQUEST, rpd->ses->username);
struct rad_req_t *req = rad_req_alloc(rpd, CODE_ACCOUNTING_REQUEST, rpd->ses->username, 0);
if (!req)
return -1;
......@@ -448,7 +449,7 @@ int rad_acct_stop(struct radius_pd_t *rpd)
req->ts = ts.tv_sec;
req->try = 0;
} else {
req = rad_req_alloc(rpd, CODE_ACCOUNTING_REQUEST, rpd->ses->username);
req = rad_req_alloc(rpd, CODE_ACCOUNTING_REQUEST, rpd->ses->username, 1);
if (!req)
return -1;
......
......@@ -232,7 +232,7 @@ static void rad_auth_sent(struct rad_req_t *req, int res)
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);
struct rad_req_t *req = rad_req_alloc(rpd, CODE_ACCESS_REQUEST, username, 0);
if (!req)
return NULL;
......
......@@ -83,8 +83,10 @@ struct rad_req_t {
in_addr_t server_addr;
int server_port;
int type:8;
int try:6;
int type;
int prio;
int try;
int active:1;
int async:1;
......@@ -113,7 +115,7 @@ struct rad_server_t {
int fail_timeout;
int max_fail;
struct list_head req_queue;
struct list_head req_queue[2];
int client_cnt[2];
time_t fail_time;
int timeout_cnt;
......@@ -180,7 +182,7 @@ struct radius_pd_t *rad_find_session_pack(struct rad_packet_t *pack);
int rad_dict_load(const char *fname);
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_alloc(struct radius_pd_t *rpd, int code, const char *username, int prio);
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 *);
......
......@@ -18,7 +18,7 @@
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)
static struct rad_req_t *__rad_req_alloc(struct radius_pd_t *rpd, int code, const char *username, in_addr_t addr, int port, int prio)
{
struct rad_plugin_t *plugin;
struct ppp_t *ppp = NULL;
......@@ -42,6 +42,7 @@ static struct rad_req_t *__rad_req_alloc(struct radius_pd_t *rpd, int code, cons
req->ts = ts.tv_sec;
req->type = code == CODE_ACCESS_REQUEST ? RAD_SERV_AUTH : RAD_SERV_ACCT;
req->prio = prio;
if (addr)
req->serv = rad_server_get2(req->type, addr, port);
......@@ -142,14 +143,14 @@ out_err:
return NULL;
}
struct rad_req_t *rad_req_alloc(struct radius_pd_t *rpd, int code, const char *username)
struct rad_req_t *rad_req_alloc(struct radius_pd_t *rpd, int code, const char *username, int prio)
{
return __rad_req_alloc(rpd, code, username, 0, 0);
return __rad_req_alloc(rpd, code, username, 0, 0, prio);
}
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 *req = __rad_req_alloc(rpd, code, username, addr, port);
struct rad_req_t *req = __rad_req_alloc(rpd, code, username, addr, port, 0);
if (!req)
return NULL;
......
......@@ -204,7 +204,7 @@ int rad_server_req_enter(struct rad_req_t *req)
if (req->serv->req_cnt >= req->serv->req_limit) {
if (req->send) {
list_add_tail(&req->entry, &req->serv->req_queue);
list_add_tail(&req->entry, &req->serv->req_queue[req->prio]);
req->serv->queue_cnt++;
log_ppp_debug("radius(%i): queue %p\n", req->serv->id, req);
pthread_mutex_unlock(&req->serv->lock);
......@@ -236,6 +236,8 @@ int rad_server_req_enter(struct rad_req_t *req)
void rad_server_req_exit(struct rad_req_t *req)
{
struct rad_server_t *serv = req->serv;
if (!req->serv->req_limit)
return;
......@@ -243,20 +245,28 @@ void rad_server_req_exit(struct rad_req_t *req)
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)) {
struct rad_req_t *r = list_entry(req->serv->req_queue.next, typeof(*r), entry);
log_ppp_debug("radius(%i): wakeup %p\n", req->serv->id, r);
list_del(&r->entry);
req->serv->queue_cnt--;
req->serv->req_cnt++;
r->active = 1;
triton_context_call(r->rpd ? r->rpd->ses->ctrl->ctx : NULL, (triton_event_func)req_wakeup, r);
pthread_mutex_lock(&serv->lock);
serv->req_cnt--;
log_ppp_debug("radius(%i): req_exit %i\n", serv->id, serv->req_cnt);
assert(serv->req_cnt >= 0);
if (serv->req_cnt < serv->req_limit) {
struct list_head *list = NULL;
if (!list_empty(&serv->req_queue[0]))
list = &serv->req_queue[0];
else if (!list_empty(&serv->req_queue[1]))
list = &serv->req_queue[1];
if (list) {
struct rad_req_t *r = list_entry(list->next, typeof(*r), entry);
log_ppp_debug("radius(%i): wakeup %p\n", serv->id, r);
list_del(&r->entry);
serv->queue_cnt--;
serv->req_cnt++;
r->active = 1;
triton_context_call(r->rpd ? r->rpd->ses->ctrl->ctx : NULL, (triton_event_func)req_wakeup, r);
}
}
pthread_mutex_unlock(&req->serv->lock);
pthread_mutex_unlock(&serv->lock);
}
int rad_server_realloc(struct rad_req_t *req)
......@@ -304,11 +314,18 @@ void rad_server_fail(struct rad_server_t *s)
log_warn("radius: server(%i) not responding\n", s->id);
}
while (!list_empty(&s->req_queue)) {
r = list_entry(s->req_queue.next, typeof(*r), entry);
while (!list_empty(&s->req_queue[0])) {
r = list_entry(s->req_queue[0].next, typeof(*r), entry);
list_del(&r->entry);
triton_context_call(r->rpd ? r->rpd->ses->ctrl->ctx : NULL, (triton_event_func)req_wakeup_failed, r);
}
while (!list_empty(&s->req_queue[1])) {
r = list_entry(s->req_queue[1].next, typeof(*r), entry);
list_del(&r->entry);
triton_context_call(r->rpd ? r->rpd->ses->ctrl->ctx : NULL, (triton_event_func)req_wakeup_failed, r);
}
s->queue_cnt = 0;
s->stat_fail_cnt++;
......@@ -524,7 +541,8 @@ static void __add_server(struct rad_server_t *s)
}
s->id = ++num;
INIT_LIST_HEAD(&s->req_queue);
INIT_LIST_HEAD(&s->req_queue[0]);
INIT_LIST_HEAD(&s->req_queue[1]);
pthread_mutex_init(&s->lock, NULL);
list_add_tail(&s->entry, &serv_list);
s->starting = conf_acct_on;
......@@ -883,8 +901,14 @@ static void load_config(void)
if (s->need_free) {
list_del(&s->entry);
while (!list_empty(&s->req_queue)) {
r = list_entry(s->req_queue.next, typeof(*r), entry);
while (!list_empty(&s->req_queue[0])) {
r = list_entry(s->req_queue[0].next, typeof(*r), entry);
list_del(&r->entry);
triton_context_call(r->rpd->ses->ctrl->ctx, (triton_event_func)req_wakeup, r);
}
while (!list_empty(&s->req_queue[1])) {
r = list_entry(s->req_queue[1].next, typeof(*r), entry);
list_del(&r->entry);
triton_context_call(r->rpd->ses->ctrl->ctx, (triton_event_func)req_wakeup, r);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册