summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Nault <g.nault@alphalink.fr>2014-03-28 21:09:24 +0100
committerDmitry Kozlov <xeb@mail.ru>2014-04-01 06:48:02 +0400
commita801c89a0bfc83a7026f822e9b429cf6e331bcc8 (patch)
treeaec5b6035ba58d984eaf9179eba4257cc12a33da
parent7d8b15e2a328ebe426897bff9dadc3081fc9465e (diff)
downloadaccel-ppp-a801c89a0bfc83a7026f822e9b429cf6e331bcc8.tar.gz
accel-ppp-a801c89a0bfc83a7026f822e9b429cf6e331bcc8.zip
l2tp: try generating Session IDs harder
Don't give up immediately when generating a new Session ID fails. Keep trying until a valid Session ID is found. Abort when the number of attempts exceeds the number of valid Session IDs. This is derived from algorithm 3 of RFC 6056 (Port Randomization Recommendations). Other algorithms may be used later on if need be. Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
-rw-r--r--accel-pppd/ctrl/l2tp/l2tp.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/accel-pppd/ctrl/l2tp/l2tp.c b/accel-pppd/ctrl/l2tp/l2tp.c
index 83136641..925b6434 100644
--- a/accel-pppd/ctrl/l2tp/l2tp.c
+++ b/accel-pppd/ctrl/l2tp/l2tp.c
@@ -1057,6 +1057,7 @@ static struct l2tp_sess_t *l2tp_tunnel_new_session(struct l2tp_conn_t *conn)
struct l2tp_sess_t *sess = NULL;
struct l2tp_sess_t **sess_search = NULL;
ssize_t rdlen = 0;
+ uint16_t count;
sess = mempool_alloc(l2tp_sess_pool);
if (sess == NULL) {
@@ -1067,23 +1068,27 @@ static struct l2tp_sess_t *l2tp_tunnel_new_session(struct l2tp_conn_t *conn)
}
memset(sess, 0, sizeof(*sess));
- rdlen = read(urandom_fd, &sess->sid, sizeof(sess->sid));
- if (rdlen != sizeof(sess->sid)) {
- log_tunnel(log_error, conn,
- "impossible to allocate new session:"
- " reading from urandom failed: %s\n",
- (rdlen < 0) ? strerror(errno) : "short read");
- goto out_err;
- }
- if (sess->sid == 0) {
- log_tunnel(log_error, conn,
- "impossible to allocate new session:"
- " session ID generation failed\n");
- goto out_err;
+ for (count = UINT16_MAX; count > 0; --count) {
+ rdlen = read(urandom_fd, &sess->sid, sizeof(sess->sid));
+ if (rdlen != sizeof(sess->sid)) {
+ log_tunnel(log_error, conn,
+ "impossible to allocate new session:"
+ " reading from urandom failed: %s\n",
+ (rdlen < 0) ? strerror(errno) : "short read");
+ goto out_err;
+ }
+
+ if (sess->sid == 0)
+ continue;
+
+ sess_search = tsearch(sess, &conn->sessions, sess_cmp);
+ if (*sess_search != sess)
+ continue;
+
+ break;
}
- sess_search = tsearch(sess, &conn->sessions, sess_cmp);
- if (*sess_search != sess) {
+ if (count == 0) {
log_tunnel(log_error, conn,
"impossible to allocate new session:"
" could not find any unused session ID\n");