- s/tap/tun/
authorBrendan O'Dea <bod@optus.net>
Thu, 8 Jul 2004 16:54:35 +0000 (16:54 +0000)
committerBrendan O'Dea <bod@optus.net>
Thu, 8 Jul 2004 16:54:35 +0000 (16:54 +0000)
- fix for LASTSEEN breakage:  don't do anything in the CLI other than
  flag changes to be made by the parent
- split out master parts from cluster_check_master() into cluster_check_slaves()

cli.c
cluster.c
cluster.h
l2tpns.c
l2tpns.h
ppp.c
tbf.c

diff --git a/cli.c b/cli.c
index 0f7a848..2707e17 100644 (file)
--- a/cli.c
+++ b/cli.c
@@ -2,7 +2,7 @@
 // vim: sw=4 ts=8
 
 char const *cvs_name = "$Name:  $";
-char const *cvs_id_cli = "$Id: cli.c,v 1.8 2004-07-07 09:09:53 bodea Exp $";
+char const *cvs_id_cli = "$Id: cli.c,v 1.9 2004-07-08 16:54:35 bodea Exp $";
 
 #include <stdio.h>
 #include <stdarg.h>
@@ -39,15 +39,15 @@ extern ippoolt *ip_address_pool;
 extern struct Tstats *_statistics;
 struct cli_def *cli = NULL;
 int cli_quit = 0;
-extern int clifd, udpfd, tapfd, snoopfd, ifrfd, cluster_sockfd;
+extern int clifd, udpfd, tunfd, snoopfd, ifrfd, cluster_sockfd;
 extern int *radfds;
-extern sessionidt *cli_session_kill;
-extern tunnelidt *cli_tunnel_kill;
 extern struct configt *config;
 extern struct config_descriptt config_values[];
 #ifdef RINGBUFFER
 extern struct Tringbuffer *ringbuffer;
 #endif
+extern struct cli_session_actions *cli_session_actions;
+extern struct cli_tunnel_actions *cli_tunnel_actions;
 
 char *debug_levels[] = {
     "CRIT",
@@ -265,7 +265,7 @@ void cli_do(int sockfd)
 
     // Close sockets
     if (udpfd) close(udpfd); udpfd = 0;
-    if (tapfd) close(tapfd); tapfd = 0;
+    if (tunfd) close(tunfd); tunfd = 0;
     if (snoopfd) close(snoopfd); snoopfd = 0;
     for (i = 0; i < config->num_radfds; i++)
        if (radfds[i]) close(radfds[i]);
@@ -599,13 +599,13 @@ int cmd_show_counters(struct cli_def *cli, char *command, char **argv, int argc)
 
     cli_print(cli, "%-10s %-8s %-10s %-8s", "Ethernet", "Bytes", "Packets", "Errors");
     cli_print(cli, "%-10s %8lu %8lu %8lu", "RX",
-           GET_STAT(tap_rx_bytes),
-           GET_STAT(tap_rx_packets),
-           GET_STAT(tap_rx_errors));
+           GET_STAT(tun_rx_bytes),
+           GET_STAT(tun_rx_packets),
+           GET_STAT(tun_rx_errors));
     cli_print(cli, "%-10s %8lu %8lu %8lu", "TX",
-           GET_STAT(tap_tx_bytes),
-           GET_STAT(tap_tx_packets),
-           GET_STAT(tap_tx_errors));
+           GET_STAT(tun_tx_bytes),
+           GET_STAT(tun_tx_packets),
+           GET_STAT(tun_tx_errors));
     cli_print(cli, "");
 
     cli_print(cli, "%-10s %-8s %-10s %-8s %-8s", "Tunnel", "Bytes", "Packets", "Errors", "Retries");
@@ -624,11 +624,7 @@ int cmd_show_counters(struct cli_def *cli, char *command, char **argv, int argc)
     cli_print(cli, "%-30s%-10s", "Counter", "Value");
     cli_print(cli, "-----------------------------------------");
     cli_print(cli, "%-30s%lu", "radius_retries",       GET_STAT(radius_retries));
-    cli_print(cli, "%-30s%lu", "arp_errors",           GET_STAT(arp_errors));
-    cli_print(cli, "%-30s%lu", "arp_replies",          GET_STAT(arp_replies));
-    cli_print(cli, "%-30s%lu", "arp_discarded",                GET_STAT(arp_discarded));
     cli_print(cli, "%-30s%lu", "arp_sent",             GET_STAT(arp_sent));
-    cli_print(cli, "%-30s%lu", "arp_recv",             GET_STAT(arp_recv));
     cli_print(cli, "%-30s%lu", "packets_snooped",      GET_STAT(packets_snooped));
     cli_print(cli, "%-30s%lu", "tunnel_created",       GET_STAT(tunnel_created));
     cli_print(cli, "%-30s%lu", "session_created",      GET_STAT(session_created));
@@ -647,8 +643,7 @@ int cmd_show_counters(struct cli_def *cli, char *command, char **argv, int argc)
 #ifdef STATISTICS
     cli_print(cli, "\n%-30s%-10s", "Counter", "Value");
     cli_print(cli, "-----------------------------------------");
-    cli_print(cli, "%-30s%lu", "call_processtap",      GET_STAT(call_processtap));
-    cli_print(cli, "%-30s%lu", "call_processarp",      GET_STAT(call_processarp));
+    cli_print(cli, "%-30s%lu", "call_processtun",      GET_STAT(call_processtun));
     cli_print(cli, "%-30s%lu", "call_processipout",    GET_STAT(call_processipout));
     cli_print(cli, "%-30s%lu", "call_processudp",      GET_STAT(call_processudp));
     cli_print(cli, "%-30s%lu", "call_processpap",      GET_STAT(call_processpap));
@@ -1028,17 +1023,8 @@ int cmd_drop_user(struct cli_def *cli, char *command, char **argv, int argc)
 
        if (session[s].ip && session[s].opened && !session[s].die)
        {
-           int x;
-
            cli_print(cli, "Dropping user %s", session[s].user);
-           for (x = 0; x < MAXSESSION; x++)
-           {
-               if (!cli_session_kill[x])
-               {
-                   cli_session_kill[x] = s;
-                   break;
-               }
-           }
+           cli_session_actions[s].action |= CLI_SESS_KILL;
        }
     }
 
