summaryrefslogtreecommitdiff
path: root/accel-pptpd/ctrl/l2tp/l2tp.c
diff options
context:
space:
mode:
Diffstat (limited to 'accel-pptpd/ctrl/l2tp/l2tp.c')
-rw-r--r--accel-pptpd/ctrl/l2tp/l2tp.c56
1 files changed, 38 insertions, 18 deletions
diff --git a/accel-pptpd/ctrl/l2tp/l2tp.c b/accel-pptpd/ctrl/l2tp/l2tp.c
index 2a7687e..b565e33 100644
--- a/accel-pptpd/ctrl/l2tp/l2tp.c
+++ b/accel-pptpd/ctrl/l2tp/l2tp.c
@@ -10,6 +10,7 @@
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
+#include <linux/socket.h>
#include <linux/if.h>
#include <linux/if_ether.h>
#include <linux/if_pppox.h>
@@ -27,6 +28,10 @@
#include "l2tp.h"
#include "attr_defs.h"
+#ifndef SOL_PPPOL2TP
+#define SOL_PPPOL2TP 273
+#endif
+
#define STATE_WAIT_SCCCN 1
#define STATE_WAIT_ICRQ 2
#define STATE_WAIT_ICCN 3
@@ -59,6 +64,8 @@ struct l2tp_conn_t
struct triton_timer_t rtimeout_timer;
struct triton_timer_t hello_timer;
+ int tunnel_fd;
+
struct sockaddr_in addr;
uint16_t tid;
uint16_t sid;
@@ -95,9 +102,6 @@ static void l2tp_disconnect(struct l2tp_conn_t *conn)
{
struct l2tp_packet_t *pack;
- if (conn->tid)
- l2tp_nl_delete_tunnel(conn->tid);
-
triton_md_unregister_handler(&conn->hnd);
close(conn->hnd.fd);
@@ -119,6 +123,12 @@ static void l2tp_disconnect(struct l2tp_conn_t *conn)
l2tp_conn[conn->tid] = NULL;
pthread_mutex_unlock(&l2tp_lock);
+ if (conn->ppp.fd != -1)
+ close(conn->ppp.fd);
+
+ if (conn->tunnel_fd != -1)
+ close(conn->tunnel_fd);
+
triton_event_fire(EV_CTRL_FINISHED, &conn->ppp);
if (conf_verbose)
@@ -298,6 +308,8 @@ static int l2tp_tunnel_alloc(struct l2tp_serv_t *serv, struct l2tp_packet_t *pac
ppp_init(&conn->ppp);
conn->ppp.ctrl = &conn->ctrl;
+ conn->ppp.fd = -1;
+ conn->tunnel_fd = -1;
triton_context_register(&conn->ctx, &conn->ppp);
triton_md_register_handler(&conn->ctx, &conn->hnd);
@@ -323,46 +335,54 @@ out_err:
static int l2tp_connect(struct l2tp_conn_t *conn)
{
struct sockaddr_pppol2tp pppox_addr;
-
+ int arg = 1;
+
+ memset(&pppox_addr, 0, sizeof(pppox_addr));
pppox_addr.sa_family = AF_PPPOX;
pppox_addr.sa_protocol = PX_PROTO_OL2TP;
pppox_addr.pppol2tp.fd = conn->hnd.fd;
memcpy(&pppox_addr.pppol2tp.addr, &conn->addr, sizeof(conn->addr));
pppox_addr.pppol2tp.s_tunnel = conn->tid;
- pppox_addr.pppol2tp.s_session = conn->sid;
pppox_addr.pppol2tp.d_tunnel = conn->peer_tid;
- pppox_addr.pppol2tp.d_session = conn->peer_sid;
- l2tp_nl_delete_tunnel(conn->tid);
- l2tp_nl_create_tunnel(conn->hnd.fd, conn->tid, conn->peer_tid);
- l2tp_nl_create_session(conn->tid, conn->sid, conn->peer_sid);
+ conn->tunnel_fd = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP);
+ if (!conn->ppp.fd) {
+ log_ppp_error("l2tp: socket(AF_PPPOX): %s\n", strerror(errno));
+ return -1;
+ }
conn->ppp.fd = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP);
if (!conn->ppp.fd) {
+ close(conn->tunnel_fd);
+ conn->tunnel_fd = -1;
log_ppp_error("l2tp: socket(AF_PPPOX): %s\n", strerror(errno));
return -1;
}
- if (connect(conn->ppp.fd, (struct sockaddr *)&pppox_addr, sizeof(pppox_addr))) {
- log_ppp_error("l2tp: connect: %s\n", strerror(errno));
- close(conn->ppp.fd);
+ if (connect(conn->tunnel_fd, (struct sockaddr *)&pppox_addr, sizeof(pppox_addr)) < 0) {
+ log_ppp_error("l2tp: connect(tunnel): %s\n", strerror(errno));
+ return -1;
+ }
+
+ pppox_addr.pppol2tp.s_session = conn->sid;
+ pppox_addr.pppol2tp.d_session = conn->peer_sid;
+
+ if (connect(conn->ppp.fd, (struct sockaddr *)&pppox_addr, sizeof(pppox_addr)) < 0) {
+ log_ppp_error("l2tp: connect(session): %s\n", strerror(errno));
return -1;
}
- /*if (setsockopt(conn->ppp.fd, SOL_SOCKET, PPPOL2TP_SO_LNSMODE, &conn->ppp.fd, sizeof(conn->ppp.fd))) {
+ if (setsockopt(conn->ppp.fd, SOL_PPPOL2TP, PPPOL2TP_SO_LNSMODE, &arg, sizeof(arg))) {
log_ppp_error("l2tp: setsockopt: %s\n", strerror(errno));
- close(conn->ppp.fd);
return -1;
- }*/
+ }
conn->ppp.chan_name = _strdup(inet_ntoa(conn->addr.sin_addr));
triton_event_fire(EV_CTRL_STARTED, &conn->ppp);
- if (establish_ppp(&conn->ppp)) {
- close(conn->ppp.fd);
+ if (establish_ppp(&conn->ppp))
return -1;
- }
conn->state = STATE_PPP;