Fasten quitting l2tp game

Drop routes as quickly as possible to lose as few packets as possible in the
meanwhile.
This commit is contained in:
Samuel Thibault 2024-01-21 02:45:44 +01:00
parent 0ac498d7d3
commit a22295d804
3 changed files with 105 additions and 16 deletions

View file

@ -435,8 +435,7 @@ static void send_heartbeat(int seq, uint8_t *data, int size)
if (size > sizeof(past_hearts[0].data)) if (size > sizeof(past_hearts[0].data))
{ {
LOG(0, 0, 0, "Tried to heartbeat something larger than the maximum packet!\n"); LOG(0, 0, 0, "Tried to heartbeat something larger than the maximum packet!\n");
kill(0, SIGTERM); crash();
exit(1);
} }
i = seq % HB_HISTORY_SIZE; i = seq % HB_HISTORY_SIZE;
past_hearts[i].seq = seq; past_hearts[i].seq = seq;
@ -903,8 +902,7 @@ static int hb_add_type(uint8_t **p, int type, int id)
break; break;
default: default:
LOG(0, 0, 0, "Found an invalid type in heart queue! (%d)\n", type); LOG(0, 0, 0, "Found an invalid type in heart queue! (%d)\n", type);
kill(0, SIGTERM); crash();
exit(1);
} }
return 0; return 0;
} }
@ -951,8 +949,7 @@ void cluster_heartbeat()
if (p > (buff + sizeof(buff))) { // Did we somehow manage to overun the buffer? if (p > (buff + sizeof(buff))) { // Did we somehow manage to overun the buffer?
LOG(0, 0, 0, "FATAL: Overran the heartbeat buffer! This is fatal. Exiting. (size %d)\n", (int) (p - buff)); LOG(0, 0, 0, "FATAL: Overran the heartbeat buffer! This is fatal. Exiting. (size %d)\n", (int) (p - buff));
kill(0, SIGTERM); crash();
exit(1);
} }
// //
@ -1011,8 +1008,7 @@ void cluster_heartbeat()
// Did we do something wrong? // Did we do something wrong?
if (p > (buff + sizeof(buff))) { // Did we somehow manage to overun the buffer? if (p > (buff + sizeof(buff))) { // Did we somehow manage to overun the buffer?
LOG(0, 0, 0, "Overran the heartbeat buffer now! This is fatal. Exiting. (size %d)\n", (int) (p - buff)); LOG(0, 0, 0, "Overran the heartbeat buffer now! This is fatal. Exiting. (size %d)\n", (int) (p - buff));
kill(0, SIGTERM); crash();
exit(1);
} }
LOG(4, 0, 0, "Sending v%d heartbeat #%d, change #%" PRIu64 " with %d changes " LOG(4, 0, 0, "Sending v%d heartbeat #%d, change #%" PRIu64 " with %d changes "
@ -1960,8 +1956,7 @@ static int cluster_process_heartbeat(uint8_t *data, int size, int more, uint8_t
LOG(0, 0, 0, "They've seen more state changes (%" PRIu64 " vs my %" PRIu64 ") so I'm gone!\n", LOG(0, 0, 0, "They've seen more state changes (%" PRIu64 " vs my %" PRIu64 ") so I'm gone!\n",
h->table_version, config->cluster_table_version); h->table_version, config->cluster_table_version);
kill(0, SIGTERM); crash();
exit(1);
} }
if (h->table_version < config->cluster_table_version) if (h->table_version < config->cluster_table_version)
@ -1969,8 +1964,7 @@ static int cluster_process_heartbeat(uint8_t *data, int size, int more, uint8_t
if (basetime > h->basetime) { if (basetime > h->basetime) {
LOG(0, 0, 0, "They're an older master than me so I'm gone!\n"); LOG(0, 0, 0, "They're an older master than me so I'm gone!\n");
kill(0, SIGTERM); crash();
exit(1);
} }
if (basetime < h->basetime) if (basetime < h->basetime)
@ -1978,8 +1972,7 @@ static int cluster_process_heartbeat(uint8_t *data, int size, int more, uint8_t
if (my_address < addr) { // Tie breaker. if (my_address < addr) { // Tie breaker.
LOG(0, 0, 0, "They're a higher IP address than me, so I'm gone!\n"); LOG(0, 0, 0, "They're a higher IP address than me, so I'm gone!\n");
kill(0, SIGTERM); crash();
exit(1);
} }
// //
@ -2366,8 +2359,7 @@ int processcluster(uint8_t *data, int size, in_addr_t addr)
} }
LOG(0, 0, 0, "Received a valid C_KILL: I'm going to die now.\n"); LOG(0, 0, 0, "Received a valid C_KILL: I'm going to die now.\n");
kill(0, SIGTERM); crash();
exit(0); // Lets be paranoid;
return -1; // Just signalling the compiler. return -1; // Just signalling the compiler.
case C_HEARTBEAT: case C_HEARTBEAT:

