handle SIGHUP

This commit is contained in:
sup39 2022-07-01 16:04:37 +09:00
parent 231e7f7fa4
commit c180cf207f
4 changed files with 112 additions and 99 deletions

View file

@ -1,4 +1,4 @@
VERSION = 0.1.0-beta.1 VERSION = 0.1.0-beta.2
CFLAGS = -Os $(and $(LUA_ROOT),-I$(LUA_ROOT)) $(MYCFLAGS) CFLAGS = -Os $(and $(LUA_ROOT),-I$(LUA_ROOT)) $(MYCFLAGS)
LDFLAGS = $(and $(LUA_ROOT),-L$(LUA_ROOT)) -llua -lm $(MYLDFLAGS) LDFLAGS = $(and $(LUA_ROOT),-L$(LUA_ROOT)) -llua -lm $(MYLDFLAGS)

View file

@ -203,5 +203,7 @@ int supRA_read_option(const char *path) {
intvl->interval = htonl(val); intvl->interval = htonl(val);
} }
// done
lua_close(L);
return rc; return rc;
} }

View file

@ -15,6 +15,7 @@ static uint8_t
*ra_msg_buflim = NULL; *ra_msg_buflim = NULL;
void init_ra_msg_buf(size_t bufsize) { void init_ra_msg_buf(size_t bufsize) {
free(ra_msg_buf); // free previous
ra_msg_ptr = ra_msg_buf = malloc(bufsize); ra_msg_ptr = ra_msg_buf = malloc(bufsize);
ra_msg_buflim = ra_msg_buf+bufsize; ra_msg_buflim = ra_msg_buf+bufsize;

View file

@ -15,8 +15,7 @@
#include <sys/epoll.h> #include <sys/epoll.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <netinet/icmp6.h> #include <netinet/icmp6.h>
#include <lua.h> #include <signal.h>
#include <lauxlib.h>
#include "icmpv6.h" #include "icmpv6.h"
#include "ra.h" #include "ra.h"
#include "options.h" #include "options.h"
@ -39,6 +38,8 @@ static void init_ra_msg(int if_mtu, uint8_t if_macaddr[6]) {
mtu->mtu = htonl(if_mtu); mtu->mtu = htonl(if_mtu);
} }
static void empty_handler(int sig) {}
#define PERROR_EXIT(msg) {perror(msg); exit(errno);} #define PERROR_EXIT(msg) {perror(msg); exit(errno);}
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
if (argc <= 2) { if (argc <= 2) {
@ -46,28 +47,28 @@ int main(int argc, char *argv[]) {
return 1; return 1;
} }
signal(SIGHUP, empty_handler);
while (1) {
const char *ifname = argv[1]; const char *ifname = argv[1];
int ifid = if_nametoindex(ifname); int ifid = if_nametoindex(ifname);
if (ifid == 0) PERROR_EXIT("Bad Interface"); if (ifid == 0) PERROR_EXIT("Bad Interface");
/** get link info (man netdevice) **/ /** get link info (man netdevice) **/
int if_mtu;
uint8_t if_macaddr[6];
struct ifreq ifr; struct ifreq ifr;
strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name)); strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
int iofd = socket(AF_INET6, SOCK_DGRAM, 0); int iofd = socket(AF_INET6, SOCK_DGRAM, 0);
if (iofd < 0) PERROR_EXIT("Fail to create socket"); if (iofd < 0) PERROR_EXIT("Fail to create socket");
// macaddr // macaddr
uint8_t if_macaddr[6];
if (ioctl(iofd, SIOCGIFHWADDR, &ifr)) PERROR_EXIT("Fail to ioctl(HWADDR)"); if (ioctl(iofd, SIOCGIFHWADDR, &ifr)) PERROR_EXIT("Fail to ioctl(HWADDR)");
memcpy(if_macaddr, &ifr.ifr_hwaddr.sa_data, sizeof(if_macaddr)); memcpy(if_macaddr, &ifr.ifr_hwaddr.sa_data, sizeof(if_macaddr));
// mtu // mtu
if (if_mtu <= 0) {
if (ioctl(iofd, SIOCGIFMTU, &ifr)) PERROR_EXIT("Fail to ioctl(MTU)"); if (ioctl(iofd, SIOCGIFMTU, &ifr)) PERROR_EXIT("Fail to ioctl(MTU)");
if_mtu = ifr.ifr_mtu; int if_mtu = ifr.ifr_mtu;
}
// clean // clean
close(iofd); close(iofd);
/* open icmpv6 socket */
int sfd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); int sfd = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
if (sfd < 0) PERROR_EXIT("Fail to create socket"); if (sfd < 0) PERROR_EXIT("Fail to create socket");
@ -125,26 +126,35 @@ int main(int argc, char *argv[]) {
if (now >= tnext) { // advertise right now if (now >= tnext) { // advertise right now
send_ra(sfd, (struct sockaddr*)&bcaddr, bcaddrlen); send_ra(sfd, (struct sockaddr*)&bcaddr, bcaddrlen);
tnext = now + 200 + 400*rand()/RAND_MAX; // TODO tnext = now + 200 + 400*rand()/RAND_MAX; // TODO
puts("to ff02::1");
} }
// wait for message or timeout
int evc = epoll_wait(epfd, evs, evcnt, tnext-now); int evc = epoll_wait(epfd, evs, evcnt, tnext-now);
if (evc < 0) PERROR_EXIT("Fail to epoll_wait"); if (evc < 0) {
while (evc--) { // interrupt => reload settings
uint32_t fd = evs[evc].data.fd; if (errno == EINTR) break;
uint8_t buf[4096]; // other error
char caddr_p[INET6_ADDRSTRLEN]; PERROR_EXIT("Fail to epoll_wait");
}
// received message
if (evc) {
struct sockaddr_in6 caddr; struct sockaddr_in6 caddr;
socklen_t caddrlen = sizeof(caddr); socklen_t caddrlen = sizeof(caddr);
ssize_t buflen = recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&caddr, &caddrlen); struct icmpv6_head msg;
if (buflen < 0) PERROR_EXIT("Fail to recvfrom()"); ssize_t msglen = recvfrom(sfd, &msg, sizeof msg, 0, (struct sockaddr*)&caddr, &caddrlen);
if (buflen < sizeof(struct icmpv6_head)) continue; // bad message if (msglen < 0) PERROR_EXIT("Fail to recvfrom()");
// if (caddr.sin6_scope_id != ifid) continue; // only response to RS
inet_ntop(AF_INET6, &caddr.sin6_addr, caddr_p, sizeof(caddr_p)); if (msglen == sizeof msg && msg.type == ICMPV6_RS) {
// struct icmpv6_head *h = (struct icmpv6_head*)buf;
send_ra(sfd, (struct sockaddr*)&caddr, caddrlen); send_ra(sfd, (struct sockaddr*)&caddr, caddrlen);
printf("to %s%%%d\n", caddr_p, caddr.sin6_scope_id);
} }
} }
}
// clean up
close(sfd);
close(epfd);
puts("Reloading...");
}
return 0; return 0;
} }