@@ -1048,7 +1034,7 @@ int cmd_drop_user(struct cli_def *cli, char *command, char **argv, int argc)
 int cmd_drop_tunnel(struct cli_def *cli, char *command, char **argv, int argc)
 {
     int i;
-    tunnelidt tid;
+    tunnelidt t;
 
     if (CLI_HELP_REQUESTED)
        return cli_arg_help(cli, argc > 1,
@@ -1068,35 +1054,26 @@ int cmd_drop_tunnel(struct cli_def *cli, char *command, char **argv, int argc)
 
     for (i = 0; i < argc; i++)
     {
-       int x;
-
-       if ((tid = atol(argv[i])) <= 0 || (tid >= MAXTUNNEL))
+       if ((t = atol(argv[i])) <= 0 || (t >= MAXTUNNEL))
        {
            cli_print(cli, "Invalid tunnel ID (1-%d)", MAXTUNNEL-1);
            continue;
        }
 
-       if (!tunnel[tid].ip)
+       if (!tunnel[t].ip)
        {
-           cli_print(cli, "Tunnel %d is not connected", tid);
+           cli_print(cli, "Tunnel %d is not connected", t);
            continue;
        }
 
-       if (tunnel[tid].die)
+       if (tunnel[t].die)
        {
-           cli_print(cli, "Tunnel %d is already being shut down", tid);
+           cli_print(cli, "Tunnel %d is already being shut down", t);
            continue;
        }
 
-       for (x = 0; x < MAXTUNNEL; x++)
-       {
-           if (!cli_tunnel_kill[x])
-           {
-               cli_tunnel_kill[x] = tid;
-               cli_print(cli, "Tunnel %d shut down (%s)", tid, tunnel[tid].hostname);
-               break;
-           }
-       }
+       cli_print(cli, "Tunnel %d shut down (%s)", t, tunnel[t].hostname);
+       cli_tunnel_actions[t].action |= CLI_TUN_KILL;
     }
 
     return CLI_OK;
@@ -1131,18 +1108,10 @@ int cmd_drop_session(struct cli_def *cli, char *command, char **argv, int argc)
            continue;
        }
 
-       if (session[s].opened && !session[s].die)
+       if (session[s].ip && session[s].opened && !session[s].die)
        {
-           int x;
-           for (x = 0; x < MAXSESSION; x++)
-           {
-               if (!cli_session_kill[x])
-               {
-                   cli_session_kill[x] = s;
-                   break;
-               }
-           }
            cli_print(cli, "Dropping session %d", s);
+           cli_session_actions[s].action |= CLI_SESS_KILL;
        }
        else
        {
@@ -1216,10 +1185,11 @@ int cmd_snoop(struct cli_def *cli, char *command, char **argv, int argc)
        return CLI_OK;
     }
 
-    session[s].snoop_ip = ip;
-    session[s].snoop_port = port;
-
     cli_print(cli, "Snooping user %s to %s:%d", argv[0], inet_toa(session[s].snoop_ip), session[s].snoop_port);
+    cli_session_actions[s].snoop_ip = ip;
+    cli_session_actions[s].snoop_port = port;
+    cli_session_actions[s].action |= CLI_SESS_SNOOP;
+
     return CLI_OK;
 }
 
@@ -1251,10 +1221,9 @@ int cmd_no_snoop(struct cli_def *cli, char *command, char **argv, int argc)
            cli_print(cli, "User %s is not connected", argv[i]);
            continue;
        }
-       session[s].snoop_ip = 0;
-       session[s].snoop_port = 0;
 
        cli_print(cli, "Not snooping user %s", argv[i]);
+       cli_session_actions[s].action |= CLI_SESS_NOSNOOP;
     }
     return CLI_OK;
 }
@@ -1287,10 +1256,16 @@ int cmd_throttle(struct cli_def *cli, char *command, char **argv, int argc)
            cli_print(cli, "User %s is not connected", argv[i]);
            continue;
        }
-       if (!throttle_session(s, config->rl_rate))
-           cli_print(cli, "Error throttling %s", argv[i]);
-       else
-           cli_print(cli, "Throttling user %s", argv[i]);
+
+       if (session[s].throttle)
+       {
+           cli_print(cli, "User %s already throttled", argv[i]);
+           continue;
+       }
+
+       cli_print(cli, "Throttling user %s", argv[i]);
+       cli_session_actions[s].throttle = config->rl_rate; // could be configurable at some stage
+       cli_session_actions[s].action |= CLI_SESS_THROTTLE;
     }
 
     return CLI_OK;
@@ -1324,9 +1299,15 @@ int cmd_no_throttle(struct cli_def *cli, char *command, char **argv, int argc)
            cli_print(cli, "User %s is not connected", argv[i]);
            continue;
        }
-       throttle_session(s, 0);
+
+       if (!session[s].throttle)
+       {
+           cli_print(cli, "User %s not throttled", argv[i]);
+           continue;
+       }
 
        cli_print(cli, "Unthrottling user %s", argv[i]);
+       cli_session_actions[s].action |= CLI_SESS_NOTHROTTLE;
     }
 
     return CLI_OK;
index a251a77..d99da26 100644 (file)
--- a/cluster.c
+++ b/cluster.c
@@ -1,6 +1,6 @@
 // L2TPNS Clustering Stuff
 
-char const *cvs_id_cluster = "$Id: cluster.c,v 1.7 2004-07-07 09:09:53 bodea Exp $";
+char const *cvs_id_cluster = "$Id: cluster.c,v 1.8 2004-07-08 16:54:35 bodea Exp $";
 
 #include <stdio.h>
 #include <sys/file.h>
@@ -66,7 +66,6 @@ static struct {
        int     uptodate;
 } peers[CLUSTER_MAX_SIZE];     // List of all the peers we've heard from.
 static int num_peers;          // Number of peers in list.
-static int have_peers;         // At least one up to date peer
 
 int rle_decompress(u8 ** src_p, int ssize, u8 *dst, int dsize);
 int rle_compress(u8 ** src_p, int ssize, u8 *dst, int dsize);
