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

@ -2119,6 +2119,66 @@ static int setupif(int ifidx, uint32_t mru, int config_addr)
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
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)
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??
if (config->cluster_iam_master)
@ -6032,6 +6120,14 @@ static void mainloop(void)
//
// 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");
}