View file

@ -2119,6 +2119,66 @@ static int setupif(int ifidx, uint32_t mru, int config_addr)
return 0; return 0;
} }
//
// Quickly drop the gateway from the interface
static int disableif(int ifidx)
{
struct {
// interface setting
struct nlmsghdr nh;
union {
struct ifinfomsg ifinfo;
struct ifaddrmsg ifaddr;
} ifmsg;
char rtdata[32]; // 32 should be enough
} req;
in_addr_t ip;
memset(&req, 0, sizeof(req));
req.nh.nlmsg_type = RTM_DELADDR;
req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_MULTI;
req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(req.ifmsg.ifaddr));
req.ifmsg.ifaddr.ifa_family = AF_INET;
req.ifmsg.ifaddr.ifa_prefixlen = 32;
req.ifmsg.ifaddr.ifa_scope = RT_SCOPE_UNIVERSE;
req.ifmsg.ifaddr.ifa_index = ifidx;
if (config->nbmultiaddress > 1)
{
int i;
for (i = 0; i < config->nbmultiaddress ; i++)
{
ip = config->iftun_n_address[i];
rtnetlink_addattr(&req.nh, IFA_LOCAL, &ip, sizeof(ip));
if (rtnetlink_send(&req.nh) < 0)
return -1;
}
}
else
{
if (config->iftun_address)
ip = config->iftun_address;
else
ip = 0x01010101; // 1.1.1.1
rtnetlink_addattr(&req.nh, IFA_LOCAL, &ip, sizeof(ip));
if (rtnetlink_send(&req.nh) < 0)
return -1;
}
memset(&req, 0, sizeof(req));
req.nh.nlmsg_type = NLMSG_DONE;
req.nh.nlmsg_len = NLMSG_LENGTH(0);
if (rtnetlink_send(&req.nh) < 0)
return -1;
return 0;
}
// set up LAC UDP ports // set up LAC UDP ports
static int initlacudp(int *pudpfd, in_addr_t ip_dest, uint16_t port_dest) static int initlacudp(int *pudpfd, in_addr_t ip_dest, uint16_t port_dest)
{ {
@ -3821,6 +3881,33 @@ static void tunnelshutdown(tunnelidt t, char *reason, int result, int error, cha
} }
} }
static void drop_routes(void)
{
unsigned i;
LOG(1, 0, 0, "Disabling receiving l2tp\n");
// Disable receiving l2tp trafic first since we don't forward to master any more
disableif(tunidx);
LOG(1, 0, 0, "Dropping routes\n");
// Disable receiving Internet trafic
for (i = 1; i <= config->cluster_highest_sessionid ; ++i)
{
routesset(i, &session[i], 0);
routes6set(i, &session[i], 0);
}
}
//
// We ended up in an odd state, better stop here as quickly as possible before
// causing trouble to the rest of the cluster
//
void crash(void)
{
kill(0, SIGTERM);
drop_routes();
exit(1);
}
// read and process packet on tunnel (UDP) // read and process packet on tunnel (UDP)
void processudp(uint8_t *buf, int len, struct sockaddr_in *addr, uint16_t indexudpfd) void processudp(uint8_t *buf, int len, struct sockaddr_in *addr, uint16_t indexudpfd)
{ {
@ -6017,6 +6104,7 @@ static void mainloop(void)
} }
} }
} }
LOG(1, 0, 0, "Leaving...\n");
// Are we the master and shutting down?? // Are we the master and shutting down??
if (config->cluster_iam_master) if (config->cluster_iam_master)
@ -6032,6 +6120,14 @@ static void mainloop(void)
// //
// Important!!! We MUST not process any packets past this point! // Important!!! We MUST not process any packets past this point!
//
//
// Now drop routes as quickly as possible to lose as few packets as
// possible in the meanwhile
//
drop_routes();
LOG(1, 0, 0, "Shutdown complete\n"); LOG(1, 0, 0, "Shutdown complete\n");
} }

View file

@ -1037,6 +1037,7 @@ void throttle_session(sessionidt s, int rate_in, int rate_out);
int load_tunnel(tunnelidt, tunnelt *); int load_tunnel(tunnelidt, tunnelt *);
int load_session(sessionidt, sessiont *); int load_session(sessionidt, sessiont *);
void become_master(void); // We're the master; kick off any required master initializations. void become_master(void); // We're the master; kick off any required master initializations.
void crash(void); // We messed up. Die.
// cli.c // cli.c