@@ -330,13 +329,6 @@ int master_garden_packet(sessionidt s, char *data, int size)
 static void send_heartbeat(int seq, char * data, int size)
 {
     int i;
-    static int last_seq = -1;
-
-    if (last_seq != -1 && (seq != (last_seq+1)%HB_MAX_SEQ) ) {
-       log(0,0,0,0, "FATAL: Sequence number skipped! (%d != %d)\n",
-               seq, last_seq);
-    } 
-    last_seq = seq;
 
     if (size > sizeof(past_hearts[0].data)) {
        log(0,0,0,0, "Tried to heartbeat something larger than the maximum packet!\n");
@@ -426,6 +418,48 @@ void master_update_counts(void)
        return;
 }
 
+//
+// On the master, check how our slaves are going. If
+// one of them's not up-to-date we'll heartbeat faster.
+// If we don't have any of them, then we need to turn
+// on our own packet handling!
+//
+void cluster_check_slaves(void)
+{
+       int i;
+       static int have_peers = 0;
+       int had_peers = have_peers;
+       clockt t = TIME;
+
+       if (!config->cluster_iam_master)
+               return;         // Only runs on the master...
+
+       config->cluster_iam_uptodate = 1;       // cleared in loop below
+
+       for (i = have_peers = 0; i < num_peers; i++)
+       {
+               if ((peers[i].timestamp + config->cluster_hb_timeout) < t)
+                       continue;       // Stale peer! Skip them.
+
+               if (!peers[i].basetime)
+                       continue;       // Shutdown peer! Skip them.
+
+               if (peers[i].uptodate)
+                       have_peers = 1;
+
+               if (!peers[i].uptodate)
+                       config->cluster_iam_uptodate = 0; // Start fast heartbeats
+       }
+
+#ifdef BGP
+       // master lost all slaves, need to handle traffic ourself
+       if (bgp_configured && had_peers && !have_peers)
+               bgp_enable_routing(1);
+       else if (bgp_configured && !had_peers && have_peers)
+               bgp_enable_routing(0);
+#endif /* BGP */
+}
+
 //
 // Check that we have a master. If it's been too
 // long since we heard from a master then hold an election.
@@ -434,48 +468,40 @@ void cluster_check_master(void)
 {
        int i, count, tcount, high_sid = 0;
        int last_free = 0;
-       int had_peers = have_peers;
        clockt t = TIME;
        static int probed = 0;
 
-       if (TIME < (config->cluster_last_hb + config->cluster_hb_timeout))
-       {
+       if (config->cluster_iam_master)
+               return;         // Only runs on the slaves...
+
                // If the master is late (missed 2 hearbeats by a second and a
                // hair) it may be that the switch has dropped us from the
                // multicast group, try unicasting one probe to the master
                // which will hopefully respond with a unicast heartbeat that
                // will allow us to limp along until the querier next runs.
-               if (config->cluster_master_address
-                   && TIME > (config->cluster_last_hb + 2 * config->cluster_hb_interval + 11))
+       if (TIME > (config->cluster_last_hb + 2 * config->cluster_hb_interval + 11))
+       {
+               if (!probed && config->cluster_master_address)
                {
-                       if (!probed)
-                       {
-                               probed = 1;
-                               log(1, 0, 0, 0, "Heartbeat from master %.1fs late, probing...\n",
-                                   TIME - (config->cluster_last_hb + config->cluster_hb_interval));
-
-                               peer_send_message(config->cluster_master_address,
-                                   C_LASTSEEN, config->cluster_seq_number, NULL, 0);
-                       }
-               } else {        // We got a recent heartbeat; reset the probe flag.
-                       probed = 0;
-               }
-
-               if (!config->cluster_iam_master)
-                       return;         // Everything's ok. return.
+                       probed = 1;
+                       log(1, 0, 0, 0, "Heartbeat from master %.1fs late, probing...\n",
+                           0.1 * (TIME - (config->cluster_last_hb + config->cluster_hb_interval)));
 
-               // Master needs to check peer state
+                       peer_send_message(config->cluster_master_address,
+                           C_LASTSEEN, config->cluster_seq_number, NULL, 0);
+               }
+       } else {        // We got a recent heartbeat; reset the probe flag.
+               probed = 0;
        }
 
-       config->cluster_last_hb = TIME + 1;
+       if (TIME < (config->cluster_last_hb + config->cluster_hb_timeout))
+               return; // Everything's ok!
 
-       if (config->cluster_iam_master)
-               config->cluster_iam_uptodate = 1;       // cleared in loop below
-       else
-               log(0,0,0,0, "Master timed out! Holding election...\n");
+       config->cluster_last_hb = TIME + 1;     // Just the one election thanks.
 
+       log(0,0,0,0, "Master timed out! Holding election...\n");
 
-       for (i = have_peers = 0; i < num_peers; i++)
+       for (i = 0; i < num_peers; i++)
        {
                if ((peers[i].timestamp + config->cluster_hb_timeout) < t)
                        continue;       // Stale peer! Skip them.
@@ -483,17 +509,6 @@ void cluster_check_master(void)
                if (!peers[i].basetime)
                        continue;       // Shutdown peer! Skip them.
 
-               if (peers[i].uptodate)
-                       have_peers = 1;
-
-               if (config->cluster_iam_master)
-               {
-                       if (!peers[i].uptodate)
-                               config->cluster_iam_uptodate = 0; // Start fast heartbeats
-
-                       continue;
-               }
-
                if (peers[i].basetime < basetime) {
                        log(1,0,0,0, "Expecting %s to become master\n", inet_toa(peers[i].peer) );
                        return;         // They'll win the election. Get out of here.
@@ -506,16 +521,6 @@ void cluster_check_master(void)
                }
        }
 
-       if (config->cluster_iam_master)         // If we're the master, we've already won
-       {
-#ifdef BGP
-               // master lost all slaves, need to handle traffic ourself
-               if (bgp_configured && had_peers && !have_peers)
-                       bgp_enable_routing(1);
-#endif /* BGP */
-               return;
-       }
-
                // Wow. it's been ages since I last heard a heartbeat
                // and I'm better than an of my peers so it's time
                // to become a master!!!
@@ -525,11 +530,6 @@ void cluster_check_master(void)
 
        log(0,0,0,0, "I am declaring myself the master!\n");
 
-#ifdef BGP
-       if (bgp_configured && have_peers)
-               bgp_enable_routing(0); /* stop handling traffic */
-#endif /* BGP */
-
        if (config->cluster_seq_number == -1)
                config->cluster_seq_number = 0;
 
@@ -897,13 +897,8 @@ int cluster_catchup_slave(int seq, u32 slave)
        while (seq != config->cluster_seq_number) {
                s = seq%HB_HISTORY_SIZE;
                if (seq != past_hearts[s].seq) {
-                       int i;
                        log(0,0,0,0, "Tried to re-send heartbeat for %s but %d doesn't match %d! (%d,%d)\n",
                                inet_toa(slave), seq, past_hearts[s].seq, s, config->cluster_seq_number);
-
-                       for (i = 0; i < HB_HISTORY_SIZE; ++i) {
-                               log(0,0,0,0, "\tentry %3d: seq %d (size %d)\n", i, past_hearts[s].seq, past_hearts[s].size);
-                       }
                        return -1;      // What to do here!?
                }
                peer_send_data(slave, past_hearts[s].data, past_hearts[s].size);
@@ -943,6 +938,7 @@ int cluster_add_peer(u32 peer, time_t basetime, pingt *p)
 
                // Is this the master shutting down??
        if (peer == config->cluster_master_address && !basetime) {
+               log(3,0,0,0, "Master %s shutting down...\n", inet_toa(config->cluster_master_address));
                config->cluster_master_address = 0;
                config->cluster_last_hb = 0; // Force an election.
                cluster_check_master();
@@ -980,21 +976,6 @@ int cluster_add_peer(u32 peer, time_t basetime, pingt *p)
                log(1,0,0,0, "Added %s as a new peer. Now %d peers\n", inet_toa(peer), num_peers);
        }
 
-       if (peers[i].uptodate)
-       {
-#ifdef BGP
-               /* drop routes if we've now got a peer */
-               if (config->cluster_iam_master && bgp_configured && !have_peers)
-                       bgp_enable_routing(0);
-#endif /* BGP */
-               have_peers = 1;
-       }
-       else if (config->cluster_iam_master)
-       {
-               config->cluster_iam_uptodate = 0; // increase heart-rate...
-       }
-
-
        return 1;
 }
 
index 042d41a..8eba2d5 100644 (file)
--- a/cluster.h
+++ b/cluster.h
@@ -1,5 +1,5 @@
 // L2TPNS Clustering Stuff
-// $Id: cluster.h,v 1.4 2004-07-07 09:09:53 bodea Exp $
+// $Id: cluster.h,v 1.5 2004-07-08 16:54:35 bodea Exp $
 
 #ifndef __CLUSTER_H__
 #define __CLUSTER_H__
@@ -78,6 +78,7 @@ void master_update_counts(void);
 void cluster_send_ping(time_t basetime);
 void cluster_heartbeat(void);
 void cluster_check_master(void);
+void cluster_check_slaves(void);
 int show_cluster(struct cli_def *cli, char *command, char **argv, int argc);
 
 #endif /* __CLUSTER_H__ */
index 5133807..45d652e 100644 (file)
--- a/l2tpns.c
+++ b/l2tpns.c
@@ -4,7 +4,7 @@
 // Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced
 // vim: sw=8 ts=8
 
-char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.11 2004-07-07 09:09:53 bodea Exp $";
+char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.12 2004-07-08 16:54:35 bodea Exp $";
 
 #include <arpa/inet.h>
 #include <assert.h>
@@ -22,7 +22,6 @@ char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.11 2004-07-07 09:09:53 bodea Exp
 #include <stdarg.h>
 #include <stdlib.h>
 #include <stdio.h>
-#define __USE_GNU
 #include <string.h>
 #include <sys/ioctl.h>
 #include <sys/socket.h>
@@ -51,7 +50,7 @@ char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.11 2004-07-07 09:09:53 bodea Exp
 
 // Globals
 struct configt *config = NULL; // all configuration
-int tapfd = -1;                        // tap interface file handle
+int tunfd = -1;                        // tun interface file handle. (network device)
 int udpfd = -1;                        // UDP file handle
 int controlfd = -1;            // Control signal handle
 int snoopfd = -1;              // UDP file handle for sending out intercept data
@@ -59,24 +58,25 @@ int *radfds = NULL;         // RADIUS requests file handles
 int ifrfd = -1;                        // File descriptor for routing, etc
 time_t basetime = 0;           // base clock
 char hostname[1000] = "";      // us.
-u16 tapmac[3];                 // MAC of tap interface
-int tapidx;                    // ifr_ifindex of tap device
+int tunidx;                    // ifr_ifindex of tun device
 u32 sessionid = 0;             // session id for radius accounting
 int syslog_log = 0;            // are we logging to syslog
-FILE *log_stream = NULL;
-struct sockaddr_in snoop_addr = {0};
-extern int cluster_sockfd;
-u32 last_sid = 0;
-int clifd = 0;
-sessionidt *cli_session_kill = NULL;
-tunnelidt *cli_tunnel_kill = NULL;
-static void *ip_hash[256];
-u32 udp_tx = 0, udp_rx = 0, udp_rx_pkt = 0;
+FILE *log_stream = NULL;       // file handle for direct logging (i.e. direct into file, not via syslog).
+extern int cluster_sockfd;     // Intra-cluster communications socket.
+u32 last_sid = 0;              // Last used PPP SID. Can I kill this?? -- mo
+int clifd = 0;                 // Socket listening for CLI connections.
+
+struct cli_session_actions *cli_session_actions = NULL;        // Pending session changes requested by CLI
+struct cli_tunnel_actions *cli_tunnel_actions = NULL;  // Pending tunnel changes required by CLI
+
+static void *ip_hash[256];     // Mapping from IP address to session structures.
+
+u32 udp_tx = 0, udp_rx = 0, udp_rx_pkt = 0;    // Global traffic counters.
 u32 eth_tx = 0, eth_rx = 0, eth_rx_pkt = 0;
-u32 ip_pool_size = 1;
-time_t time_now = 0;
-char time_now_string[64] = {0};
-char main_quit = 0;
+u32 ip_pool_size = 1;          // Size of the pool of addresses used for dynamic address allocation.
+time_t time_now = 0;           // Current time in seconds since epoch.
+char time_now_string[64] = {0};        // Current time as a string.
+char main_quit = 0;            // True if we're in the process of exiting.
 char *_program_name = NULL;
 linked_list *loaded_plugins;
 linked_list *plugins[MAX_PLUGIN_TYPES];
@@ -143,11 +143,11 @@ char *plugin_functions[] = {
 
 #define max_plugin_functions (sizeof(plugin_functions) / sizeof(char *))
 
-tunnelt *tunnel = NULL;                // 1000 * 45 = 45000 = 45k
-sessiont *session = NULL;      // 5000 * 213 = 1065000 = 1 Mb
-sessioncountt *sess_count = NULL;
-radiust *radius = NULL;
-ippoolt *ip_address_pool = NULL;
+tunnelt *tunnel = NULL;                // Array of tunnel structures.
+sessiont *session = NULL;      // Array of session structures.
+sessioncountt *sess_count = NULL;      // Array of partial per-session traffic counters.
+radiust *radius = NULL;                // Array of radius structures.
+ippoolt *ip_address_pool = NULL;       // Array of dynamic IP addresses.
 controlt *controlfree = 0;
 struct Tstats *_statistics = NULL;
 #ifdef RINGBUFFER
@@ -169,7 +169,7 @@ void update_config();
 static void cache_ipmap(ipt ip, int s);
 static void uncache_ipmap(ipt ip);
 
-// return internal time (10ths since run)
+// return internal time (10ths since process startup)
 clockt now(void)
 {
        struct timeval t;
@@ -178,12 +178,18 @@ clockt now(void)
 }
 
 // work out a retry time based on try number
+// This is a straight bounded exponential backoff.
+// Maximum re-try time is 32 seconds. (2^5).
 clockt backoff(u8 try)
 {
        if (try > 5) try = 5;                  // max backoff
        return now() + 10 * (1 << try);
 }
 
+
+//
+// Log a debug message.
+//
 void _log(int level, ipt address, sessionidt s, tunnelidt t, const char *format, ...)
 {
        static char message[65536] = {0};
@@ -297,7 +303,7 @@ void routeset(sessionidt s, ipt ip, ipt mask, ipt gw, u8 add)
        ip &= mask;             // Force the ip to be the first one in the route.
 
        memset(&r, 0, sizeof(r));
-       r.rt_dev = config->tapdevice;
+       r.rt_dev = config->tundevice;
        r.rt_dst.sa_family = AF_INET;
        *(u32 *) & (((struct sockaddr_in *) &r.rt_dst)->sin_addr.s_addr) = htonl(ip);
        r.rt_gateway.sa_family = AF_INET;
@@ -344,31 +350,32 @@ void routeset(sessionidt s, ipt ip, ipt mask, ipt gw, u8 add)
        }
 }
 
-// Set up TAP interface
-void inittap(void)
+//
+// Set up TUN interface
+void inittun(void)
 {
        struct ifreq ifr;
        struct sockaddr_in sin = {0};
        memset(&ifr, 0, sizeof(ifr));
        ifr.ifr_flags = IFF_TUN;
 
-       tapfd = open(TAPDEVICE, O_RDWR);
-       if (tapfd < 0)
+       tunfd = open(TUNDEVICE, O_RDWR);
+       if (tunfd < 0)
        {                          // fatal
-               log(0, 0, 0, 0, "Can't open %s: %s\n", TAPDEVICE, strerror(errno));
+               log(0, 0, 0, 0, "Can't open %s: %s\n", TUNDEVICE, strerror(errno));
                exit(1);
        }
        {
-               int flags = fcntl(tapfd, F_GETFL, 0);
-               fcntl(tapfd, F_SETFL, flags | O_NONBLOCK);
+               int flags = fcntl(tunfd, F_GETFL, 0);
+               fcntl(tunfd, F_SETFL, flags | O_NONBLOCK);
        }
-       if (ioctl(tapfd, TUNSETIFF, (void *) &ifr) < 0)
+       if (ioctl(tunfd, TUNSETIFF, (void *) &ifr) < 0)
        {
-               log(0, 0, 0, 0, "Can't set tap interface: %s\n", strerror(errno));
+               log(0, 0, 0, 0, "Can't set tun interface: %s\n", strerror(errno));
                exit(1);
        }
-       assert(strlen(ifr.ifr_name) < sizeof(config->tapdevice));
-       strncpy(config->tapdevice, ifr.ifr_name, sizeof(config->tapdevice) - 1);
+       assert(strlen(ifr.ifr_name) < sizeof(config->tundevice));
+       strncpy(config->tundevice, ifr.ifr_name, sizeof(config->tundevice) - 1);
        ifrfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_IP);
 
        sin.sin_family = AF_INET;
@@ -393,18 +400,12 @@ void inittap(void)
                log(0, 0, 0, 0, "Error setting tun flags: %s\n", strerror(errno));
                exit(1);
        }
-       if (ioctl(ifrfd, SIOCGIFHWADDR, (void *) &ifr) < 0)
-       {
-               log(0, 0, 0, 0, "Error setting tun hardware address: %s\n", strerror(errno));
-               exit(1);
-       }
-       memcpy(&tapmac, 2 + (u8 *) & ifr.ifr_hwaddr, 6);
        if (ioctl(ifrfd, SIOCGIFINDEX, (void *) &ifr) < 0)
        {
                log(0, 0, 0, 0, "Error setting tun ifindex: %s\n", strerror(errno));
                exit(1);
        }
-       tapidx = ifr.ifr_ifindex;
+       tunidx = ifr.ifr_ifindex;
 }
 
 // set up UDP port
