diff options
author | venaas <venaas> | 2008-03-31 15:57:10 +0000 |
---|---|---|
committer | venaas <venaas@e88ac4ed-0b26-0410-9574-a7f39faa03bf> | 2008-03-31 15:57:10 +0000 |
commit | 740f81cdc46efebbdabfb8f21655e29fa643eb1d (patch) | |
tree | 5497a07f22d1803b4a59113f7d83c1a4c8f29570 /radsecproxy.c | |
parent | 7a070897b7ec293e71c02a0e159b5188ab656405 (diff) |
fixed crash when trying to send replies back to disconnected client
git-svn-id: https://svn.testnett.uninett.no/radsecproxy/branches/release-1.1@224 e88ac4ed-0b26-0410-9574-a7f39faa03bf
Diffstat (limited to 'radsecproxy.c')
-rw-r--r-- | radsecproxy.c | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/radsecproxy.c b/radsecproxy.c index cb06f7a..3dc6169 100644 --- a/radsecproxy.c +++ b/radsecproxy.c @@ -436,13 +436,38 @@ struct client *addclient(struct clsrvconf *conf) { } void removeclient(struct client *client) { + struct list_node *entry; + if (!client || !client->conf->clients) return; + pthread_mutex_lock(&client->replyq->mutex); + for (entry = list_first(client->replyq->replies); entry; entry = list_next(entry)) + free(((struct reply *)entry)->buf); + list_destroy(client->replyq->replies); + pthread_mutex_unlock(&client->replyq->mutex); list_removedata(client->conf->clients, client); free(client); } +void removeclientrqs(struct client *client) { + struct list_node *entry; + struct server *server; + struct request *rq; + int i; + + for (entry = list_first(srvconfs); entry; entry = list_next(entry)) { + server = ((struct clsrvconf *)entry->data)->servers; + pthread_mutex_lock(&server->newrq_mutex); + for (i = 0; i < MAX_REQUESTS; i++) { + rq = server->requests + i; + if (rq->from == client) + rq->from = NULL; + } + pthread_mutex_unlock(&server->newrq_mutex); + } +} + void addserver(struct clsrvconf *conf) { if (conf->servers) debugx(1, DBG_ERR, "addserver: currently works with just one server per conf"); @@ -1805,6 +1830,7 @@ int replyh(struct server *server, unsigned char *buf) { } rq = server->requests + i; + from = rq->from; pthread_mutex_lock(&server->newrq_mutex); if (!rq->buf || !rq->tries) { @@ -1813,6 +1839,12 @@ int replyh(struct server *server, unsigned char *buf) { return 0; } + if (!from) { + pthread_mutex_unlock(&server->newrq_mutex); + debug(DBG_INFO, "replyh: client gone, ignoring reply"); + return 0; + } + if (rq->received) { pthread_mutex_unlock(&server->newrq_mutex); debug(DBG_INFO, "replyh: already received, ignoring reply"); @@ -1825,7 +1857,6 @@ int replyh(struct server *server, unsigned char *buf) { return 0; } - from = rq->from; len = RADLEN(buf) - 20; attrs = buf + 20; @@ -1943,10 +1974,10 @@ int replyh(struct server *server, unsigned char *buf) { fromsa = rq->fromsa; /* once we set received = 1, rq may be reused */ rq->received = 1; - pthread_mutex_unlock(&server->newrq_mutex); debug(DBG_DBG, "replyh: giving packet back to where it came from"); sendreply(from, buf, from->conf->type == 'U' ? &fromsa : NULL); + pthread_mutex_unlock(&server->newrq_mutex); return 1; } @@ -2270,6 +2301,7 @@ void *tlsserverrd(void *arg) { shutdown(s, SHUT_RDWR); close(s); debug(DBG_DBG, "tlsserverrd thread for %s exiting", client->conf->host); + removeclientrqs(client); removeclient(client); pthread_exit(NULL); } @@ -2987,7 +3019,7 @@ void getargs(int argc, char **argv, uint8_t *foreground, uint8_t *pretend, uint8 *pretend = 1; break; case 'v': - debugx(0, DBG_ERR, "radsecproxy 1.1-alpha"); + debugx(0, DBG_ERR, "radsecproxy 1.1-prebeta"); default: goto usage; } @@ -3054,7 +3086,7 @@ int main(int argc, char **argv) { if (!foreground && (daemon(0, 0) < 0)) debugx(1, DBG_ERR, "daemon() failed: %s", strerror(errno)); - debug(DBG_INFO, "radsecproxy 1.1-alpha starting"); + debug(DBG_INFO, "radsecproxy 1.1-prebeta starting"); if (client_udp_count) { udp_server_replyq = newreplyq(); |