summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Nault <g.nault@alphalink.fr>2013-02-11 21:03:19 +0100
committerKozlov Dmitry <xeb@mail.ru>2013-02-12 00:12:48 +0400
commita517397a30f366995b561c60688cfa6484a9ede2 (patch)
treefa0e570778667edb8a8631be0eca16ecb9cc0a0d
parentd44c07282f354b09fa3628674d963415b362cb85 (diff)
downloadaccel-ppp-xebd-a517397a30f366995b561c60688cfa6484a9ede2.tar.gz
accel-ppp-xebd-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.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/accel-pppd/ctrl/l2tp/l2tp.c b/accel-pppd/ctrl/l2tp/l2tp.c
index adc9e44..06287c6 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);