merge in changes from 2.0 branch; fix byte counters in accounting records, add gigawords
This commit is contained in:
parent
ebfbe027e3
commit
bd2ec60149
11 changed files with 332 additions and 189 deletions
7
Changes
7
Changes
|
|
@ -79,6 +79,13 @@
|
||||||
routes.
|
routes.
|
||||||
- New config option: allow_duplicate_users which determines whether
|
- New config option: allow_duplicate_users which determines whether
|
||||||
or not to kill older sessions with the same username.
|
or not to kill older sessions with the same username.
|
||||||
|
- Show session open time in "show session"/"show user" detailed output.
|
||||||
|
- Have slaves with BGP configured drop BGP on receipt of a shutdown
|
||||||
|
signal, but hang about for an additional 5s to process any remaining
|
||||||
|
traffic.
|
||||||
|
- Run regular_cleanups after processing the results of the select,
|
||||||
|
looking at a sufficient slice of each table to ensure that all
|
||||||
|
entries are examined at least once per second.
|
||||||
|
|
||||||
* Fri Dec 17 2004 Brendan O'Dea <bod@optusnet.com.au> 2.0.13
|
* Fri Dec 17 2004 Brendan O'Dea <bod@optusnet.com.au> 2.0.13
|
||||||
- Better cluster master collision resolution: keep a counter of state
|
- Better cluster master collision resolution: keep a counter of state
|
||||||
|
|
|
||||||
|
|
@ -285,10 +285,6 @@ second. Even if this is disabled, you can see this information by running
|
||||||
the <EM>uptime</EM> command on the CLI.
|
the <EM>uptime</EM> command on the CLI.
|
||||||
</LI>
|
</LI>
|
||||||
|
|
||||||
<LI><B>cleanup_interval</B> (int)<BR>
|
|
||||||
Interval between regular cleanups (in seconds).
|
|
||||||
</LI>
|
|
||||||
|
|
||||||
<LI><B>multi_read_count</B> (int)<BR>
|
<LI><B>multi_read_count</B> (int)<BR>
|
||||||
Number of packets to read off each of the UDP and TUN fds when
|
Number of packets to read off each of the UDP and TUN fds when
|
||||||
returned as readable by select (default: 10). Avoids incurring the
|
returned as readable by select (default: 10). Avoids incurring the
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
.de Id
|
.de Id
|
||||||
.ds Dt \\$4 \\$5
|
.ds Dt \\$4 \\$5
|
||||||
..
|
..
|
||||||
.Id $Id: startup-config.5,v 1.9 2005-06-02 04:04:08 bodea Exp $
|
.Id $Id: startup-config.5,v 1.10 2005-06-02 11:32:33 bodea Exp $
|
||||||
.TH STARTUP-CONFIG 5 "\*(Dt" L2TPNS "File Formats and Conventions"
|
.TH STARTUP-CONFIG 5 "\*(Dt" L2TPNS "File Formats and Conventions"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
startup\-config \- configuration file for l2tpns
|
startup\-config \- configuration file for l2tpns
|
||||||
|
|
@ -91,10 +91,7 @@ record when the session is closed.
|
||||||
If
|
If
|
||||||
.B radius_accounting
|
.B radius_accounting
|
||||||
is on, defines the interval between sending of RADIUS interim
|
is on, defines the interval between sending of RADIUS interim
|
||||||
accounting records (in seconds). Note: checking of this interval
|
accounting records (in seconds).
|
||||||
occurs no more frequently than
|
|
||||||
.B cleanup_interval
|
|
||||||
seconds (see below).
|
|
||||||
.TP
|
.TP
|
||||||
.B radius_secret
|
.B radius_secret
|
||||||
Secret to be used in RADIUS packets.
|
Secret to be used in RADIUS packets.
|
||||||
|
|
@ -145,9 +142,6 @@ by running the
|
||||||
.B uptime
|
.B uptime
|
||||||
command on the CLI.
|
command on the CLI.
|
||||||
.TP
|
.TP
|
||||||
.B cleanup_interval
|
|
||||||
Interval between regular cleanups (in seconds).
|
|
||||||
.TP
|
|
||||||
.B multi_read_count
|
.B multi_read_count
|
||||||
Number of packets to read off each of the UDP and TUN fds when
|
Number of packets to read off each of the UDP and TUN fds when
|
||||||
returned as readable by select (default: 10). Avoids incurring the
|
returned as readable by select (default: 10). Avoids incurring the
|
||||||
|
|
|
||||||
8
cli.c
8
cli.c
|
|
@ -2,7 +2,7 @@
|
||||||
// vim: sw=8 ts=8
|
// vim: sw=8 ts=8
|
||||||
|
|
||||||
char const *cvs_name = "$Name: $";
|
char const *cvs_name = "$Name: $";
|
||||||
char const *cvs_id_cli = "$Id: cli.c,v 1.59 2005-06-02 03:52:46 bodea Exp $";
|
char const *cvs_id_cli = "$Id: cli.c,v 1.60 2005-06-02 11:32:30 bodea Exp $";
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
@ -411,7 +411,7 @@ static int cmd_show_session(struct cli_def *cli, char *command, char **argv, int
|
||||||
cli_print(cli, "\tIdle time:\t%u seconds", abs(time_now - session[s].last_packet));
|
cli_print(cli, "\tIdle time:\t%u seconds", abs(time_now - session[s].last_packet));
|
||||||
cli_print(cli, "\tNext Recv:\t%u", session[s].nr);
|
cli_print(cli, "\tNext Recv:\t%u", session[s].nr);
|
||||||
cli_print(cli, "\tNext Send:\t%u", session[s].ns);
|
cli_print(cli, "\tNext Send:\t%u", session[s].ns);
|
||||||
cli_print(cli, "\tBytes In/Out:\t%u/%u", session[s].total_cout, session[s].total_cin);
|
cli_print(cli, "\tBytes In/Out:\t%u/%u", session[s].cout, session[s].cin);
|
||||||
cli_print(cli, "\tPkts In/Out:\t%u/%u", session[s].pout, session[s].pin);
|
cli_print(cli, "\tPkts In/Out:\t%u/%u", session[s].pout, session[s].pin);
|
||||||
cli_print(cli, "\tMRU:\t\t%d", session[s].mru);
|
cli_print(cli, "\tMRU:\t\t%d", session[s].mru);
|
||||||
cli_print(cli, "\tRx Speed:\t%u", session[s].rx_connect_speed);
|
cli_print(cli, "\tRx Speed:\t%u", session[s].rx_connect_speed);
|
||||||
|
|
@ -507,8 +507,8 @@ static int cmd_show_session(struct cli_def *cli, char *command, char **argv, int
|
||||||
(session[i].walled_garden) ? "Y" : "N",
|
(session[i].walled_garden) ? "Y" : "N",
|
||||||
(session[i].flags & SF_IPV6CP_ACKED) ? "Y" : "N",
|
(session[i].flags & SF_IPV6CP_ACKED) ? "Y" : "N",
|
||||||
abs(time_now - (unsigned long)session[i].opened),
|
abs(time_now - (unsigned long)session[i].opened),
|
||||||
(unsigned long)session[i].total_cout,
|
(unsigned long)session[i].cout,
|
||||||
(unsigned long)session[i].total_cin,
|
(unsigned long)session[i].cin,
|
||||||
abs(time_now - (session[i].last_packet ? session[i].last_packet : time_now)),
|
abs(time_now - (session[i].last_packet ? session[i].last_packet : time_now)),
|
||||||
fmtaddr(htonl(tunnel[ session[i].tunnel ].ip), 1),
|
fmtaddr(htonl(tunnel[ session[i].tunnel ].ip), 1),
|
||||||
session[i].calling[0] ? session[i].calling : "*");
|
session[i].calling[0] ? session[i].calling : "*");
|
||||||
|
|
|
||||||
69
cluster.c
69
cluster.c
|
|
@ -1,6 +1,6 @@
|
||||||
// L2TPNS Clustering Stuff
|
// L2TPNS Clustering Stuff
|
||||||
|
|
||||||
char const *cvs_id_cluster = "$Id: cluster.c,v 1.39 2005-05-26 12:17:30 bodea Exp $";
|
char const *cvs_id_cluster = "$Id: cluster.c,v 1.40 2005-06-02 11:32:30 bodea Exp $";
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
@ -287,7 +287,7 @@ int master_forward_packet(char *data, int size, in_addr_t addr, int port)
|
||||||
LOG(4, 0, 0, "Forwarding packet from %s to master (size %d)\n", fmtaddr(addr, 0), size);
|
LOG(4, 0, 0, "Forwarding packet from %s to master (size %d)\n", fmtaddr(addr, 0), size);
|
||||||
|
|
||||||
STAT(c_forwarded);
|
STAT(c_forwarded);
|
||||||
add_type(&p, C_FORWARD, addr, (char *) &port, sizeof(port));
|
add_type(&p, C_FORWARD, addr, (char *) &port, sizeof(port)); // ick. should be uint16_t
|
||||||
memcpy(p, data, size);
|
memcpy(p, data, size);
|
||||||
p += size;
|
p += size;
|
||||||
|
|
||||||
|
|
@ -402,10 +402,16 @@ void master_update_counts(void)
|
||||||
if (config->cluster_iam_master) // Only happens on the slaves.
|
if (config->cluster_iam_master) // Only happens on the slaves.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!config->cluster_master_address) // If we don't have a master, skip it for a while.
|
if (!config->cluster_master_address) // If we don't have a master, skip it for a while.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
i = MAX_B_RECS * 5; // Examine max 2000 sessions;
|
// C_BYTES format changed in 2.1.0 (cluster version 5)
|
||||||
|
// during upgrade from previous versions, hang onto our counters
|
||||||
|
// for a bit until the new master comes up
|
||||||
|
if (config->cluster_last_hb_ver < 5)
|
||||||
|
return;
|
||||||
|
|
||||||
|
i = MAX_B_RECS * 5; // Examine max 3000 sessions;
|
||||||
if (config->cluster_highest_sessionid > i)
|
if (config->cluster_highest_sessionid > i)
|
||||||
i = config->cluster_highest_sessionid;
|
i = config->cluster_highest_sessionid;
|
||||||
|
|
||||||
|
|
@ -416,17 +422,20 @@ void master_update_counts(void)
|
||||||
walk_session_number = 1;
|
walk_session_number = 1;
|
||||||
|
|
||||||
if (!sess_local[walk_session_number].cin && !sess_local[walk_session_number].cout)
|
if (!sess_local[walk_session_number].cin && !sess_local[walk_session_number].cout)
|
||||||
continue; // Unused. Skip it.
|
continue; // Unchanged. Skip it.
|
||||||
|
|
||||||
b[c].sid = walk_session_number;
|
b[c].sid = walk_session_number;
|
||||||
b[c].in = sess_local[walk_session_number].cin;
|
b[c].pin = sess_local[walk_session_number].pin;
|
||||||
b[c].out = sess_local[walk_session_number].cout;
|
b[c].pout = sess_local[walk_session_number].pout;
|
||||||
|
b[c].cin = sess_local[walk_session_number].cin;
|
||||||
if (++c > MAX_B_RECS) // Send a max of 400 elements in a packet.
|
b[c].cout = sess_local[walk_session_number].cout;
|
||||||
break;
|
|
||||||
|
|
||||||
// Reset counters.
|
// Reset counters.
|
||||||
|
sess_local[walk_session_number].pin = sess_local[walk_session_number].pout = 0;
|
||||||
sess_local[walk_session_number].cin = sess_local[walk_session_number].cout = 0;
|
sess_local[walk_session_number].cin = sess_local[walk_session_number].cout = 0;
|
||||||
|
|
||||||
|
if (++c > MAX_B_RECS) // Send a max of 600 elements in a packet.
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!c) // Didn't find any that changes. Get out of here!
|
if (!c) // Didn't find any that changes. Get out of here!
|
||||||
|
|
@ -527,6 +536,10 @@ void cluster_check_master(void)
|
||||||
|
|
||||||
LOG(0, 0, 0, "Master timed out! Holding election...\n");
|
LOG(0, 0, 0, "Master timed out! Holding election...\n");
|
||||||
|
|
||||||
|
// In the process of shutting down, can't be master
|
||||||
|
if (main_quit)
|
||||||
|
return;
|
||||||
|
|
||||||
for (i = have_peers = 0; i < num_peers; i++)
|
for (i = have_peers = 0; i < num_peers; i++)
|
||||||
{
|
{
|
||||||
if ((peers[i].timestamp + config->cluster_hb_timeout) < t)
|
if ((peers[i].timestamp + config->cluster_hb_timeout) < t)
|
||||||
|
|
@ -610,13 +623,17 @@ void cluster_check_master(void)
|
||||||
// Reset die relative to our uptime rather than the old master's
|
// Reset die relative to our uptime rather than the old master's
|
||||||
if (session[i].die) session[i].die = TIME;
|
if (session[i].die) session[i].die = TIME;
|
||||||
|
|
||||||
// Accumulate un-sent byte counters.
|
// Accumulate un-sent byte/packet counters.
|
||||||
session[i].cin += sess_local[i].cin;
|
increment_counter(&session[i].cin, &session[i].cin_wrap, sess_local[i].cin);
|
||||||
session[i].cout += sess_local[i].cout;
|
increment_counter(&session[i].cout, &session[i].cout_wrap, sess_local[i].cout);
|
||||||
session[i].total_cin += sess_local[i].cin;
|
session[i].cin_delta += sess_local[i].cin;
|
||||||
session[i].total_cout += sess_local[i].cout;
|
session[i].cout_delta += sess_local[i].cout;
|
||||||
|
|
||||||
|
session[i].pin += sess_local[i].pin;
|
||||||
|
session[i].pout += sess_local[i].pout;
|
||||||
|
|
||||||
sess_local[i].cin = sess_local[i].cout = 0;
|
sess_local[i].cin = sess_local[i].cout = 0;
|
||||||
|
sess_local[i].pin = sess_local[i].pout = 0;
|
||||||
|
|
||||||
sess_local[i].radius = 0; // Reset authentication as the radius blocks aren't up to date.
|
sess_local[i].radius = 0; // Reset authentication as the radius blocks aren't up to date.
|
||||||
|
|
||||||
|
|
@ -1078,13 +1095,16 @@ static int cluster_handle_bytes(char *data, int size)
|
||||||
return -1; /* Abort processing */
|
return -1; /* Abort processing */
|
||||||
}
|
}
|
||||||
|
|
||||||
session[b->sid].total_cin += b->in;
|
session[b->sid].pin += b->pin;
|
||||||
session[b->sid].total_cout += b->out;
|
session[b->sid].pout += b->pout;
|
||||||
|
|
||||||
session[b->sid].cin += b->in;
|
increment_counter(&session[b->sid].cin, &session[b->sid].cin_wrap, b->cin);
|
||||||
session[b->sid].cout += b->out;
|
increment_counter(&session[b->sid].cout, &session[b->sid].cout_wrap, b->cout);
|
||||||
|
|
||||||
if (b->in)
|
session[b->sid].cin_delta += b->cin;
|
||||||
|
session[b->sid].cout_delta += b->cout;
|
||||||
|
|
||||||
|
if (b->cin)
|
||||||
session[b->sid].last_packet = time_now; // Reset idle timer!
|
session[b->sid].last_packet = time_now; // Reset idle timer!
|
||||||
|
|
||||||
size -= sizeof(*b);
|
size -= sizeof(*b);
|
||||||
|
|
@ -1223,12 +1243,12 @@ static uint8_t *convert_session(struct oldsession *old)
|
||||||
new.nr = old->nr;
|
new.nr = old->nr;
|
||||||
new.ns = old->ns;
|
new.ns = old->ns;
|
||||||
new.magic = old->magic;
|
new.magic = old->magic;
|
||||||
new.cin = old->cin;
|
|
||||||
new.cout = old->cout;
|
|
||||||
new.pin = old->pin;
|
new.pin = old->pin;
|
||||||
new.pout = old->pout;
|
new.pout = old->pout;
|
||||||
new.total_cin = old->total_cin;
|
new.cin = old->total_cin;
|
||||||
new.total_cout = old->total_cout;
|
new.cout = old->total_cout;
|
||||||
|
new.cin_delta = old->cin;
|
||||||
|
new.cout_delta = old->cout;
|
||||||
new.throttle_in = old->throttle_in;
|
new.throttle_in = old->throttle_in;
|
||||||
new.throttle_out = old->throttle_out;
|
new.throttle_out = old->throttle_out;
|
||||||
new.filter_in = old->filter_in;
|
new.filter_in = old->filter_in;
|
||||||
|
|
@ -1360,6 +1380,7 @@ static int cluster_process_heartbeat(uint8_t *data, int size, int more, uint8_t
|
||||||
config->cluster_seq_number = h->seq;
|
config->cluster_seq_number = h->seq;
|
||||||
|
|
||||||
config->cluster_last_hb = TIME; // Reset to ensure that we don't become master!!
|
config->cluster_last_hb = TIME; // Reset to ensure that we don't become master!!
|
||||||
|
config->cluster_last_hb_ver = hb_ver; // remember what cluster version the master is using
|
||||||
|
|
||||||
if (config->cluster_seq_number != h->seq) { // Out of sequence heartbeat!
|
if (config->cluster_seq_number != h->seq) { // Out of sequence heartbeat!
|
||||||
static int lastseen_seq = 0;
|
static int lastseen_seq = 0;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
// L2TPNS Clustering Stuff
|
// L2TPNS Clustering Stuff
|
||||||
// $Id: cluster.h,v 1.11 2005-05-26 12:17:30 bodea Exp $
|
// $Id: cluster.h,v 1.12 2005-06-02 11:32:30 bodea Exp $
|
||||||
|
|
||||||
#ifndef __CLUSTER_H__
|
#ifndef __CLUSTER_H__
|
||||||
#define __CLUSTER_H__
|
#define __CLUSTER_H__
|
||||||
|
|
@ -57,8 +57,10 @@ typedef struct {
|
||||||
typedef struct { /* Used to update byte counters on the */
|
typedef struct { /* Used to update byte counters on the */
|
||||||
/* master. */
|
/* master. */
|
||||||
uint32_t sid;
|
uint32_t sid;
|
||||||
uint32_t in;
|
uint32_t pin;
|
||||||
uint32_t out;
|
uint32_t pout;
|
||||||
|
uint32_t cin;
|
||||||
|
uint32_t cout;
|
||||||
} bytest;
|
} bytest;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
|
||||||
6
garden.c
6
garden.c
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
/* walled garden */
|
/* walled garden */
|
||||||
|
|
||||||
char const *cvs_id = "$Id: garden.c,v 1.22 2005-05-07 08:17:25 bodea Exp $";
|
char const *cvs_id = "$Id: garden.c,v 1.23 2005-06-02 11:32:30 bodea Exp $";
|
||||||
|
|
||||||
int plugin_api_version = PLUGIN_API_VERSION;
|
int plugin_api_version = PLUGIN_API_VERSION;
|
||||||
static struct pluginfuncs *p = 0;
|
static struct pluginfuncs *p = 0;
|
||||||
|
|
@ -206,8 +206,10 @@ int garden_session(sessiont *s, int flag, char *newuser)
|
||||||
p->sessionkill(other, "Duplicate session when user released from walled garden");
|
p->sessionkill(other, "Duplicate session when user released from walled garden");
|
||||||
}
|
}
|
||||||
/* Clean up counters */
|
/* Clean up counters */
|
||||||
s->cin = s->cout = 0;
|
|
||||||
s->pin = s->pout = 0;
|
s->pin = s->pout = 0;
|
||||||
|
s->cin = s->cout = 0;
|
||||||
|
s->cin_delta = s->cout_delta = 0;
|
||||||
|
s->cin_wrap = s->cout_wrap = 0;
|
||||||
|
|
||||||
snprintf(cmd, sizeof(cmd), "iptables -t nat -D garden_users -s %s -j garden", p->fmtaddr(htonl(s->ip), 0));
|
snprintf(cmd, sizeof(cmd), "iptables -t nat -D garden_users -s %s -j garden", p->fmtaddr(htonl(s->ip), 0));
|
||||||
p->log(3, sess, s->tunnel, "%s\n", cmd);
|
p->log(3, sess, s->tunnel, "%s\n", cmd);
|
||||||
|
|
|
||||||
285
l2tpns.c
285
l2tpns.c
|
|
@ -4,7 +4,7 @@
|
||||||
// Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced
|
// Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced
|
||||||
// vim: sw=8 ts=8
|
// vim: sw=8 ts=8
|
||||||
|
|
||||||
char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.106 2005-06-02 04:04:07 bodea Exp $";
|
char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.107 2005-06-02 11:32:30 bodea Exp $";
|
||||||
|
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
@ -90,7 +90,7 @@ uint32_t eth_tx = 0;
|
||||||
static uint32_t ip_pool_size = 1; // Size of the pool of addresses used for dynamic address allocation.
|
static uint32_t 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.
|
time_t time_now = 0; // Current time in seconds since epoch.
|
||||||
static char time_now_string[64] = {0}; // Current time as a string.
|
static char time_now_string[64] = {0}; // Current time as a string.
|
||||||
static char main_quit = 0; // True if we're in the process of exiting.
|
char main_quit = 0; // True if we're in the process of exiting.
|
||||||
linked_list *loaded_plugins;
|
linked_list *loaded_plugins;
|
||||||
linked_list *plugins[MAX_PLUGIN_TYPES];
|
linked_list *plugins[MAX_PLUGIN_TYPES];
|
||||||
|
|
||||||
|
|
@ -122,7 +122,6 @@ config_descriptt config_values[] = {
|
||||||
CONFIG("accounting_dir", accounting_dir, STRING),
|
CONFIG("accounting_dir", accounting_dir, STRING),
|
||||||
CONFIG("setuid", target_uid, INT),
|
CONFIG("setuid", target_uid, INT),
|
||||||
CONFIG("dump_speed", dump_speed, BOOL),
|
CONFIG("dump_speed", dump_speed, BOOL),
|
||||||
CONFIG("cleanup_interval", cleanup_interval, INT),
|
|
||||||
CONFIG("multi_read_count", multi_read_count, INT),
|
CONFIG("multi_read_count", multi_read_count, INT),
|
||||||
CONFIG("scheduler_fifo", scheduler_fifo, BOOL),
|
CONFIG("scheduler_fifo", scheduler_fifo, BOOL),
|
||||||
CONFIG("lock_pages", lock_pages, BOOL),
|
CONFIG("lock_pages", lock_pages, BOOL),
|
||||||
|
|
@ -191,11 +190,15 @@ static void processcontrol(uint8_t *buf, int len, struct sockaddr_in *addr, int
|
||||||
static tunnelidt new_tunnel(void);
|
static tunnelidt new_tunnel(void);
|
||||||
static void unhide_value(uint8_t *value, size_t len, uint16_t type, uint8_t *vector, size_t vec_len);
|
static void unhide_value(uint8_t *value, size_t len, uint16_t type, uint8_t *vector, size_t vec_len);
|
||||||
|
|
||||||
// return internal time (10ths since process startup)
|
// on slaves, alow BGP to withdraw cleanly before exiting
|
||||||
static clockt now(void)
|
#define QUIT_DELAY 5
|
||||||
|
|
||||||
|
// return internal time (10ths since process startup), set f if given
|
||||||
|
static clockt now(double *f)
|
||||||
{
|
{
|
||||||
struct timeval t;
|
struct timeval t;
|
||||||
gettimeofday(&t, 0);
|
gettimeofday(&t, 0);
|
||||||
|
if (f) *f = t.tv_sec + t.tv_usec / 1000000.0;
|
||||||
return (t.tv_sec - basetime) * 10 + t.tv_usec / 100000 + 1;
|
return (t.tv_sec - basetime) * 10 + t.tv_usec / 100000 + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -205,7 +208,7 @@ static clockt now(void)
|
||||||
clockt backoff(uint8_t try)
|
clockt backoff(uint8_t try)
|
||||||
{
|
{
|
||||||
if (try > 5) try = 5; // max backoff
|
if (try > 5) try = 5; // max backoff
|
||||||
return now() + 10 * (1 << try);
|
return now(NULL) + 10 * (1 << try);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -299,6 +302,16 @@ void _log_hex(int level, const char *title, const char *data, int maxsize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update a counter, accumulating 2^32 wraps
|
||||||
|
void increment_counter(uint32_t *counter, uint32_t *wrap, uint32_t delta)
|
||||||
|
{
|
||||||
|
uint32_t new = *counter + delta;
|
||||||
|
if (new < *counter)
|
||||||
|
(*wrap)++;
|
||||||
|
|
||||||
|
*counter = new;
|
||||||
|
}
|
||||||
|
|
||||||
// initialise the random generator
|
// initialise the random generator
|
||||||
static void initrandom(char *source)
|
static void initrandom(char *source)
|
||||||
{
|
{
|
||||||
|
|
@ -1078,11 +1091,13 @@ static void processipout(uint8_t * buf, int len)
|
||||||
if (sp->snoop_ip && sp->snoop_port)
|
if (sp->snoop_ip && sp->snoop_port)
|
||||||
snoop_send_packet(buf, len, sp->snoop_ip, sp->snoop_port);
|
snoop_send_packet(buf, len, sp->snoop_ip, sp->snoop_port);
|
||||||
|
|
||||||
sp->cout += len; // byte count
|
increment_counter(&sp->cout, &sp->cout_wrap, len); // byte count
|
||||||
sp->total_cout += len; // byte count
|
sp->cout_delta += len;
|
||||||
sp->pout++;
|
sp->pout++;
|
||||||
udp_tx += len;
|
udp_tx += len;
|
||||||
|
|
||||||
sess_local[s].cout += len; // To send to master..
|
sess_local[s].cout += len; // To send to master..
|
||||||
|
sess_local[s].pout++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// process outgoing (to tunnel) IPv6
|
// process outgoing (to tunnel) IPv6
|
||||||
|
|
@ -1187,11 +1202,13 @@ static void processipv6out(uint8_t * buf, int len)
|
||||||
if (sp->snoop_ip && sp->snoop_port)
|
if (sp->snoop_ip && sp->snoop_port)
|
||||||
snoop_send_packet(buf, len, sp->snoop_ip, sp->snoop_port);
|
snoop_send_packet(buf, len, sp->snoop_ip, sp->snoop_port);
|
||||||
|
|
||||||
sp->cout += len; // byte count
|
increment_counter(&sp->cout, &sp->cout_wrap, len); // byte count
|
||||||
sp->total_cout += len; // byte count
|
sp->cout_delta += len;
|
||||||
sp->pout++;
|
sp->pout++;
|
||||||
udp_tx += len;
|
udp_tx += len;
|
||||||
|
|
||||||
sess_local[s].cout += len; // To send to master..
|
sess_local[s].cout += len; // To send to master..
|
||||||
|
sess_local[s].pout++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -1237,11 +1254,13 @@ static void send_ipout(sessionidt s, uint8_t *buf, int len)
|
||||||
if (sp->snoop_ip && sp->snoop_port)
|
if (sp->snoop_ip && sp->snoop_port)
|
||||||
snoop_send_packet(buf, len, sp->snoop_ip, sp->snoop_port);
|
snoop_send_packet(buf, len, sp->snoop_ip, sp->snoop_port);
|
||||||
|
|
||||||
sp->cout += len; // byte count
|
increment_counter(&sp->cout, &sp->cout_wrap, len); // byte count
|
||||||
sp->total_cout += len; // byte count
|
sp->cout_delta += len;
|
||||||
sp->pout++;
|
sp->pout++;
|
||||||
udp_tx += len;
|
udp_tx += len;
|
||||||
|
|
||||||
sess_local[s].cout += len; // To send to master..
|
sess_local[s].cout += len; // To send to master..
|
||||||
|
sess_local[s].pout++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add an AVP (16 bit)
|
// add an AVP (16 bit)
|
||||||
|
|
@ -2552,42 +2571,61 @@ static void processtun(uint8_t * buf, int len)
|
||||||
// Else discard.
|
// Else discard.
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
// Handle retries, timeouts. Runs every 1/10th sec, want to ensure
|
||||||
// Maximum number of actions to complete.
|
// that we look at the whole of the tunnel, radius and session tables
|
||||||
// This is to avoid sending out too many packets
|
// every second
|
||||||
// at once.
|
static void regular_cleanups(double period)
|
||||||
#define MAX_ACTIONS 500
|
|
||||||
|
|
||||||
static int regular_cleanups(void)
|
|
||||||
{
|
{
|
||||||
static sessionidt s = 0; // Next session to check for actions on.
|
// Next tunnel, radius and session to check for actions on.
|
||||||
tunnelidt t;
|
static tunnelidt t = 0;
|
||||||
int count=0,i;
|
static int r = 0;
|
||||||
uint16_t r;
|
static sessionidt s = 0;
|
||||||
static clockt next_acct = 0;
|
|
||||||
static clockt next_shut_acct = 0;
|
int t_actions = 0;
|
||||||
|
int r_actions = 0;
|
||||||
|
int s_actions = 0;
|
||||||
|
|
||||||
|
int t_slice;
|
||||||
|
int r_slice;
|
||||||
|
int s_slice;
|
||||||
|
|
||||||
|
int i;
|
||||||
int a;
|
int a;
|
||||||
|
|
||||||
LOG(3, 0, 0, "Begin regular cleanup\n");
|
// divide up tables into slices based on the last run
|
||||||
|
t_slice = config->cluster_highest_tunnelid * period;
|
||||||
|
r_slice = (MAXRADIUS - 1) * period;
|
||||||
|
s_slice = config->cluster_highest_sessionid * period;
|
||||||
|
|
||||||
for (r = 1; r < MAXRADIUS; r++)
|
if (t_slice < 1)
|
||||||
{
|
t_slice = 1;
|
||||||
if (!radius[r].state)
|
else if (t_slice > config->cluster_highest_tunnelid)
|
||||||
continue;
|
t_slice = config->cluster_highest_tunnelid;
|
||||||
if (radius[r].retry)
|
|
||||||
{
|
if (r_slice < 1)
|
||||||
if (radius[r].retry <= TIME)
|
r_slice = 1;
|
||||||
radiusretry(r);
|
else if (r_slice > (MAXRADIUS - 1))
|
||||||
} else
|
r_slice = MAXRADIUS - 1;
|
||||||
radius[r].retry = backoff(radius[r].try+1); // Is this really needed? --mo
|
|
||||||
}
|
if (s_slice < 1)
|
||||||
for (t = 1; t <= config->cluster_highest_tunnelid; t++)
|
s_slice = 1;
|
||||||
|
else if (s_slice > config->cluster_highest_sessionid)
|
||||||
|
s_slice = config->cluster_highest_sessionid;
|
||||||
|
|
||||||
|
LOG(4, 0, 0, "Begin regular cleanup (last %f seconds ago)\n", period);
|
||||||
|
|
||||||
|
for (i = 0; i < t_slice; i++)
|
||||||
{
|
{
|
||||||
|
t++;
|
||||||
|
if (t > config->cluster_highest_tunnelid)
|
||||||
|
t = 1;
|
||||||
|
|
||||||
// check for expired tunnels
|
// check for expired tunnels
|
||||||
if (tunnel[t].die && tunnel[t].die <= TIME)
|
if (tunnel[t].die && tunnel[t].die <= TIME)
|
||||||
{
|
{
|
||||||
STAT(tunnel_timeout);
|
STAT(tunnel_timeout);
|
||||||
tunnelkill(t, "Expired");
|
tunnelkill(t, "Expired");
|
||||||
|
t_actions++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// check for message resend
|
// check for message resend
|
||||||
|
|
@ -2607,6 +2645,8 @@ static int regular_cleanups(void)
|
||||||
tunnelsend(c->buf, c->length, t);
|
tunnelsend(c->buf, c->length, t);
|
||||||
c = c->next;
|
c = c->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
t_actions++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Send hello
|
// Send hello
|
||||||
|
|
@ -2615,6 +2655,7 @@ static int regular_cleanups(void)
|
||||||
controlt *c = controlnew(6); // sending HELLO
|
controlt *c = controlnew(6); // sending HELLO
|
||||||
controladd(c, t, 0); // send the message
|
controladd(c, t, 0); // send the message
|
||||||
LOG(3, 0, t, "Sending HELLO message\n");
|
LOG(3, 0, t, "Sending HELLO message\n");
|
||||||
|
t_actions++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for tunnel changes requested from the CLI
|
// Check for tunnel changes requested from the CLI
|
||||||
|
|
@ -2625,13 +2666,28 @@ static int regular_cleanups(void)
|
||||||
{
|
{
|
||||||
LOG(2, 0, t, "Dropping tunnel by CLI\n");
|
LOG(2, 0, t, "Dropping tunnel by CLI\n");
|
||||||
tunnelshutdown(t, "Requested by administrator", 1, 0, 0);
|
tunnelshutdown(t, "Requested by administrator", 1, 0, 0);
|
||||||
|
t_actions++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
count = 0;
|
for (i = 0; i < r_slice; i++)
|
||||||
for (i = 1; i <= config->cluster_highest_sessionid; i++)
|
{
|
||||||
|
r++;
|
||||||
|
if (r >= MAXRADIUS)
|
||||||
|
r = 1;
|
||||||
|
|
||||||
|
if (!radius[r].state)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (radius[r].retry <= TIME)
|
||||||
|
{
|
||||||
|
radiusretry(r);
|
||||||
|
r_actions++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < s_slice; i++)
|
||||||
{
|
{
|
||||||
s++;
|
s++;
|
||||||
if (s > config->cluster_highest_sessionid)
|
if (s > config->cluster_highest_sessionid)
|
||||||
|
|
@ -2646,7 +2702,7 @@ static int regular_cleanups(void)
|
||||||
if (session[s].die <= TIME)
|
if (session[s].die <= TIME)
|
||||||
{
|
{
|
||||||
sessionkill(s, "Expired");
|
sessionkill(s, "Expired");
|
||||||
if (++count >= MAX_ACTIONS) break;
|
s_actions++;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -2656,6 +2712,7 @@ static int regular_cleanups(void)
|
||||||
// IPCP has not completed yet. Resend
|
// IPCP has not completed yet. Resend
|
||||||
LOG(3, s, session[s].tunnel, "No ACK for initial IPCP ConfigReq... resending\n");
|
LOG(3, s, session[s].tunnel, "No ACK for initial IPCP ConfigReq... resending\n");
|
||||||
sendipcp(session[s].tunnel, s);
|
sendipcp(session[s].tunnel, s);
|
||||||
|
s_actions++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drop sessions who have not responded within IDLE_TIMEOUT seconds
|
// Drop sessions who have not responded within IDLE_TIMEOUT seconds
|
||||||
|
|
@ -2663,7 +2720,7 @@ static int regular_cleanups(void)
|
||||||
{
|
{
|
||||||
sessionshutdown(s, "No response to LCP ECHO requests.", 3, 0);
|
sessionshutdown(s, "No response to LCP ECHO requests.", 3, 0);
|
||||||
STAT(session_timeout);
|
STAT(session_timeout);
|
||||||
if (++count >= MAX_ACTIONS) break;
|
s_actions++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2683,7 +2740,7 @@ static int regular_cleanups(void)
|
||||||
LOG(4, s, session[s].tunnel, "No data in %d seconds, sending LCP ECHO\n",
|
LOG(4, s, session[s].tunnel, "No data in %d seconds, sending LCP ECHO\n",
|
||||||
(int)(time_now - session[s].last_packet));
|
(int)(time_now - session[s].last_packet));
|
||||||
tunnelsend(b, 24, session[s].tunnel); // send it
|
tunnelsend(b, 24, session[s].tunnel); // send it
|
||||||
if (++count >= MAX_ACTIONS) break;
|
s_actions++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for actions requested from the CLI
|
// Check for actions requested from the CLI
|
||||||
|
|
@ -2697,6 +2754,7 @@ static int regular_cleanups(void)
|
||||||
LOG(2, s, session[s].tunnel, "Dropping session by CLI\n");
|
LOG(2, s, session[s].tunnel, "Dropping session by CLI\n");
|
||||||
sessionshutdown(s, "Requested by administrator.", 3, 0);
|
sessionshutdown(s, "Requested by administrator.", 3, 0);
|
||||||
a = 0; // dead, no need to check for other actions
|
a = 0; // dead, no need to check for other actions
|
||||||
|
s_actions++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a & CLI_SESS_NOSNOOP)
|
if (a & CLI_SESS_NOSNOOP)
|
||||||
|
|
@ -2704,6 +2762,7 @@ static int regular_cleanups(void)
|
||||||
LOG(2, s, session[s].tunnel, "Unsnooping session by CLI\n");
|
LOG(2, s, session[s].tunnel, "Unsnooping session by CLI\n");
|
||||||
session[s].snoop_ip = 0;
|
session[s].snoop_ip = 0;
|
||||||
session[s].snoop_port = 0;
|
session[s].snoop_port = 0;
|
||||||
|
s_actions++;
|
||||||
send++;
|
send++;
|
||||||
}
|
}
|
||||||
else if (a & CLI_SESS_SNOOP)
|
else if (a & CLI_SESS_SNOOP)
|
||||||
|
|
@ -2714,6 +2773,7 @@ static int regular_cleanups(void)
|
||||||
|
|
||||||
session[s].snoop_ip = cli_session_actions[s].snoop_ip;
|
session[s].snoop_ip = cli_session_actions[s].snoop_ip;
|
||||||
session[s].snoop_port = cli_session_actions[s].snoop_port;
|
session[s].snoop_port = cli_session_actions[s].snoop_port;
|
||||||
|
s_actions++;
|
||||||
send++;
|
send++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2721,6 +2781,7 @@ static int regular_cleanups(void)
|
||||||
{
|
{
|
||||||
LOG(2, s, session[s].tunnel, "Un-throttling session by CLI\n");
|
LOG(2, s, session[s].tunnel, "Un-throttling session by CLI\n");
|
||||||
throttle_session(s, 0, 0);
|
throttle_session(s, 0, 0);
|
||||||
|
s_actions++;
|
||||||
send++;
|
send++;
|
||||||
}
|
}
|
||||||
else if (a & CLI_SESS_THROTTLE)
|
else if (a & CLI_SESS_THROTTLE)
|
||||||
|
|
@ -2730,6 +2791,7 @@ static int regular_cleanups(void)
|
||||||
cli_session_actions[s].throttle_out);
|
cli_session_actions[s].throttle_out);
|
||||||
|
|
||||||
throttle_session(s, cli_session_actions[s].throttle_in, cli_session_actions[s].throttle_out);
|
throttle_session(s, cli_session_actions[s].throttle_in, cli_session_actions[s].throttle_out);
|
||||||
|
s_actions++;
|
||||||
send++;
|
send++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2737,6 +2799,7 @@ static int regular_cleanups(void)
|
||||||
{
|
{
|
||||||
LOG(2, s, session[s].tunnel, "Un-filtering session by CLI\n");
|
LOG(2, s, session[s].tunnel, "Un-filtering session by CLI\n");
|
||||||
filter_session(s, 0, 0);
|
filter_session(s, 0, 0);
|
||||||
|
s_actions++;
|
||||||
send++;
|
send++;
|
||||||
}
|
}
|
||||||
else if (a & CLI_SESS_FILTER)
|
else if (a & CLI_SESS_FILTER)
|
||||||
|
|
@ -2746,13 +2809,12 @@ static int regular_cleanups(void)
|
||||||
cli_session_actions[s].filter_out);
|
cli_session_actions[s].filter_out);
|
||||||
|
|
||||||
filter_session(s, cli_session_actions[s].filter_in, cli_session_actions[s].filter_out);
|
filter_session(s, cli_session_actions[s].filter_in, cli_session_actions[s].filter_out);
|
||||||
|
s_actions++;
|
||||||
send++;
|
send++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (send)
|
if (send)
|
||||||
cluster_send_session(s);
|
cluster_send_session(s);
|
||||||
|
|
||||||
if (++count >= MAX_ACTIONS) break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RADIUS interim accounting
|
// RADIUS interim accounting
|
||||||
|
|
@ -2773,38 +2835,14 @@ static int regular_cleanups(void)
|
||||||
|
|
||||||
radiussend(r, RADIUSINTERIM);
|
radiussend(r, RADIUSINTERIM);
|
||||||
sess_local[s].last_interim = time_now;
|
sess_local[s].last_interim = time_now;
|
||||||
|
s_actions++;
|
||||||
if (++count >= MAX_ACTIONS)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*config->accounting_dir)
|
LOG(4, 0, 0, "End regular cleanup: checked %d/%d/%d tunnels/radius/sessions; %d/%d/%d actions\n",
|
||||||
{
|
t_slice, r_slice, s_slice, t_actions, r_actions, s_actions);
|
||||||
if (next_acct <= TIME)
|
|
||||||
{
|
|
||||||
// Dump accounting data
|
|
||||||
next_acct = TIME + ACCT_TIME;
|
|
||||||
next_shut_acct = TIME + ACCT_SHUT_TIME;
|
|
||||||
dump_acct_info(1);
|
|
||||||
}
|
|
||||||
else if (next_shut_acct <= TIME)
|
|
||||||
{
|
|
||||||
// Dump accounting data for shutdown sessions
|
|
||||||
next_shut_acct = TIME + ACCT_SHUT_TIME;
|
|
||||||
if (shut_acct_n)
|
|
||||||
dump_acct_info(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count >= MAX_ACTIONS)
|
|
||||||
return 1; // Didn't finish!
|
|
||||||
|
|
||||||
LOG(3, 0, 0, "End regular cleanup (%d actions), next in %d seconds\n", count, config->cleanup_interval);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Are we in the middle of a tunnel update, or radius
|
// Are we in the middle of a tunnel update, or radius
|
||||||
// requests??
|
// requests??
|
||||||
|
|
@ -2812,8 +2850,39 @@ static int regular_cleanups(void)
|
||||||
static int still_busy(void)
|
static int still_busy(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
static time_t stopped_bgp = 0;
|
||||||
static clockt last_talked = 0;
|
static clockt last_talked = 0;
|
||||||
static clockt start_busy_wait = 0;
|
static clockt start_busy_wait = 0;
|
||||||
|
|
||||||
|
if (!config->cluster_iam_master)
|
||||||
|
{
|
||||||
|
#ifdef BGP
|
||||||
|
if (bgp_configured)
|
||||||
|
{
|
||||||
|
if (!stopped_bgp)
|
||||||
|
{
|
||||||
|
LOG(1, 0, 0, "Shutting down in %d seconds, stopping BGP...\n", QUIT_DELAY);
|
||||||
|
|
||||||
|
for (i = 0; i < BGP_NUM_PEERS; i++)
|
||||||
|
if (bgp_peers[i].state == Established)
|
||||||
|
bgp_stop(&bgp_peers[i]);
|
||||||
|
|
||||||
|
stopped_bgp = time_now;
|
||||||
|
|
||||||
|
// we don't want to become master
|
||||||
|
cluster_send_ping(0);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (time_now < (stopped_bgp + QUIT_DELAY))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif /* BGP */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (start_busy_wait == 0)
|
if (start_busy_wait == 0)
|
||||||
start_busy_wait = TIME;
|
start_busy_wait = TIME;
|
||||||
|
|
||||||
|
|
@ -2865,7 +2934,6 @@ static void mainloop(void)
|
||||||
uint8_t buf[65536];
|
uint8_t buf[65536];
|
||||||
struct timeval to;
|
struct timeval to;
|
||||||
clockt next_cluster_ping = 0; // send initial ping immediately
|
clockt next_cluster_ping = 0; // send initial ping immediately
|
||||||
time_t next_clean = time_now + config->cleanup_interval;
|
|
||||||
|
|
||||||
LOG(4, 0, 0, "Beginning of main loop. udpfd=%d, tunfd=%d, cluster_sockfd=%d, controlfd=%d\n",
|
LOG(4, 0, 0, "Beginning of main loop. udpfd=%d, tunfd=%d, cluster_sockfd=%d, controlfd=%d\n",
|
||||||
udpfd, tunfd, cluster_sockfd, controlfd);
|
udpfd, tunfd, cluster_sockfd, controlfd);
|
||||||
|
|
@ -2890,6 +2958,7 @@ static void mainloop(void)
|
||||||
fd_set w;
|
fd_set w;
|
||||||
int bgp_set[BGP_NUM_PEERS];
|
int bgp_set[BGP_NUM_PEERS];
|
||||||
#endif /* BGP */
|
#endif /* BGP */
|
||||||
|
int more = 0;
|
||||||
|
|
||||||
if (config->reload_config)
|
if (config->reload_config)
|
||||||
{
|
{
|
||||||
|
|
@ -2928,7 +2997,7 @@ static void mainloop(void)
|
||||||
|
|
||||||
STAT(select_called);
|
STAT(select_called);
|
||||||
|
|
||||||
TIME = now();
|
TIME = now(NULL);
|
||||||
if (n < 0)
|
if (n < 0)
|
||||||
{
|
{
|
||||||
if (errno == EINTR ||
|
if (errno == EINTR ||
|
||||||
|
|
@ -3055,6 +3124,7 @@ static void mainloop(void)
|
||||||
config->multi_read_count, udp_pkts, tun_pkts, cluster_pkts);
|
config->multi_read_count, udp_pkts, tun_pkts, cluster_pkts);
|
||||||
|
|
||||||
STAT(multi_read_exceeded);
|
STAT(multi_read_exceeded);
|
||||||
|
more++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3077,9 +3147,11 @@ static void mainloop(void)
|
||||||
next_cluster_ping = TIME + config->cluster_hb_interval;
|
next_cluster_ping = TIME + config->cluster_hb_interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!config->cluster_iam_master)
|
||||||
|
continue;
|
||||||
|
|
||||||
// Run token bucket filtering queue..
|
// Run token bucket filtering queue..
|
||||||
// Only run it every 1/10th of a second.
|
// Only run it every 1/10th of a second.
|
||||||
// Runs on all machines both master and slave.
|
|
||||||
{
|
{
|
||||||
static clockt last_run = 0;
|
static clockt last_run = 0;
|
||||||
if (last_run != TIME)
|
if (last_run != TIME)
|
||||||
|
|
@ -3089,20 +3161,42 @@ static void mainloop(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle timeouts. Make sure that this gets run anyway, even if there was
|
// Handle timeouts, retries etc.
|
||||||
* something to read, else under load this will never actually run....
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
if (config->cluster_iam_master && next_clean <= time_now)
|
|
||||||
{
|
{
|
||||||
if (regular_cleanups())
|
static double last_clean = 0;
|
||||||
|
double this_clean;
|
||||||
|
double diff;
|
||||||
|
|
||||||
|
TIME = now(&this_clean);
|
||||||
|
diff = this_clean - last_clean;
|
||||||
|
|
||||||
|
// Run during idle time (after we've handled
|
||||||
|
// all incoming packets) or every 1/10th sec
|
||||||
|
if (!more || diff > 0.1)
|
||||||
{
|
{
|
||||||
// Did it finish?
|
regular_cleanups(diff);
|
||||||
next_clean = time_now + 1 ; // Didn't finish. Check quickly.
|
last_clean = this_clean;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
if (*config->accounting_dir)
|
||||||
|
{
|
||||||
|
static clockt next_acct = 0;
|
||||||
|
static clockt next_shut_acct = 0;
|
||||||
|
|
||||||
|
if (next_acct <= TIME)
|
||||||
{
|
{
|
||||||
next_clean = time_now + config->cleanup_interval; // Did. Move to next interval.
|
// Dump accounting data
|
||||||
|
next_acct = TIME + ACCT_TIME;
|
||||||
|
next_shut_acct = TIME + ACCT_SHUT_TIME;
|
||||||
|
dump_acct_info(1);
|
||||||
|
}
|
||||||
|
else if (next_shut_acct <= TIME)
|
||||||
|
{
|
||||||
|
// Dump accounting data for shutdown sessions
|
||||||
|
next_shut_acct = TIME + ACCT_SHUT_TIME;
|
||||||
|
if (shut_acct_n)
|
||||||
|
dump_acct_info(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3117,6 +3211,7 @@ static void mainloop(void)
|
||||||
|
|
||||||
//
|
//
|
||||||
// Important!!! We MUST not process any packets past this point!
|
// Important!!! We MUST not process any packets past this point!
|
||||||
|
LOG(1, 0, 0, "Clean shutdown complete\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void stripdomain(char *host)
|
static void stripdomain(char *host)
|
||||||
|
|
@ -3591,7 +3686,7 @@ void snoop_send_packet(char *packet, uint16_t size, in_addr_t destination, uint1
|
||||||
|
|
||||||
static int dump_session(FILE **f, sessiont *s)
|
static int dump_session(FILE **f, sessiont *s)
|
||||||
{
|
{
|
||||||
if (!s->opened || !s->ip || !(s->cin || s->cout) || !*s->user || s->walled_garden)
|
if (!s->opened || !s->ip || !(s->cin_delta || s->cout_delta) || !*s->user || s->walled_garden)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (!*f)
|
if (!*f)
|
||||||
|
|
@ -3625,11 +3720,10 @@ static int dump_session(FILE **f, sessiont *s)
|
||||||
s->user, // username
|
s->user, // username
|
||||||
fmtaddr(htonl(s->ip), 0), // ip
|
fmtaddr(htonl(s->ip), 0), // ip
|
||||||
(s->throttle_in || s->throttle_out) ? 2 : 1, // qos
|
(s->throttle_in || s->throttle_out) ? 2 : 1, // qos
|
||||||
(uint32_t) s->cin, // uptxoctets
|
(uint32_t) s->cin_delta, // uptxoctets
|
||||||
(uint32_t) s->cout); // downrxoctets
|
(uint32_t) s->cout_delta); // downrxoctets
|
||||||
|
|
||||||
s->pin = s->cin = 0;
|
s->cin_delta = s->cout_delta = 0;
|
||||||
s->pout = s->cout = 0;
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -3800,14 +3894,6 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
mainloop();
|
mainloop();
|
||||||
|
|
||||||
#ifdef BGP
|
|
||||||
/* try to shut BGP down cleanly; with luck the sockets will be
|
|
||||||
writable since we're out of the select */
|
|
||||||
for (i = 0; i < BGP_NUM_PEERS; i++)
|
|
||||||
if (bgp_peers[i].state == Established)
|
|
||||||
bgp_stop(&bgp_peers[i]);
|
|
||||||
#endif /* BGP */
|
|
||||||
|
|
||||||
/* remove plugins (so cleanup code gets run) */
|
/* remove plugins (so cleanup code gets run) */
|
||||||
plugins_done();
|
plugins_done();
|
||||||
|
|
||||||
|
|
@ -4084,7 +4170,6 @@ static void update_config()
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(config->old_plugins, config->plugins, sizeof(config->plugins));
|
memcpy(config->old_plugins, config->plugins, sizeof(config->plugins));
|
||||||
if (!config->cleanup_interval) config->cleanup_interval = 10;
|
|
||||||
if (!config->multi_read_count) config->multi_read_count = 10;
|
if (!config->multi_read_count) config->multi_read_count = 10;
|
||||||
if (!config->cluster_address) config->cluster_address = inet_addr(DEFAULT_MCAST_ADDR);
|
if (!config->cluster_address) config->cluster_address = inet_addr(DEFAULT_MCAST_ADDR);
|
||||||
if (!*config->cluster_interface)
|
if (!*config->cluster_interface)
|
||||||
|
|
|
||||||
18
l2tpns.h
18
l2tpns.h
|
|
@ -1,5 +1,5 @@
|
||||||
// L2TPNS Global Stuff
|
// L2TPNS Global Stuff
|
||||||
// $Id: l2tpns.h,v 1.74 2005-06-02 04:04:07 bodea Exp $
|
// $Id: l2tpns.h,v 1.75 2005-06-02 11:32:31 bodea Exp $
|
||||||
|
|
||||||
#ifndef __L2TPNS_H__
|
#ifndef __L2TPNS_H__
|
||||||
#define __L2TPNS_H__
|
#define __L2TPNS_H__
|
||||||
|
|
@ -173,10 +173,10 @@ typedef struct
|
||||||
uint16_t nr; // next receive
|
uint16_t nr; // next receive
|
||||||
uint16_t ns; // next send
|
uint16_t ns; // next send
|
||||||
uint32_t magic; // ppp magic number
|
uint32_t magic; // ppp magic number
|
||||||
uint32_t cin, cout; // byte counts
|
|
||||||
uint32_t pin, pout; // packet counts
|
uint32_t pin, pout; // packet counts
|
||||||
uint32_t total_cin; // This counter is never reset while a session is open
|
uint32_t cin, cout; // byte counts
|
||||||
uint32_t total_cout; // This counter is never reset while a session is open
|
uint32_t cin_wrap, cout_wrap; // byte counter wrap count (RADIUS accounting giagawords)
|
||||||
|
uint32_t cin_delta, cout_delta; // byte count changes (for dump_session())
|
||||||
uint16_t throttle_in; // upstream throttle rate (kbps)
|
uint16_t throttle_in; // upstream throttle rate (kbps)
|
||||||
uint16_t throttle_out; // downstream throttle rate
|
uint16_t throttle_out; // downstream throttle rate
|
||||||
uint8_t filter_in; // input filter index (to ip_filters[N-1]; 0 if none)
|
uint8_t filter_in; // input filter index (to ip_filters[N-1]; 0 if none)
|
||||||
|
|
@ -201,7 +201,7 @@ typedef struct
|
||||||
uint8_t walled_garden; // is this session gardened?
|
uint8_t walled_garden; // is this session gardened?
|
||||||
uint8_t ipv6prefixlen; // IPv6 route prefix length
|
uint8_t ipv6prefixlen; // IPv6 route prefix length
|
||||||
struct in6_addr ipv6route; // Static IPv6 route
|
struct in6_addr ipv6route; // Static IPv6 route
|
||||||
char reserved[24]; // Space to expand structure without changing HB_VERSION
|
char reserved[16]; // Space to expand structure without changing HB_VERSION
|
||||||
}
|
}
|
||||||
sessiont;
|
sessiont;
|
||||||
|
|
||||||
|
|
@ -217,6 +217,10 @@ sessiont;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
// packet counters
|
||||||
|
uint32_t pin;
|
||||||
|
uint32_t pout;
|
||||||
|
|
||||||
// byte counters
|
// byte counters
|
||||||
uint32_t cin;
|
uint32_t cin;
|
||||||
uint32_t cout;
|
uint32_t cout;
|
||||||
|
|
@ -437,7 +441,6 @@ typedef struct
|
||||||
|
|
||||||
char config_file[128];
|
char config_file[128];
|
||||||
int reload_config; // flag to re-read config (set by cli)
|
int reload_config; // flag to re-read config (set by cli)
|
||||||
int cleanup_interval; // interval between regular cleanups (in seconds)
|
|
||||||
int multi_read_count; // amount of packets to read per fd in processing loop
|
int multi_read_count; // amount of packets to read per fd in processing loop
|
||||||
|
|
||||||
char tundevice[10]; // tun device name
|
char tundevice[10]; // tun device name
|
||||||
|
|
@ -496,6 +499,7 @@ typedef struct
|
||||||
int cluster_highest_sessionid;
|
int cluster_highest_sessionid;
|
||||||
int cluster_highest_tunnelid;
|
int cluster_highest_tunnelid;
|
||||||
clockt cluster_last_hb; // Last time we saw a heartbeat from the master.
|
clockt cluster_last_hb; // Last time we saw a heartbeat from the master.
|
||||||
|
int cluster_last_hb_ver; // Heartbeat version last seen from master
|
||||||
int cluster_num_changes; // Number of changes queued.
|
int cluster_num_changes; // Number of changes queued.
|
||||||
|
|
||||||
int cluster_hb_interval; // How often to send a heartbeat.
|
int cluster_hb_interval; // How often to send a heartbeat.
|
||||||
|
|
@ -616,6 +620,7 @@ void route6set(sessionidt s, struct in6_addr ip, int prefixlen, int add);
|
||||||
sessionidt sessionbyip(in_addr_t ip);
|
sessionidt sessionbyip(in_addr_t ip);
|
||||||
sessionidt sessionbyipv6(struct in6_addr ip);
|
sessionidt sessionbyipv6(struct in6_addr ip);
|
||||||
sessionidt sessionbyuser(char *username);
|
sessionidt sessionbyuser(char *username);
|
||||||
|
void increment_counter(uint32_t *counter, uint32_t *wrap, uint32_t delta);
|
||||||
void random_data(uint8_t *buf, int len);
|
void random_data(uint8_t *buf, int len);
|
||||||
void sessionkill(sessionidt s, char *reason);
|
void sessionkill(sessionidt s, char *reason);
|
||||||
void sessionshutdown(sessionidt s, char *reason, int result, int error);
|
void sessionshutdown(sessionidt s, char *reason, int result, int error);
|
||||||
|
|
@ -681,6 +686,7 @@ if (count++ < max) { \
|
||||||
extern configt *config;
|
extern configt *config;
|
||||||
extern time_t basetime; // Time when this process started.
|
extern time_t basetime; // Time when this process started.
|
||||||
extern time_t time_now; // Seconds since EPOCH.
|
extern time_t time_now; // Seconds since EPOCH.
|
||||||
|
extern char main_quit;
|
||||||
extern uint32_t last_id;
|
extern uint32_t last_id;
|
||||||
extern struct Tstats *_statistics;
|
extern struct Tstats *_statistics;
|
||||||
extern in_addr_t my_address;
|
extern in_addr_t my_address;
|
||||||
|
|
|
||||||
57
ppp.c
57
ppp.c
|
|
@ -1,6 +1,6 @@
|
||||||
// L2TPNS PPP Stuff
|
// L2TPNS PPP Stuff
|
||||||
|
|
||||||
char const *cvs_id_ppp = "$Id: ppp.c,v 1.61 2005-05-13 09:23:00 bodea Exp $";
|
char const *cvs_id_ppp = "$Id: ppp.c,v 1.62 2005-06-02 11:32:31 bodea Exp $";
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
@ -1015,21 +1015,26 @@ void processipin(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p += 4;
|
||||||
|
l -= 4;
|
||||||
|
|
||||||
if (session[s].snoop_ip && session[s].snoop_port)
|
if (session[s].snoop_ip && session[s].snoop_port)
|
||||||
{
|
{
|
||||||
// Snooping this session
|
// Snooping this session
|
||||||
snoop_send_packet(p + 4, l - 4, session[s].snoop_ip, session[s].snoop_port);
|
snoop_send_packet(p, l, session[s].snoop_ip, session[s].snoop_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
session[s].cin += l - 4;
|
increment_counter(&session[s].cin, &session[s].cin_wrap, l);
|
||||||
session[s].total_cin += l - 4;
|
session[s].cin_delta += l;
|
||||||
sess_local[s].cin += l - 4;
|
|
||||||
|
|
||||||
session[s].pin++;
|
session[s].pin++;
|
||||||
eth_tx += l - 4;
|
|
||||||
|
sess_local[s].cin += l;
|
||||||
|
sess_local[s].pin++;
|
||||||
|
|
||||||
|
eth_tx += l;
|
||||||
|
|
||||||
STAT(tun_tx_packets);
|
STAT(tun_tx_packets);
|
||||||
INC_STAT(tun_tx_bytes, l - 4);
|
INC_STAT(tun_tx_bytes, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
// process IPv6 packet received
|
// process IPv6 packet received
|
||||||
|
|
@ -1103,21 +1108,26 @@ void processipv6in(tunnelidt t, sessionidt s, uint8_t *p, uint16_t l)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p += 4;
|
||||||
|
l -= 4;
|
||||||
|
|
||||||
if (session[s].snoop_ip && session[s].snoop_port)
|
if (session[s].snoop_ip && session[s].snoop_port)
|
||||||
{
|
{
|
||||||
// Snooping this session
|
// Snooping this session
|
||||||
snoop_send_packet(p + 4, l - 4, session[s].snoop_ip, session[s].snoop_port);
|
snoop_send_packet(p, l, session[s].snoop_ip, session[s].snoop_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
session[s].cin += l - 4;
|
increment_counter(&session[s].cin, &session[s].cin_wrap, l);
|
||||||
session[s].total_cin += l - 4;
|
session[s].cin_delta += l;
|
||||||
sess_local[s].cin += l - 4;
|
|
||||||
|
|
||||||
session[s].pin++;
|
session[s].pin++;
|
||||||
eth_tx += l - 4;
|
|
||||||
|
sess_local[s].cin += l;
|
||||||
|
sess_local[s].pin++;
|
||||||
|
|
||||||
|
eth_tx += l;
|
||||||
|
|
||||||
STAT(tun_tx_packets);
|
STAT(tun_tx_packets);
|
||||||
INC_STAT(tun_tx_bytes, l - 4);
|
INC_STAT(tun_tx_bytes, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
@ -1137,19 +1147,24 @@ void send_ipin(sessionidt s, uint8_t *buf, int len)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
buf += 4;
|
||||||
|
len -= 4;
|
||||||
|
|
||||||
if (session[s].snoop_ip && session[s].snoop_port)
|
if (session[s].snoop_ip && session[s].snoop_port)
|
||||||
{
|
{
|
||||||
// Snooping this session
|
// Snooping this session
|
||||||
snoop_send_packet(buf + 4, len - 4, session[s].snoop_ip, session[s].snoop_port);
|
snoop_send_packet(buf, len, session[s].snoop_ip, session[s].snoop_port);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Increment packet counters
|
// Increment packet counters
|
||||||
session[s].cin += len - 4;
|
increment_counter(&session[s].cin, &session[s].cin_wrap, len);
|
||||||
session[s].total_cin += len - 4;
|
session[s].cin_delta += len;
|
||||||
sess_local[s].cin += len - 4;
|
|
||||||
|
|
||||||
session[s].pin++;
|
session[s].pin++;
|
||||||
eth_tx += len - 4;
|
|
||||||
|
sess_local[s].cin += len;
|
||||||
|
sess_local[s].pin++;
|
||||||
|
|
||||||
|
eth_tx += len;
|
||||||
|
|
||||||
STAT(tun_tx_packets);
|
STAT(tun_tx_packets);
|
||||||
INC_STAT(tun_tx_bytes, len - 4);
|
INC_STAT(tun_tx_bytes, len - 4);
|
||||||
|
|
|
||||||
49
radius.c
49
radius.c
|
|
@ -1,6 +1,6 @@
|
||||||
// L2TPNS Radius Stuff
|
// L2TPNS Radius Stuff
|
||||||
|
|
||||||
char const *cvs_id_radius = "$Id: radius.c,v 1.31 2005-05-16 04:51:16 bodea Exp $";
|
char const *cvs_id_radius = "$Id: radius.c,v 1.32 2005-06-02 11:32:32 bodea Exp $";
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
@ -132,7 +132,7 @@ void radiussend(uint16_t r, uint8_t state)
|
||||||
radius[r].try = 0;
|
radius[r].try = 0;
|
||||||
|
|
||||||
radius[r].state = state;
|
radius[r].state = state;
|
||||||
radius[r].retry = backoff(radius[r].try++);
|
radius[r].retry = backoff(radius[r].try++) + 20; // 3s, 4s, 6s, 10s...
|
||||||
LOG(4, s, session[s].tunnel, "Send RADIUS id %d sock %d state %s try %d\n",
|
LOG(4, s, session[s].tunnel, "Send RADIUS id %d sock %d state %s try %d\n",
|
||||||
r >> RADIUS_SHIFT, r & RADIUS_MASK,
|
r >> RADIUS_SHIFT, r & RADIUS_MASK,
|
||||||
radius_state(radius[r].state), radius[r].try);
|
radius_state(radius[r].state), radius[r].try);
|
||||||
|
|
@ -233,47 +233,63 @@ void radiussend(uint16_t r, uint8_t state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (state == RADIUSSTART || state == RADIUSSTOP || state == RADIUSINTERIM)
|
else if (state == RADIUSSTART || state == RADIUSSTOP || state == RADIUSINTERIM)
|
||||||
{ // accounting
|
{ // accounting
|
||||||
*p = 40; // accounting type
|
*p = 40; // accounting type
|
||||||
p[1] = 6;
|
p[1] = 6;
|
||||||
*(uint32_t *) (p + 2) = htonl(state - RADIUSSTART + 1); // start=1, stop=2, interim=3
|
*(uint32_t *) (p + 2) = htonl(state - RADIUSSTART + 1); // start=1, stop=2, interim=3
|
||||||
p += p[1];
|
p += p[1];
|
||||||
if (s)
|
if (s)
|
||||||
{
|
{
|
||||||
*p = 44; // session ID
|
*p = 44; // session ID
|
||||||
p[1] = 18;
|
p[1] = 18;
|
||||||
sprintf(p + 2, "%08X%08X", session[s].unique_id, session[s].opened);
|
sprintf(p + 2, "%08X%08X", session[s].unique_id, session[s].opened);
|
||||||
p += p[1];
|
p += p[1];
|
||||||
if (state == RADIUSSTART)
|
if (state == RADIUSSTART)
|
||||||
{ // start
|
{ // start
|
||||||
*p = 41; // delay
|
*p = 41; // delay
|
||||||
p[1] = 6;
|
p[1] = 6;
|
||||||
*(uint32_t *) (p + 2) = htonl(time(NULL) - session[s].opened);
|
*(uint32_t *) (p + 2) = htonl(time(NULL) - session[s].opened);
|
||||||
p += p[1];
|
p += p[1];
|
||||||
sess_local[s].last_interim = time_now; // Setup "first" Interim
|
sess_local[s].last_interim = time_now; // Setup "first" Interim
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // stop, interim
|
{ // stop, interim
|
||||||
*p = 42; // input octets
|
*p = 42; // input octets
|
||||||
p[1] = 6;
|
p[1] = 6;
|
||||||
*(uint32_t *) (p + 2) = htonl(session[s].cin);
|
*(uint32_t *) (p + 2) = htonl(session[s].cin);
|
||||||
p += p[1];
|
p += p[1];
|
||||||
*p = 43; // output octets
|
|
||||||
|
*p = 43; // output octets
|
||||||
p[1] = 6;
|
p[1] = 6;
|
||||||
*(uint32_t *) (p + 2) = htonl(session[s].cout);
|
*(uint32_t *) (p + 2) = htonl(session[s].cout);
|
||||||
p += p[1];
|
p += p[1];
|
||||||
*p = 46; // session time
|
if (state == RADIUSSTOP)
|
||||||
p[1] = 6;
|
{
|
||||||
*(uint32_t *) (p + 2) = htonl(time(NULL) - session[s].opened);
|
*p = 46; // session time
|
||||||
p += p[1];
|
p[1] = 6;
|
||||||
*p = 47; // input packets
|
*(uint32_t *) (p + 2) = htonl(time(NULL) - session[s].opened);
|
||||||
|
p += p[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = 47; // input packets
|
||||||
p[1] = 6;
|
p[1] = 6;
|
||||||
*(uint32_t *) (p + 2) = htonl(session[s].pin);
|
*(uint32_t *) (p + 2) = htonl(session[s].pin);
|
||||||
p += p[1];
|
p += p[1];
|
||||||
*p = 48; // output spackets
|
|
||||||
|
*p = 48; // output packets
|
||||||
p[1] = 6;
|
p[1] = 6;
|
||||||
*(uint32_t *) (p + 2) = htonl(session[s].pout);
|
*(uint32_t *) (p + 2) = htonl(session[s].pout);
|
||||||
p += p[1];
|
p += p[1];
|
||||||
|
|
||||||
|
*p = 52; // input gigawords
|
||||||
|
p[1] = 6;
|
||||||
|
*(uint32_t *) (p + 2) = htonl(session[s].cin_wrap);
|
||||||
|
p += p[1];
|
||||||
|
|
||||||
|
*p = 53; // output gigawords
|
||||||
|
p[1] = 6;
|
||||||
|
*(uint32_t *) (p + 2) = htonl(session[s].cout_wrap);
|
||||||
|
p += p[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (session[s].snoop_ip && session[s].snoop_port)
|
if (session[s].snoop_ip && session[s].snoop_port)
|
||||||
|
|
@ -711,7 +727,6 @@ void radiusretry(uint16_t r)
|
||||||
|
|
||||||
if (s) t = session[s].tunnel;
|
if (s) t = session[s].tunnel;
|
||||||
|
|
||||||
radius[r].retry = backoff(radius[r].try + 1);
|
|
||||||
switch (radius[r].state)
|
switch (radius[r].state)
|
||||||
{
|
{
|
||||||
case RADIUSCHAP: // sending CHAP down PPP
|
case RADIUSCHAP: // sending CHAP down PPP
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue