summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKozlov Dmitry <xeb@mail.ru>2012-09-09 11:12:42 +0400
committerKozlov Dmitry <xeb@mail.ru>2012-09-09 11:12:42 +0400
commitc516503e689b1df12ce562cfcb85be47a663b9da (patch)
tree9a6570e15c66c06e42b26b048a6b837b59d57441
parent56db0285dd934e058fb6981577c07258f5413b67 (diff)
downloadaccel-ppp-xebd-c516503e689b1df12ce562cfcb85be47a663b9da.tar.gz
accel-ppp-xebd-c516503e689b1df12ce562cfcb85be47a663b9da.zip
l2tp: send CDN in tunnel context
-rw-r--r--accel-pppd/ctrl/l2tp/l2tp.c31
1 files changed, 29 insertions, 2 deletions
diff --git a/accel-pppd/ctrl/l2tp/l2tp.c b/accel-pppd/ctrl/l2tp/l2tp.c
index 10a67fc..7fb00ef 100644
--- a/accel-pppd/ctrl/l2tp/l2tp.c
+++ b/accel-pppd/ctrl/l2tp/l2tp.c
@@ -121,6 +121,7 @@ static void l2tp_rtimeout(struct triton_timer_t *t);
static void l2tp_send_HELLO(struct triton_timer_t *t);
static void l2tp_send_SCCRP(struct l2tp_conn_t *conn);
static int l2tp_send(struct l2tp_conn_t *conn, struct l2tp_packet_t *pack, int log_debug);
+static void __l2tp_send(struct l2tp_packet_t *pack);
static int l2tp_conn_read(struct triton_md_handler_t *);
static void l2tp_conn_log(void (*print)(const char *fmt, ...), struct l2tp_conn_t *conn)
@@ -193,7 +194,9 @@ static int l2tp_send_CDN(struct l2tp_sess_t *sess, uint16_t res, uint16_t err)
pack->hdr.sid = htons(sess->peer_sid);
- return l2tp_send(sess->paren_conn, pack, 0);
+ triton_context_call(&sess->paren_conn->ctx, (triton_event_func)__l2tp_send, pack);
+
+ return 0;
out_err:
if (pack)
@@ -672,7 +675,7 @@ static int l2tp_session_connect(struct l2tp_sess_t *sess)
}
u_inet_ntoa(conn->lac_addr.sin_addr.s_addr, addr);
- sprintf(chan_name, "%s:%i session %i", addr, ntohs(conn->lac_addr.sin_port), sess->sid);
+ sprintf(chan_name, "%s:%i session %i", addr, ntohs(conn->lac_addr.sin_port), sess->peer_sid);
sess->ppp.ses.chan_name = _strdup(chan_name);
triton_event_fire(EV_CTRL_STARTED, &sess->ppp.ses);
@@ -743,6 +746,20 @@ out_err:
return -1;
}
+static void l2tp_retransmit(struct l2tp_conn_t *conn)
+{
+ struct l2tp_packet_t *pack;
+
+ pack = list_entry(conn->send_queue.next, typeof(*pack), entry);
+ pack->hdr.Nr = htons(conn->Nr + 1);
+ if (conf_verbose) {
+ l2tp_conn_log(log_debug, conn);
+ log_debug("send ");
+ l2tp_packet_print(pack, log_debug);
+ }
+ l2tp_packet_send(conn->hnd.fd, pack);
+}
+
static void l2tp_rtimeout(struct triton_timer_t *t)
{
struct l2tp_conn_t *conn = container_of(t, typeof(*conn), rtimeout_timer);
@@ -812,6 +829,14 @@ out_err:
return -1;
}
+static void __l2tp_send(struct l2tp_packet_t *pack)
+{
+ struct l2tp_conn_t *conn = container_of(triton_context_self(), typeof(*conn), ctx);
+
+ if (l2tp_send(conn, pack, 0))
+ l2tp_tunnel_free(conn);
+}
+
static int l2tp_send_ZLB(struct l2tp_conn_t *conn)
{
struct l2tp_packet_t *pack;
@@ -1291,6 +1316,8 @@ static int l2tp_conn_read(struct triton_md_handler_t *h)
if (ntohs(pack->hdr.Ns) < conn->Nr + 1 || (ntohs(pack->hdr.Ns > 32767 && conn->Nr + 1 < 32767))) {
l2tp_conn_log(log_debug, conn);
log_debug("duplicate packet %i\n", ntohs(pack->hdr.Ns));
+ if (!list_empty(&conn->send_queue))
+ l2tp_retransmit(conn);
if (l2tp_send_ZLB(conn))
goto drop;
} else {