X-Git-Url: http://git.sameswireless.fr/l2tpns.git/blobdiff_plain/bcc2c7408be2d278ceef675b5d989ce6ed395315..ba1c3362c6dc0d65eb3d06368c47b75aa135456b:/l2tplac.c diff --git a/l2tplac.c b/l2tplac.c index 4c71d6c..5fb361e 100644 --- a/l2tplac.c +++ b/l2tplac.c @@ -1,15 +1,23 @@ /* + * Fernando ALVES 2013 * Add functionality "LAC" to l2tpns. * Used to forward a ppp session to another "LNS". + * GPL licenced */ + #include #include +#include +#include #include "md5.h" +#include "dhcp6.h" #include "l2tpns.h" #include "util.h" +#include "cluster.h" #include "l2tplac.h" +#include "pppoe.h" /* sequence diagram: Client <--> LAC <--> LNS1 <--> LNS2 * @@ -227,6 +235,8 @@ void lac_save_rad_tag_tunnels(sessionidt s) LOG(1, s, session[s].tunnel, "Error, Bad IP tunnel server endpoint \n"); else if (strlen(ptunnelrlns[idtag].tunnel_assignment_id) <= 0) LOG(1, s, session[s].tunnel, "Error, No tunnel_assignment_id \n"); + else if (ptunnelrlns[idtag].tunnel_server_endpoint == ntohl(config->bind_address)) + LOG(0, s, session[s].tunnel, "Error, IP Remote LNS == IP local bind address (%s) !!!\n", fmtaddr(config->bind_address, 0)); else { for (idrlns = 1; idrlns < MAXRLNSTUNNEL; ++idrlns) @@ -234,7 +244,7 @@ void lac_save_rad_tag_tunnels(sessionidt s) if (pconfigrlns[idrlns].state == CONFRLNSFREE) { pconfigrlns[idrlns].ip = ptunnelrlns[idtag].tunnel_server_endpoint; - pconfigrlns[idrlns].port = L2TPPORT; //Default L2TP poart + pconfigrlns[idrlns].port = L2TPPORT; //Default L2TP port strcpy(pconfigrlns[idrlns].l2tp_secret, ptunnelrlns[idtag].tunnel_password); strcpy(pconfigrlns[idrlns].tunnel_assignment_id, ptunnelrlns[idtag].tunnel_assignment_id); @@ -288,6 +298,7 @@ static int lac_create_tunnelsession(tunnelidt t, sessionidt s, confrlnsidt i_con tunnel[t].port = pconfigrlns[i_conf].port; tunnel[t].window = 4; // default window tunnel[t].isremotelns = i_conf; + tunnel[t].indexudp = config->indexlacudpfd; STAT(tunnel_created); random_data(pconfigrlns[i_conf].auth, sizeof(pconfigrlns[i_conf].auth)); @@ -442,7 +453,7 @@ void lac_calc_rlns_auth(tunnelidt t, uint8_t id, uint8_t *out) } // Forward session to LAC or Remote LNS -int lac_session_forward(uint8_t *buf, int len, sessionidt sess, uint16_t proto) +int lac_session_forward(uint8_t *buf, int len, sessionidt sess, uint16_t proto, in_addr_t s_addr, int sin_port, uint16_t indexudpfd) { uint16_t t = 0, s = 0; uint8_t *p = buf + 2; // First word L2TP options @@ -463,10 +474,29 @@ int lac_session_forward(uint8_t *buf, int len, sessionidt sess, uint16_t proto) if ((!tunnel[t].isremotelns) && (!tunnel[session[sess].tunnel].isremotelns)) { - LOG(0, sess, session[sess].tunnel, "Link Tunnel Session (%u) broken\n", s); + LOG(0, sess, session[sess].tunnel, "Link Tunnel Session (%u/%u) broken\n", s, t); return 0; } + if (!config->cluster_iam_master) + { + if ( (proto == PPPIPCP) || (proto == PPPLCP) || + (proto == PPPPAP) || (proto == PPPCHAP) || + (proto == PPPIPV6CP && config->ipv6_prefix.s6_addr[0]) || + (proto == PPPCCP) ) + { + session[sess].last_packet = time_now; + master_forward_packet(buf, len, s_addr, sin_port, indexudpfd); + return 1; + } + } + + if (t == TUNNEL_ID_PPPOE) + { + pppoe_forwardto_session_pppoe(buf, len, sess, proto); + return 1; + } + if (*buf & 0x40) { // length p += 2;