diff options
author | Guillaume Nault <g.nault@alphalink.fr> | 2013-02-11 21:03:19 +0100 |
---|---|---|
committer | Kozlov Dmitry <xeb@mail.ru> | 2013-02-12 00:12:48 +0400 |
commit | a517397a30f366995b561c60688cfa6484a9ede2 (patch) | |
tree | fa0e570778667edb8a8631be0eca16ecb9cc0a0d | |
parent | d44c07282f354b09fa3628674d963415b362cb85 (diff) | |
download | accel-ppp-a517397a30f366995b561c60688cfa6484a9ede2.tar.gz accel-ppp-a517397a30f366995b561c60688cfa6484a9ede2.zip |
l2tp: Connect to peer once first reply received
When peer's port isn't known (i.e. right after a tunnel establishment
request has been sent), use the source port of the first peer's
response as the destination port of any future L2TP message sent over
that tunnel.
Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
-rw-r--r-- | accel-pppd/ctrl/l2tp/l2tp.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/accel-pppd/ctrl/l2tp/l2tp.c b/accel-pppd/ctrl/l2tp/l2tp.c index adc9e449..06287c66 100644 --- a/accel-pppd/ctrl/l2tp/l2tp.c +++ b/accel-pppd/ctrl/l2tp/l2tp.c @@ -938,6 +938,25 @@ out_err: return NULL; } +static inline int l2tp_tunnel_update_peerport(struct l2tp_conn_t *conn, + uint16_t port_nbo) +{ + in_port_t old_port = conn->peer_addr.sin_port; + int res; + + conn->peer_addr.sin_port = port_nbo; + res = connect(conn->hnd.fd, &conn->peer_addr, sizeof(conn->peer_addr)); + if (res < 0) { + l2tp_conn_log(log_error, conn); + log_error("l2tp: Impossible to update peer port from" + " %hu to %hu: connect() failed: %s\n", + ntohs(old_port), ntohs(port_nbo), strerror(errno)); + conn->peer_addr.sin_port = old_port; + } + + return res; +} + static int l2tp_session_connect(struct l2tp_sess_t *sess) { struct sockaddr_pppol2tp pppox_addr; @@ -1778,6 +1797,15 @@ static int l2tp_conn_read(struct triton_md_handler_t *h) if (!pack) continue; + if (conn->peer_addr.sin_port == 0) { + /* Get peer's first reply source port and use it as + destination port for further outgoing messages */ + res = l2tp_tunnel_update_peerport(conn, + pack->addr.sin_port); + if (res < 0) + goto drop; + } + if (ntohs(pack->hdr.tid) != conn->tid && (pack->hdr.tid || !conf_dir300_quirk)) { if (conf_verbose) { l2tp_conn_log(log_warn, conn); |