diff options
author | Guillaume Nault <g.nault@alphalink.fr> | 2014-03-28 21:09:24 +0100 |
---|---|---|
committer | Dmitry Kozlov <xeb@mail.ru> | 2014-04-01 06:48:02 +0400 |
commit | a801c89a0bfc83a7026f822e9b429cf6e331bcc8 (patch) | |
tree | aec5b6035ba58d984eaf9179eba4257cc12a33da | |
parent | 7d8b15e2a328ebe426897bff9dadc3081fc9465e (diff) | |
download | accel-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.c | 35 |
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"); |