X-Git-Url: http://git.sameswireless.fr/l2tpns.git/blobdiff_plain/5e65215ed4758c8fcd26ecaadc4b6121b93dab1c..959cce2660c25a7f9e248c969a5d9b013d6190d4:/l2tplac.c diff --git a/l2tplac.c b/l2tplac.c index 7fa8e87..0d11b45 100644 --- a/l2tplac.c +++ b/l2tplac.c @@ -1,15 +1,20 @@ /* + * Fernando ALVES 2013 * Add functionality "LAC" to l2tpns. * Used to forward a ppp session to another "LNS". + * GPL licenced */ + #include #include #include "md5.h" #include "l2tpns.h" #include "util.h" +#include "cluster.h" #include "l2tplac.h" +#include "pppoe.h" /* sequence diagram: Client <--> LAC <--> LNS1 <--> LNS2 * @@ -196,7 +201,8 @@ int lac_rad_select_assignment_id(sessionidt s, char *assignment_id) if (nbtagfound > 0) { // random between 0 and nbtagfound-1 - idtag = (nbtagfound*rand()/(RAND_MAX+1.0)); + idtag = (rand() % nbtagfound); + if (idtag >= nbtagfound) idtag = 0; //Sanity checks. @@ -226,13 +232,16 @@ 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) { 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); @@ -247,7 +256,6 @@ void lac_save_rad_tag_tunnels(sessionidt s) if ( (pconfigrlns[idrlns].ip == ptunnelrlns[idtag].tunnel_server_endpoint) && (strcmp(pconfigrlns[idrlns].tunnel_assignment_id, ptunnelrlns[idtag].tunnel_assignment_id) == 0) ) { - LOG(3, s, session[s].tunnel, "Tunnel IP %s already defined\n", fmtaddr(htonl(pconfigrlns[idrlns].ip), 0)); // l2tp_secret may be changed strcpy(pconfigrlns[idrlns].l2tp_secret, ptunnelrlns[idtag].tunnel_password); pconfigrlns[idrlns].port = L2TPPORT; //Default L2TP poart @@ -259,10 +267,11 @@ void lac_save_rad_tag_tunnels(sessionidt s) } } - if (idrlns >= MAXRLNSTUNNEL) - { - LOG(0, s, session[s].tunnel, "No more Remote LNS Conf Free\n"); - return; + if (idrlns >= MAXRLNSTUNNEL) + { + LOG(0, s, session[s].tunnel, "No more Remote LNS Conf Free\n"); + return; + } } } } @@ -286,6 +295,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)); @@ -440,7 +450,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 @@ -461,10 +471,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; @@ -569,8 +598,9 @@ int lac_cli_show_remotelns(confrlnsidt idrlns, char *strout) if (idrlns == 0) // Show Summary - sprintf(strout, "%15s %-32s %-32s %11s %7s %10s", + sprintf(strout, "%15s %3s %-32s %-32s %11s %7s %10s", "IP Remote LNS", + "TID", "l2tp secret", "assignment Id", "File/Radius", @@ -578,7 +608,7 @@ int lac_cli_show_remotelns(confrlnsidt idrlns, char *strout) "Count Sess"); else { - tunnelidt t; + tunnelidt t, tfound = 0; sessionidt s; int countsess = 0; char state[20]; @@ -586,29 +616,27 @@ int lac_cli_show_remotelns(confrlnsidt idrlns, char *strout) strcpy(state, "Close"); for (t = 0; t <= config->cluster_highest_tunnelid ; ++t) { - if ((tunnel[t].isremotelns) && + if ((tunnel[t].isremotelns == idrlns) && (tunnel[t].ip == pconfigrlns[idrlns].ip) && (tunnel[t].port == pconfigrlns[idrlns].port) && (tunnel[t].state != TUNNELDIE)) { - if (tunnel[t].isremotelns) - { - if (tunnel[t].state == TUNNELOPENING) - strcpy(state, "Opening"); - else if (tunnel[t].state == TUNNELOPEN) - strcpy(state, "Open"); - - for (s = 1; s <= config->cluster_highest_sessionid ; ++s) - if (session[s].tunnel == t) - countsess++; - - break; - } + if (tunnel[t].state == TUNNELOPENING) + strcpy(state, "Opening"); + else if (tunnel[t].state == TUNNELOPEN) + strcpy(state, "Open"); + + for (s = 1; s <= config->cluster_highest_sessionid ; ++s) + if (session[s].tunnel == t) + countsess++; + tfound = t; + break; } } - sprintf(strout, "%15s %-32s %-32s %11s %7s %10u", + sprintf(strout, "%15s %3u %-32s %-32s %11s %7s %10u", fmtaddr(htonl(pconfigrlns[idrlns].ip), 0), + tfound, pconfigrlns[idrlns].l2tp_secret, pconfigrlns[idrlns].tunnel_assignment_id, (pconfigrlns[idrlns].state == CONFRLNSSET?"File":(pconfigrlns[idrlns].state == CONFRLNSSETBYRADIUS?"Radius":"Free")),