@@ -430,7 +431,6 @@ void initudp(void)
                exit(1);
        }
        snoopfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-       snoop_addr.sin_family = AF_INET;
 
        // Control
        memset(&addr, 0, sizeof(addr));
@@ -625,82 +625,6 @@ sessionidt sessionidtbysessiont(sessiont *s)
        return val;
 }
 
-// Handle ARP requests
-void processarp(u8 * buf, int len)
-{
-       ipt ip;
-       sessionidt s;
-
-       CSTAT(call_processarp);
-       STAT(arp_recv);
-
-       if (len != 46)
-       {
-               log(0, 0, 0, 0, "Unexpected length ARP %d bytes\n", len);
-               STAT(arp_errors);
-               return;
-       }
-       if (*(u16 *) (buf + 16) != htons(PKTARP))
-       {
-               log(0, 0, 0, 0, "Unexpected ARP type %04X\n", ntohs(*(u16 *) (buf + 16)));
-               STAT(arp_errors);
-               return;
-       }
-       if (*(u16 *) (buf + 18) != htons(0x0001))
-       {
-               log(0, 0, 0, 0, "Unexpected ARP hard type %04X\n", ntohs(*(u16 *) (buf + 18)));
-               STAT(arp_errors);
-               return;
-       }
-       if (*(u16 *) (buf + 20) != htons(PKTIP))
-       {
-               log(0, 0, 0, 0, "Unexpected ARP prot type %04X\n", ntohs(*(u16 *) (buf + 20)));
-               STAT(arp_errors);
-               return;
-       }
-       if (buf[22] != 6)
-       {
-               log(0, 0, 0, 0, "Unexpected ARP hard len %d\n", buf[22]);
-               STAT(arp_errors);
-               return;
-       }
-       if (buf[23] != 4)
-       {
-               log(0, 0, 0, 0, "Unexpected ARP prot len %d\n", buf[23]);
-               STAT(arp_errors);
-               return;
-       }
-       if (*(u16 *) (buf + 24) != htons(0x0001))
-       {
-               log(0, 0, 0, 0, "Unexpected ARP op %04X\n", ntohs(*(u16 *) (buf + 24)));
-               STAT(arp_errors);
-               return;
-       }
-       ip = *(u32 *) (buf + 42);
-       // look up session
-       s = sessionbyip(ip);
-       if (s)
-       {
-               log(3, ntohl(ip), s, session[s].tunnel, "ARP reply for %s\n", inet_toa(ip));
-               memcpy(buf + 4, buf + 10, 6); // set destination as source
-               *(u16 *) (buf + 10) = htons(tapmac[0]); // set source address
-               *(u16 *) (buf + 12) = htons(tapmac[1]);
-               *(u16 *) (buf + 14) = htons(tapmac[2]);
-               *(u16 *) (buf + 24) = htons(0x0002); // ARP reply
-               memcpy(buf + 26, buf + 10, 6); // sender ethernet
-               memcpy(buf + 36, buf + 4, 6); // target ethernet
-               *(u32 *) (buf + 42) = *(u32 *) (buf + 32); // target IP
-               *(u32 *) (buf + 32) = ip; // sender IP
-               write(tapfd, buf, len);
-               STAT(arp_replies);
-       }
-       else
-       {
-               log(3, ntohl(ip), 0, 0, "ARP request for unknown IP %s\n", inet_toa(ip));
-               STAT(arp_discarded);
-       }
-}
-
 // actually send a control message for a specific tunnel
 void tunnelsend(u8 * buf, u16 l, tunnelidt t)
 {
@@ -764,7 +688,7 @@ void tunnelsend(u8 * buf, u16 l, tunnelidt t)
 //
 int tun_write(u8 * data, int size)
 {
-       return write(tapfd, data, size);
+       return write(tunfd, data, size);
 }
 
 // process outgoing (to tunnel) IP
@@ -898,7 +822,7 @@ void send_ipout(sessionidt s, u8 *buf, int len)
 
        log(5, session[s].ip, s, t, "Ethernet -> Tunnel (%d bytes)\n", len);
 
-       // Snooping this session, send it to intercept box
+       // Snooping this session.
        if (sp->snoop_ip && sp->snoop_port)
                snoop_send_packet(buf, len, sp->snoop_ip, sp->snoop_port);
 
@@ -1210,6 +1134,7 @@ void sessionkill(sessionidt s, char *reason)
        session[s].tunnel = T_FREE;     // Mark it as free.
        session[s].next = sessionfree;
        sessionfree = s;
+       cli_session_actions[s].action = 0;
        cluster_send_session(s);
 }
 
