// 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.134 2005-09-16 05:30:30 bodea Exp $";
+char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.142 2005-09-19 02:39:57 bodea Exp $";
#include <arpa/inet.h>
#include <assert.h>
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.
static char time_now_string[64] = {0}; // Current time as a string.
+int time_changed = 0; // time_now changed
char main_quit = 0; // True if we're in the process of exiting.
+char main_reload = 0; // Re-load pending
linked_list *loaded_plugins;
linked_list *plugins[MAX_PLUGIN_TYPES];
static void free_ip_address(sessionidt s);
static void dump_acct_info(int all);
static void sighup_handler(int sig);
-static void sigalrm_handler(int sig);
static void shutdown_handler(int sig);
static void sigchild_handler(int sig);
static void build_chap_response(uint8_t *challenge, uint8_t id, uint16_t challenge_length, uint8_t **challenge_response);
#define QUIT_SHUTDOWN 2 // SIGQUIT: shutdown sessions/tunnels, reject new connections
// return internal time (10ths since process startup), set f if given
+// as a side-effect sets time_now, and time_changed
static clockt now(double *f)
{
struct timeval t;
gettimeofday(&t, 0);
if (f) *f = t.tv_sec + t.tv_usec / 1000000.0;
+ if (t.tv_sec != time_now)
+ {
+ time_now = t.tv_sec;
+ time_changed++;
+ }
return (t.tv_sec - basetime) * 10 + t.tv_usec / 100000 + 1;
}
{
int d = (tcp[12] >> 4) * 4;
uint8_t *mss = 0;
+ uint8_t *opts;
uint8_t *data;
+ uint16_t orig;
+ uint32_t sum;
if ((tcp[13] & 0x3f) & ~(TCP_FLAG_SYN|TCP_FLAG_ACK)) // only want SYN and SYN,ACK
return;
if (tcp + d > buf + len) // short?
return;
+ opts = tcp + 20;
data = tcp + d;
- tcp += 20;
- while (tcp < data)
+ while (opts < data)
{
- if (*tcp == 2 && tcp[1] == 4) // mss option (2), length 4
+ if (*opts == 2 && opts[1] == 4) // mss option (2), length 4
{
- mss = tcp + 2;
+ mss = opts + 2;
if (mss + 2 > data) return; // short?
break;
}
- if (*tcp == 0) return; // end of options
- if (*tcp == 1 || !tcp[1]) // no op (one byte), or no length (prevent loop)
- tcp++;
+ if (*opts == 0) return; // end of options
+ if (*opts == 1 || !opts[1]) // no op (one byte), or no length (prevent loop)
+ opts++;
else
- tcp += tcp[1]; // skip over option
+ opts += opts[1]; // skip over option
}
if (!mss) return; // not found
- if (ntohs(*(uint16_t *) mss) <= MSS) return; // mss OK
+ orig = ntohs(*(uint16_t *) mss);
+
+ if (orig <= MSS) return; // mss OK
- LOG(5, s, t, "TCP: %s:%u -> %s:%u SYN%s, adjusted mss from %u to %u\n",
- fmtaddr(*(in_addr_t *)(buf + 12), 0), ntohs(*(uint16_t *)tcp),
- fmtaddr(*(in_addr_t *)(buf + 16), 1), ntohs(*(uint16_t *)(tcp + 2)),
- (tcp[13] & TCP_FLAG_ACK) ? ",ACK" : "",
- ntohs(*(uint16_t *) mss), MSS);
+ LOG(5, s, t, "TCP: %s:%u -> %s:%u SYN%s: adjusted mss from %u to %u\n",
+ fmtaddr(*(in_addr_t *) (buf + 12), 0), ntohs(*(uint16_t *) tcp),
+ fmtaddr(*(in_addr_t *) (buf + 16), 1), ntohs(*(uint16_t *) (tcp + 2)),
+ (tcp[13] & TCP_FLAG_ACK) ? ",ACK" : "", orig, MSS);
- // FIXME
+ // set mss
+ *(int16_t *) mss = htons(MSS);
+
+ // adjust checksum (see rfc1141)
+ sum = orig + (~MSS & 0xffff);
+ sum += ntohs(*(uint16_t *) (tcp + 16));
+ sum = (sum & 0xffff) + (sum >> 16);
+ *(uint16_t *) (tcp + 16) = htons(sum);
}
// process outgoing (to tunnel) IP
l += 6;
if (l > mru) l = mru;
- q = makeppp(buf, sizeof(buf), 0, 0, s, t, proto);
+ q = makeppp(buf, sizeof(buf), 0, 0, s, t, PPPLCP);
if (!q) return;
- *q = CodeRej;
+ *q = ProtocolRej;
*(q + 1) = ++sess_local[s].lcp_ident;
- *(uint16_t *)(q + 2) = l;
+ *(uint16_t *)(q + 2) = htons(l);
*(uint16_t *)(q + 4) = htons(proto);
memcpy(q + 6, p, l - 6);
int more = 0;
int n;
+
+ if (main_reload)
+ {
+ main_reload = 0;
+ read_config_file();
+ config->reload_config++;
+ }
+
if (config->reload_config)
{
- // Update the config state based on config settings
+ config->reload_config = 0;
update_config();
}
}
}
+ if (time_changed)
+ {
+ double Mbps = 1024.0 * 1024.0 / 8 * time_changed;
+
+ // Log current traffic stats
+ snprintf(config->bandwidth, sizeof(config->bandwidth),
+ "UDP-ETH:%1.0f/%1.0f ETH-UDP:%1.0f/%1.0f TOTAL:%0.1f IN:%u OUT:%u",
+ (udp_rx / Mbps), (eth_tx / Mbps), (eth_rx / Mbps), (udp_tx / Mbps),
+ ((udp_tx + udp_rx + eth_tx + eth_rx) / Mbps),
+ udp_rx_pkt / time_changed, eth_rx_pkt / time_changed);
+
+ udp_tx = udp_rx = 0;
+ udp_rx_pkt = eth_rx_pkt = 0;
+ eth_tx = eth_rx = 0;
+ time_changed = 0;
+
+ if (config->dump_speed)
+ printf("%s\n", config->bandwidth);
+
+ // Update the internal time counter
+ strftime(time_now_string, sizeof(time_now_string), "%Y-%m-%d %H:%M:%S", localtime(&time_now));
+
+ {
+ // Run timer hooks
+ struct param_timer p = { time_now };
+ run_plugins(PLUGIN_TIMER, &p);
+ }
+ }
+
// Runs on every machine (master and slaves).
if (next_cluster_ping <= TIME)
{
// Start the timer routine off
time(&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);
initplugins();
initdata(optdebug, optconfig);
init_cli(hostname);
read_config_file();
+ update_config();
init_tbf(config->num_tbfs);
LOG(0, 0, 0, "L2TPNS version " VERSION "\n");
LOG(0, 0, 0, "Can't lock pages: %s\n", strerror(errno));
}
- alarm(1);
-
// Drop privileges here
if (config->target_uid > 0 && geteuid() == 0)
setuid(config->target_uid);
static void sighup_handler(int sig)
{
- if (log_stream)
- {
- if (log_stream != stderr)
- fclose(log_stream);
-
- log_stream = NULL;
- }
-
- read_config_file();
-}
-
-static void sigalrm_handler(int sig)
-{
- // Log current traffic stats
-
- snprintf(config->bandwidth, sizeof(config->bandwidth),
- "UDP-ETH:%1.0f/%1.0f ETH-UDP:%1.0f/%1.0f TOTAL:%0.1f IN:%u OUT:%u",
- (udp_rx / 1024.0 / 1024.0 * 8),
- (eth_tx / 1024.0 / 1024.0 * 8),
- (eth_rx / 1024.0 / 1024.0 * 8),
- (udp_tx / 1024.0 / 1024.0 * 8),
- ((udp_tx + udp_rx + eth_tx + eth_rx) / 1024.0 / 1024.0 * 8),
- udp_rx_pkt, eth_rx_pkt);
-
- udp_tx = udp_rx = 0;
- udp_rx_pkt = eth_rx_pkt = 0;
- eth_tx = eth_rx = 0;
-
- if (config->dump_speed)
- printf("%s\n", config->bandwidth);
-
- // Update the internal time counter
- time(&time_now);
- strftime(time_now_string, sizeof(time_now_string), "%Y-%m-%d %H:%M:%S", localtime(&time_now));
- alarm(1);
-
- {
- // Run timer hooks
- struct param_timer p = { time_now };
- run_plugins(PLUGIN_TIMER, &p);
- }
-
+ main_reload++;
}
static void shutdown_handler(int sig)
{
- LOG(1, 0, 0, "Shutting down\n");
main_quit = (sig == SIGQUIT) ? QUIT_SHUTDOWN : QUIT_FAILOVER;
}
LOG(0, 0, 0, "Can't write to PID file %s: %s\n", config->pid_file, strerror(errno));
}
}
-
- config->reload_config = 0;
}
static void read_config_file()
cli_do_file(f);
LOG(3, 0, 0, "Done reading config file\n");
fclose(f);
- update_config();
}
int sessionsetup(sessionidt s, tunnelidt t)