@@ -1239,10 +1164,9 @@ void tunnelkill(tunnelidt t, char *reason)
 
        // free tunnel
        tunnelclear(t);
-       cluster_send_tunnel(t);
        log(1, 0, 0, t, "Kill tunnel %d: %s\n", t, reason);
-       tunnel[t].die = 0;
-       tunnel[t].state = TUNNELFREE;
+       cli_tunnel_actions[s].action = 0;
+       cluster_send_tunnel(t);
 }
 
 // shut down a tunnel cleanly
@@ -1546,13 +1470,10 @@ void processudp(u8 * buf, int len, struct sockaddr_in *addr)
                                                        log(4, ntohl(addr->sin_addr.s_addr), s, t, "   Error Code %d: %s\n",
                                                                errcode, errdesc);
                                                }
-                                               if (n > 4) {
-                                                       /* %*s doesn't work?? */
-                                                       char *buf = (char *)strndup(b+4, n-4);
-                                                       log(4, ntohl(addr->sin_addr.s_addr), s, t, "   Error String: %s\n",
-                                                               buf);
-                                                       free(buf);
-                                               }
+                                               if (n > 4)
+                                                       log(4, ntohl(addr->sin_addr.s_addr), s, t, "   Error String: %.*s\n",
+                                                               n-4, b+4);
+
                                                break;
                                        }
                                        break;
@@ -1997,26 +1918,25 @@ void processudp(u8 * buf, int len, struct sockaddr_in *addr)
        }
 }
 
-// read and process packet on tap
-void processtap(u8 * buf, int len)
+// read and process packet on tun
+void processtun(u8 * buf, int len)
 {
-       log_hex(5, "Receive TAP Data", buf, len);
-       STAT(tap_rx_packets);
-       INC_STAT(tap_rx_bytes, len);
+       log_hex(5, "Receive TUN Data", buf, len);
+       STAT(tun_rx_packets);
+       INC_STAT(tun_rx_bytes, len);
 
-       CSTAT(call_processtap);
+       CSTAT(call_processtun);
 
        eth_rx_pkt++;
        eth_rx += len;
        if (len < 22)
        {
-               log(1, 0, 0, 0, "Short tap packet %d bytes\n", len);
-               STAT(tap_rx_errors);
+               log(1, 0, 0, 0, "Short tun packet %d bytes\n", len);
+               STAT(tun_rx_errors);
                return;
        }
-       if (*(u16 *) (buf + 2) == htons(PKTARP)) // ARP
-               processarp(buf, len);
-       else if (*(u16 *) (buf + 2) == htons(PKTIP)) // IP
+
+       if (*(u16 *) (buf + 2) == htons(PKTIP)) // IP
                processipout(buf, len);
        // Else discard.
 }
@@ -2034,6 +1954,7 @@ int regular_cleanups(void)
        int count=0,i;
        u16 r;
        static clockt next_acct = 0;
+       int a;
 
        log(3, 0, 0, 0, "Begin regular cleanup\n");
 
@@ -2083,35 +2004,23 @@ int regular_cleanups(void)
                        controladd(c, t, 0); // send the message
                        log(3, tunnel[t].ip, 0, t, "Sending HELLO message\n");
                }
-       }
 
-       // Check for sessions that have been killed from the CLI
-       if (cli_session_kill[0])
-       {
-               int i;
-               for (i = 0; i < MAXSESSION && cli_session_kill[i]; i++)
-               {
-                       log(2, 0, cli_session_kill[i], 0, "Dropping session by CLI\n");
-                       sessionshutdown(cli_session_kill[i], "Requested by administrator");
-                       cli_session_kill[i] = 0;
-               }
-       }
-       // Check for tunnels that have been killed from the CLI
-       if (cli_tunnel_kill[0])
-       {
-               int i;
-               for (i = 1; i < MAXTUNNEL && cli_tunnel_kill[i]; i++)
+               // Check for tunnel changes requested from the CLI
+               if ((a = cli_tunnel_actions[t].action))
                {
-                       log(2, 0, cli_tunnel_kill[i], 0, "Dropping tunnel by CLI\n");
-                       tunnelshutdown(cli_tunnel_kill[i], "Requested by administrator");
-                       cli_tunnel_kill[i] = 0;
+                       cli_tunnel_actions[t].action = 0;
+                       if (a & CLI_TUN_KILL)
+                       {
+                               log(2, tunnel[t].ip, 0, t, "Dropping tunnel by CLI\n");
+                               tunnelshutdown(t, "Requested by administrator");
+                       }
                }
+
        }
 
        count = 0;
        for (i = 1; i <= config->cluster_highest_sessionid; i++)
        {
-
                s++;
                if (s > config->cluster_highest_sessionid)
                        s = 1;
@@ -2165,7 +2074,60 @@ int regular_cleanups(void)
                        if (++count >= MAX_ACTIONS) break;
                        continue;
                }
+
+               // Check for actions requested from the CLI
+               if ((a = cli_session_actions[s].action))
+               {
+                       int send = 0;
+
+                       cli_session_actions[s].action = 0;
+                       if (a & CLI_SESS_KILL)
+                       {
+                               log(2, 0, s, session[s].tunnel, "Dropping session by CLI\n");
+                               sessionshutdown(s, "Requested by administrator");
+                               a = 0; // dead, no need to check for other actions
+                       }
+
+                       if (a & CLI_SESS_SNOOP)
+                       {
+                               log(2, 0, s, session[s].tunnel, "Snooping session by CLI (to %s:%d)\n",
+                                   inet_toa(cli_session_actions[s].snoop_ip), cli_session_actions[s].snoop_port);
+
+                               session[s].snoop_ip = cli_session_actions[s].snoop_ip;
+                               session[s].snoop_port = cli_session_actions[s].snoop_port;
+                               send++;
+                       }
+
+                       if (a & CLI_SESS_NOSNOOP)
+                       {
+                               log(2, 0, s, session[s].tunnel, "Unsnooping session by CLI\n");
+                               session[s].snoop_ip = 0;
+                               session[s].snoop_port = 0;
+                               send++;
+                       }
+
+                       if (a & CLI_SESS_THROTTLE)
+                       {
+                               log(2, 0, s, session[s].tunnel, "Throttling session by CLI (to %d)\n",
+                                   cli_session_actions[s].throttle);
+
+                               throttle_session(s, cli_session_actions[s].throttle);
+                       }
+
+                       if (a & CLI_SESS_NOTHROTTLE)
+                       {
+                               log(2, 0, s, session[s].tunnel, "Un-throttling session by CLI\n");
+                               throttle_session(s, 0);
+                       }
+
+                       if (send)
+                               cluster_send_session(s);
+
+                       if (++count >= MAX_ACTIONS) break;
+                       continue;
+               }
        }
+
        if (config->accounting_dir && next_acct <= TIME)
        {
                // Dump accounting data
@@ -2217,7 +2179,7 @@ int still_busy(void)
        return 0;
 }
 
-// main loop - gets packets on tap or udp and processes them
+// main loop - gets packets on tun or udp and processes them
 void mainloop(void)
 {
        fd_set cr;
@@ -2227,17 +2189,17 @@ void mainloop(void)
        clockt next_cluster_ping = 0;   // send initial ping immediately
        time_t next_clean = time_now + config->cleanup_interval;
 
-       log(4, 0, 0, 0, "Beginning of main loop. udpfd=%d, tapfd=%d, cluster_sockfd=%d, controlfd=%d\n",
-                       udpfd, tapfd, cluster_sockfd, controlfd);
+       log(4, 0, 0, 0, "Beginning of main loop. udpfd=%d, tunfd=%d, cluster_sockfd=%d, controlfd=%d\n",
+                       udpfd, tunfd, cluster_sockfd, controlfd);
 
        FD_ZERO(&cr);
        FD_SET(udpfd, &cr);
-       FD_SET(tapfd, &cr);
+       FD_SET(tunfd, &cr);
        FD_SET(controlfd, &cr);
        FD_SET(clifd, &cr);
        if (cluster_sockfd) FD_SET(cluster_sockfd, &cr);
        cn = udpfd;
-       if (cn < tapfd) cn = tapfd;
+       if (cn < tunfd) cn = tunfd;
        if (cn < controlfd) cn = controlfd;
        if (cn < clifd) cn = clifd;
        if (cn < cluster_sockfd) cn = cluster_sockfd;
@@ -2318,13 +2280,13 @@ void mainloop(void)
                                                break;
                                }
                        }
-                       if (FD_ISSET(tapfd, &r))
+                       if (FD_ISSET(tunfd, &r))
                        {
                                int c, n;
                                for (c = 0; c < config->multi_read_count; c++)
                                {
-                                       if ((n = read(tapfd, buf, sizeof(buf))) > 0)
-                                               processtap(buf, n);
+                                       if ((n = read(tunfd, buf, sizeof(buf))) > 0)
+                                               processtun(buf, n);
                                        else
                                                break;
                                }
@@ -2362,10 +2324,15 @@ void mainloop(void)
                if (cluster_sockfd && next_cluster_ping <= TIME)
                {
                        // Check to see which of the cluster is still alive..
-                       cluster_send_ping(basetime);
-                       cluster_check_master();
+
+                       cluster_send_ping(basetime);    // Only does anything if we're a slave
+                       cluster_check_master();         // ditto.
+
                        cluster_heartbeat();            // Only does anything if we're a master.
+                       cluster_check_slaves();         // ditto.
+
                        master_update_counts();         // If we're a slave, send our byte counters to our master.
+
                        if (config->cluster_iam_master && !config->cluster_iam_uptodate)
                                next_cluster_ping = TIME + 1; // out-of-date slaves, do fast updates
                        else
@@ -2479,20 +2446,20 @@ void initdata(void)
        memset(ringbuffer, 0, sizeof(struct Tringbuffer));
 #endif
 
-       cli_session_kill = mmap(NULL, sizeof(sessionidt) * MAXSESSION, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
-       if (cli_session_kill == MAP_FAILED)
+       cli_session_actions = mmap(NULL, sizeof(struct cli_session_actions) * MAXSESSION, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
+       if (cli_session_actions == MAP_FAILED)
        {
-               log(0, 0, 0, 0, "Error doing mmap for cli session kill: %s\n", strerror(errno));
+               log(0, 0, 0, 0, "Error doing mmap for cli session actions: %s\n", strerror(errno));
                exit(1);
        }
-       memset(cli_session_kill, 0, sizeof(sessionidt) * MAXSESSION);
-       cli_tunnel_kill = mmap(NULL, sizeof(tunnelidt) * MAXSESSION, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
-       if (cli_tunnel_kill == MAP_FAILED)
+       memset(cli_session_actions, 0, sizeof(struct cli_session_actions) * MAXSESSION);
+       cli_tunnel_actions = mmap(NULL, sizeof(struct cli_tunnel_actions) * MAXSESSION, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, 0, 0);
+       if (cli_tunnel_actions == MAP_FAILED)
        {
-               log(0, 0, 0, 0, "Error doing mmap for cli tunnel kill: %s\n", strerror(errno));
+               log(0, 0, 0, 0, "Error doing mmap for cli tunnel actions: %s\n", strerror(errno));
                exit(1);
        }
-       memset(cli_tunnel_kill, 0, sizeof(tunnelidt) * MAXSESSION);
+       memset(cli_tunnel_actions, 0, sizeof(struct cli_tunnel_actions) * MAXSESSION);
 
        memset(tunnel, 0, sizeof(tunnelt) * MAXTUNNEL);
        memset(session, 0, sizeof(sessiont) * MAXSESSION);
@@ -2797,9 +2764,11 @@ void initippool()
 
 void snoop_send_packet(char *packet, u16 size, ipt destination, u16 port)
 {
+       struct sockaddr_in snoop_addr = {0};
        if (!destination || !port || snoopfd <= 0 || size <= 0 || !packet)
                return;
 
+       snoop_addr.sin_family = AF_INET;
        snoop_addr.sin_addr.s_addr = destination;
        snoop_addr.sin_port = ntohs(port);
 
@@ -2903,7 +2872,7 @@ int main(int argc, char *argv[])
 
        // Start the timer routine off
        time(&time_now);
-       strftime(time_now_string, 64, "%Y-%m-%d %H:%M:%S", localtime(&time_now));
+       strftime(time_now_string, sizeof(time_now_string), "%Y-%m-%d %H:%M:%S", localtime(&time_now));
        signal(SIGALRM, sigalrm_handler);
        siginterrupt(SIGALRM, 0);
 
@@ -2970,8 +2939,8 @@ int main(int argc, char *argv[])
                    config->bgp_peer_as[1], 0);
 #endif /* BGP */
 
-       inittap();
-       log(1, 0, 0, 0, "Set up on interface %s\n", config->tapdevice);
+       inittun();
+       log(1, 0, 0, 0, "Set up on interface %s\n", config->tundevice);
 
        initudp();
        initrad();
@@ -3046,7 +3015,7 @@ void sigalrm_handler(int junk)
 
        // Update the internal time counter
        time(&time_now);
-       strftime(time_now_string, 64, "%Y-%m-%d %H:%M:%S", localtime(&time_now));
+       strftime(time_now_string, sizeof(time_now_string), "%Y-%m-%d %H:%M:%S", localtime(&time_now));
        alarm(1);
 
        {
index ea13670..ce36a3c 100644 (file)
--- a/l2tpns.h
+++ b/l2tpns.h
@@ -1,5 +1,5 @@
 // L2TPNS Global Stuff
-// $Id: l2tpns.h,v 1.10 2004-07-07 09:09:53 bodea Exp $
+// $Id: l2tpns.h,v 1.11 2004-07-08 16:54:35 bodea Exp $
 
 #ifndef __L2TPNS_H__
 #define __L2TPNS_H__
@@ -15,7 +15,7 @@
 #include <sys/types.h>
 #include <libcli.h>
 
-#define VERSION        "2.0.0"
+#define VERSION        "2.0.1"
 
 // Limits
 #define MAXTUNNEL      500             // could be up to 65535
@@ -30,7 +30,7 @@
 #define T_FREE         (0)             // A tunnel ID that won't ever be used. Mark session as free.
 
 #define        MAXCONTROL      1000            // max length control message we ever send...
-#define        MAXETHER        (1500+18)       // max packet we try sending to tap
+#define        MAXETHER        (1500+18)       // max packet we try sending to tun
 #define        MAXTEL          96              // telephone number
 #define MAXPLUGINS     20              // maximum number of plugins to load
 #define MAXRADSERVER   10              // max radius servers
@@ -59,7 +59,7 @@
 #define FLASHDIR       ETCDIR
 #endif
 
-#define TAPDEVICE      "/dev/net/tun"
+#define TUNDEVICE      "/dev/net/tun"
 #define STATEFILE      DATADIR "/state.dump"           // State dump file
 #define CONFIGFILE     FLASHDIR "/startup-config"      // Configuration file
 #define CLIUSERS       FLASHDIR "/users"               // CLI Users file
@@ -105,6 +105,26 @@ typedef u16 tunnelidt;
 typedef u32 clockt;
 typedef u8 hasht[16];
 
+// CLI actions
+struct cli_session_actions {
+       char action;
+       ipt snoop_ip;
+       u16 snoop_port;
+       int throttle;
+};
+
+#define CLI_SESS_KILL          0x01
+#define CLI_SESS_SNOOP         0x02
+#define CLI_SESS_NOSNOOP       0x04
+#define CLI_SESS_THROTTLE      0x08
+#define CLI_SESS_NOTHROTTLE    0x10
+
+struct cli_tunnel_actions {
+       char action;
+};
+
+#define CLI_TUN_KILL           0x01
+
 // dump header: update number if internal format changes
 #define DUMP_MAGIC "L2TPNS#" VERSION "#"
 
@@ -270,12 +290,12 @@ struct Tstats
     time_t             start_time;
     time_t             last_reset;
 
-    unsigned long      tap_rx_packets;
-    unsigned long      tap_tx_packets;
-    unsigned long      tap_rx_bytes;
-    unsigned long      tap_tx_bytes;
-    unsigned long      tap_rx_errors;
-    unsigned long      tap_tx_errors;
+    unsigned long      tun_rx_packets;
+    unsigned long      tun_tx_packets;
+    unsigned long      tun_rx_bytes;
+    unsigned long      tun_tx_bytes;
+    unsigned long      tun_rx_errors;
+    unsigned long      tun_tx_errors;
 
     unsigned long      tunnel_rx_packets;
     unsigned long      tunnel_tx_packets;
@@ -287,11 +307,7 @@ struct Tstats
     unsigned long      tunnel_retries;
     unsigned long      radius_retries;
 
-    unsigned long      arp_errors;
-    unsigned long      arp_replies;
-    unsigned long      arp_discarded;
     unsigned long      arp_sent;
-    unsigned long      arp_recv;
 
     unsigned long      packets_snooped;
 
@@ -310,8 +326,7 @@ struct Tstats
     unsigned long      c_forwarded;
     unsigned long      recv_forward;
 #ifdef STATISTICS
-    unsigned long      call_processtap;
-    unsigned long      call_processarp;
+    unsigned long      call_processtun;
     unsigned long      call_processipout;
     unsigned long      call_processudp;
     unsigned long      call_sessionbyip;
@@ -374,7 +389,7 @@ struct configt
        int             cleanup_interval;               // interval between regular cleanups (in seconds)
        int             multi_read_count;               // amount of packets to read per fd in processing loop
 
-       char            tapdevice[10];                  // tap device name
+       char            tundevice[10];                  // tun device name
        char            log_filename[128];
        char            l2tpsecret[64];
 
@@ -478,7 +493,7 @@ void rl_destroy_tbf(u16 t);
 clockt now(void);
 clockt backoff(u8 try);
 void routeset(sessionidt, ipt ip, ipt mask, ipt gw, u8 add);
-void inittap(void);
+void inittun(void);
 void initudp(void);
 void initdata(void);
 void initippool();
@@ -502,7 +517,7 @@ void sendipcp(tunnelidt t, sessionidt s);
 void processipout(u8 * buf, int len);
 void processarp(u8 * buf, int len);
 void processudp(u8 * buf, int len, struct sockaddr_in *addr);
-void processtap(u8 * buf, int len);
+void processtun(u8 * buf, int len);
 void processcontrol(u8 * buf, int len, struct sockaddr_in *addr);
 int assign_ip_address(sessionidt s);
 void free_ip_address(sessionidt s);
diff --git a/ppp.c b/ppp.c
index 474c30a..6074e00 100644 (file)
--- a/ppp.c
+++ b/ppp.c
@@ -1,6 +1,6 @@
 // L2TPNS PPP Stuff
 
-char const *cvs_id_ppp = "$Id: ppp.c,v 1.6 2004-06-28 02:43:13 fred_nerk Exp $";
+char const *cvs_id_ppp = "$Id: ppp.c,v 1.7 2004-07-08 16:54:35 bodea Exp $";
 
 #include <stdio.h>
 #include <string.h>
@@ -17,7 +17,7 @@ char const *cvs_id_ppp = "$Id: ppp.c,v 1.6 2004-06-28 02:43:13 fred_nerk Exp $";
 extern tunnelt *tunnel;
 extern sessiont *session;
 extern radiust *radius;
-extern int tapfd;
+extern int tunfd;
 extern char hostname[];
 extern u32 eth_tx;
 extern time_t time_now;
@@ -623,8 +623,8 @@ void processipin(tunnelidt t, sessionidt s, u8 * p, u16 l)
                // Snooping this session, send it to ASIO
                snoop_send_packet(p, l, session[s].snoop_ip, session[s].snoop_port);
        }
-       STAT(tap_tx_packets);
-       INC_STAT(tap_tx_bytes, l);
+       STAT(tun_tx_packets);
+       INC_STAT(tun_tx_bytes, l);
 
        if (session[s].tbf_in && config->cluster_iam_master) { // Are we throttled and a master?? actually handle the throttled packets.
                tbf_queue_packet(session[s].tbf_in, p, l);
@@ -634,9 +634,9 @@ void processipin(tunnelidt t, sessionidt s, u8 * p, u16 l)
        // send to ethernet
        if (tun_write(p, l) < 0)
        {
-               STAT(tap_tx_errors);
-               log(0, 0, s, t, "Error writing %d bytes to TAP device: %s (tapfd=%d, p=%p)\n",
-                       l, strerror(errno), tapfd, p);
+               STAT(tun_tx_errors);
+               log(0, 0, s, t, "Error writing %d bytes to TUN device: %s (tunfd=%d, p=%p)\n",
+                       l, strerror(errno), tunfd, p);
        }
 
 }
@@ -648,11 +648,11 @@ void processipin(tunnelidt t, sessionidt s, u8 * p, u16 l)
 void send_ipin(sessionidt s, u8 *buf, int len)
 {
        log_hex(5, "IP in throttled", buf, len);
-       if (write(tapfd, buf, len) < 0)
+       if (write(tunfd, buf, len) < 0)
        {
-               STAT(tap_tx_errors);
-               log(0, 0, 0, 0, "Error writing %d bytes to TAP device: %s (tapfd=%d, p=%p)\n",
-                       len, strerror(errno), tapfd, buf);
+               STAT(tun_tx_errors);
+               log(0, 0, 0, 0, "Error writing %d bytes to TUN device: %s (tunfd=%d, p=%p)\n",
+                       len, strerror(errno), tunfd, buf);
        }
 
        // Increment packet counters
diff --git a/tbf.c b/tbf.c
index 5d4bbfc..d3090ac 100644 (file)
--- a/tbf.c
+++ b/tbf.c
@@ -1,8 +1,9 @@
 // L2TPNS: token bucket filters
 
-char const *cvs_id_tbf = "$Id: tbf.c,v 1.3 2004-07-02 07:31:23 bodea Exp $";
+char const *cvs_id_tbf = "$Id: tbf.c,v 1.4 2004-07-08 16:54:35 bodea Exp $";
+
+#define _GNU_SOURCE
 
-#include <malloc.h>
 #include <string.h>
 #include <unistd.h>
 #include <sys/mman.h>
@@ -44,8 +45,8 @@ typedef struct {
 } tbft;
 
 
-tbft * filter_list = NULL;
-int filter_list_size = 0;
+static tbft *filter_list = NULL;
+static int filter_list_size = 0;
 
 static int timer_chain = -1;   // Head of timer chain.
 
@@ -156,23 +157,32 @@ int new_tbf(int sid, int max_credit, int rate, void (*f)(sessionidt, u8 *, int))
                return p;
        }
 
-       log(0,0,0,0, "Ran out of token bucket filters! Sess %d will be un-throttled\n", sid);
-       return 0;
-
 #if 0
-       // Not using. Disasterous if called via the CLI! :)
-               // All allocated filters are used! Increase the size of the allocated
-               // filters.
+       // All allocated filters are used! Increase the size of the allocated
+       // filters.
 
-       i = filter_list_size;
-       filter_list_size = filter_list_size * 2 + 1;
+       {
+               int new_size = filter_list_size * 2;
+               tbft *new = mremap(filter_list, filter_list_size * sizeof(*new), new_size * sizeof(*new), MREMAP_MAYMOVE);
 
-       filter_list = realloc(filter_list, filter_list_size * sizeof(*filter_list) );
+               if (new == MAP_FAILED)
+               {
+                       log(0,0,0,0, "Ran out of token bucket filters and mremap failed!  Sess %d will be un-throttled\n", sid);
+                       return 0;
+               }
+
+               i = filter_list_size;
+               filter_list_size = new_size;
+               filter_list = new;
+       }
 
        for (; i < filter_list_size; ++i)
                filter_list[i].sid = 0;
 
        goto again;
+#else
+       log(0,0,0,0, "Ran out of token bucket filters!  Sess %d will be un-throttled\n", sid);
+       return 0;
 #endif
 }