Moved SLPD related code to slpd.c
- Added setup_slpd()
This commit is contained in:
parent
62b63fff8b
commit
26a7e51cbe
4 changed files with 145 additions and 136 deletions
|
@ -60,7 +60,6 @@
|
||||||
|
|
||||||
int keylifetime = 0;
|
int keylifetime = 0;
|
||||||
int edgeupdateinterval = 0;
|
int edgeupdateinterval = 0;
|
||||||
int slpdinterval = 0;
|
|
||||||
#ifdef HAVE_LZO
|
#ifdef HAVE_LZO
|
||||||
static char lzo_wrkmem[LZO1X_999_MEM_COMPRESS > LZO1X_1_MEM_COMPRESS ? LZO1X_999_MEM_COMPRESS : LZO1X_1_MEM_COMPRESS];
|
static char lzo_wrkmem[LZO1X_999_MEM_COMPRESS > LZO1X_1_MEM_COMPRESS ? LZO1X_999_MEM_COMPRESS : LZO1X_1_MEM_COMPRESS];
|
||||||
#endif
|
#endif
|
||||||
|
@ -1592,25 +1591,6 @@ void handle_incoming_vpn_data(void *data, int flags) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_incoming_slpd_data(void *data, int flags) {
|
|
||||||
listen_socket_t *ls = data;
|
|
||||||
|
|
||||||
char pkt[MAXSIZE];
|
|
||||||
struct sockaddr_in6 addr;
|
|
||||||
socklen_t addrlen = sizeof(addr);
|
|
||||||
|
|
||||||
size_t len = recvfrom(ls->udp.fd, pkt, MAXSIZE, 0, (struct sockaddr *)&addr, &addrlen);
|
|
||||||
|
|
||||||
if(len <= 0 || len > MAXSIZE) {
|
|
||||||
if(!sockwouldblock(sockerrno))
|
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Receiving SLPD packet failed: %s", sockstrerror(sockerrno));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
handle_incoming_slpd_packet(ls, &pkt, &addr, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void handle_device_data(void *data, int flags) {
|
void handle_device_data(void *data, int flags) {
|
||||||
vpn_packet_t packet;
|
vpn_packet_t packet;
|
||||||
UNUSED(data);
|
UNUSED(data);
|
||||||
|
|
117
src/net_setup.c
117
src/net_setup.c
|
@ -39,6 +39,7 @@
|
||||||
#include "route.h"
|
#include "route.h"
|
||||||
#include "rsa.h"
|
#include "rsa.h"
|
||||||
#include "script.h"
|
#include "script.h"
|
||||||
|
#include "slpd.h"
|
||||||
#include "splay_tree.h"
|
#include "splay_tree.h"
|
||||||
#include "subnet.h"
|
#include "subnet.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
@ -49,9 +50,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char *myport;
|
char *myport;
|
||||||
char *my_slpd_port;
|
|
||||||
char *my_slpd_group;
|
|
||||||
int my_slpd_expire;
|
|
||||||
static char *myname;
|
static char *myname;
|
||||||
static io_t device_io;
|
static io_t device_io;
|
||||||
devops_t devops;
|
devops_t devops;
|
||||||
|
@ -325,7 +323,7 @@ static void slpdupdate_handler(void *data) {
|
||||||
|
|
||||||
while(c_iface) {
|
while(c_iface) {
|
||||||
logger(DEBUG_STATUS, LOG_NOTICE, "Sending SLPD out on %s", c_iface->value);
|
logger(DEBUG_STATUS, LOG_NOTICE, "Sending SLPD out on %s", c_iface->value);
|
||||||
send_slpd_broadcast(c_iface->value);
|
send_slpd_broadcast(myself, c_iface->value);
|
||||||
c_iface = lookup_config_next(config_tree, c_iface);
|
c_iface = lookup_config_next(config_tree, c_iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,105 +340,6 @@ static void edgeupdate_handler(void *data) {
|
||||||
timeout_set(data, &(struct timeval){edgeupdateinterval + (rand() % 10), rand() % 100000});
|
timeout_set(data, &(struct timeval){edgeupdateinterval + (rand() % 10), rand() % 100000});
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_slpd_broadcast(char *iface) {
|
|
||||||
int sd;
|
|
||||||
struct addrinfo *mcast_addr;
|
|
||||||
struct addrinfo hints;
|
|
||||||
sockaddr_t r;
|
|
||||||
|
|
||||||
char slpd_msg[MAXSIZE] = "";
|
|
||||||
|
|
||||||
/* Check if interface is up */
|
|
||||||
struct ifreq ifr;
|
|
||||||
sd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
|
|
||||||
memset(&ifr, 0, sizeof(ifr));
|
|
||||||
strcpy(ifr.ifr_name, iface);
|
|
||||||
if (ioctl(sd, SIOCGIFFLAGS, &ifr) < 0) {
|
|
||||||
logger(DEBUG_ALWAYS, LOG_INFO, "ioctl() on %s error: [%s:%d]", iface, strerror(errno), errno);
|
|
||||||
}
|
|
||||||
close(sd);
|
|
||||||
// Requested interface is down
|
|
||||||
if (!(ifr.ifr_flags & IFF_UP) || !(ifr.ifr_flags & IFF_RUNNING))
|
|
||||||
return;
|
|
||||||
|
|
||||||
bzero(&hints, sizeof(hints));
|
|
||||||
hints.ai_family = AF_INET6;
|
|
||||||
hints.ai_socktype = SOCK_DGRAM;
|
|
||||||
hints.ai_flags = AI_ADDRCONFIG | AI_CANONNAME;
|
|
||||||
|
|
||||||
int status;
|
|
||||||
if ((status = getaddrinfo(my_slpd_group, my_slpd_port, &hints, &mcast_addr)) != 0 ) {
|
|
||||||
logger(DEBUG_ALWAYS, LOG_INFO, "getaddrinfo() error: [%s:%d]", strerror(errno), errno);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((sd = socket(mcast_addr->ai_family, mcast_addr->ai_socktype, 0)) < 0 ) {
|
|
||||||
logger(DEBUG_ALWAYS, LOG_INFO, "socket() error: [%s:%d]", strerror(errno), errno);
|
|
||||||
freeaddrinfo(mcast_addr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int on = 1;
|
|
||||||
if (setsockopt(sd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&on, sizeof(on)) < 0) {
|
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "setsockopt() IPV6_V6ONLY failed [%s:%d]", strerror(errno), errno);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Send SLPD only on this Interface */
|
|
||||||
|
|
||||||
unsigned int ifindex;
|
|
||||||
ifindex = if_nametoindex(iface);
|
|
||||||
if(setsockopt (sd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex)) != 0) {
|
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "setsockopt() IPV6_MULTICAST_IF failed [%s:%d]", strerror(errno), errno);
|
|
||||||
freeaddrinfo(mcast_addr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int reuse = 1;
|
|
||||||
if(setsockopt (sd, IPPROTO_IPV6, SO_REUSEADDR, (char*)&reuse, sizeof(reuse)) != 0) {
|
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "setsockopt() SO_REUSEADDR failed: [%s:%d]", strerror(errno), errno);
|
|
||||||
freeaddrinfo(mcast_addr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(slpd_msg, MAXSIZE, "sLPD 0 2 %s %d", myname, atoi(myport));
|
|
||||||
|
|
||||||
char signature[87];
|
|
||||||
char b64sig[255];
|
|
||||||
char pkt[MAXSIZE];
|
|
||||||
|
|
||||||
if (!node_read_ecdsa_public_key(myself)) {
|
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Can not load public key for SLPD");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!read_ecdsa_private_key()) {
|
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Can not load private key for SLPD");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
slpd_msg[MAXSIZE-1] = '\00';
|
|
||||||
|
|
||||||
if (!ecdsa_sign(myself->connection->ecdsa, slpd_msg, strlen(slpd_msg), &signature)) {
|
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "Can not sign payload for SLPD");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b64encode(signature, b64sig, 64) != 86) {
|
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "b64encode() failed!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int l = snprintf(pkt, strlen(slpd_msg) + strlen(b64sig) + 2, "%s %s", slpd_msg, b64sig);
|
|
||||||
pkt[l] = '\00';
|
|
||||||
|
|
||||||
if (sendto(sd, pkt, strlen(pkt), 0, mcast_addr->ai_addr, mcast_addr->ai_addrlen) != strlen(pkt) ) {
|
|
||||||
logger(DEBUG_ALWAYS, LOG_ERR, "SLPD send() error: [%s:%d]", strerror(errno), errno);
|
|
||||||
}
|
|
||||||
|
|
||||||
close(sd);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void regenerate_key(void) {
|
void regenerate_key(void) {
|
||||||
logger(DEBUG_STATUS, LOG_INFO, "Expiring symmetric keys");
|
logger(DEBUG_STATUS, LOG_INFO, "Expiring symmetric keys");
|
||||||
send_key_changed();
|
send_key_changed();
|
||||||
|
@ -923,17 +822,7 @@ static bool setup_myself(void) {
|
||||||
else
|
else
|
||||||
port_specified = true;
|
port_specified = true;
|
||||||
|
|
||||||
if(!get_config_string(lookup_config(config_tree, "SLPDPort"), &my_slpd_port))
|
setup_slpd();
|
||||||
my_slpd_port = xstrdup(DEFAULT_SLPD_PORT);
|
|
||||||
|
|
||||||
if(!get_config_string(lookup_config(config_tree, "SLPDGroup"), &my_slpd_group))
|
|
||||||
my_slpd_group = xstrdup(DEFAULT_SLPD_GROUP);
|
|
||||||
|
|
||||||
char *tmp_expire;
|
|
||||||
if(!get_config_string(lookup_config(config_tree, "SLPDExpire"), &tmp_expire))
|
|
||||||
my_slpd_expire = DEFAULT_SLPD_EXPIRE;
|
|
||||||
else
|
|
||||||
my_slpd_expire = atoi(tmp_expire);
|
|
||||||
|
|
||||||
myself->connection->options = 0;
|
myself->connection->options = 0;
|
||||||
myself->connection->protocol_major = PROT_MAJOR;
|
myself->connection->protocol_major = PROT_MAJOR;
|
||||||
|
|
142
src/slpd.c
142
src/slpd.c
|
@ -19,10 +19,14 @@
|
||||||
|
|
||||||
#include "slpd.h"
|
#include "slpd.h"
|
||||||
|
|
||||||
extern int my_slpd_expire;
|
char *my_slpd_port;
|
||||||
|
char *my_slpd_group;
|
||||||
|
int my_slpd_expire;
|
||||||
|
int slpdinterval = 0;
|
||||||
|
|
||||||
|
extern char *myname;
|
||||||
|
|
||||||
void periodic_slpd_handler(void) {
|
void periodic_slpd_handler(void) {
|
||||||
|
|
||||||
// expire SLPD addresses
|
// expire SLPD addresses
|
||||||
for splay_each(node_t, n, node_tree) {
|
for splay_each(node_t, n, node_tree) {
|
||||||
if (!n->slpd_address)
|
if (!n->slpd_address)
|
||||||
|
@ -36,6 +40,20 @@ void periodic_slpd_handler(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setup_slpd(void) {
|
||||||
|
if(!get_config_string(lookup_config(config_tree, "SLPDPort"), &my_slpd_port))
|
||||||
|
my_slpd_port = xstrdup(DEFAULT_SLPD_PORT);
|
||||||
|
|
||||||
|
if(!get_config_string(lookup_config(config_tree, "SLPDGroup"), &my_slpd_group))
|
||||||
|
my_slpd_group = xstrdup(DEFAULT_SLPD_GROUP);
|
||||||
|
|
||||||
|
char *tmp_expire;
|
||||||
|
if(!get_config_string(lookup_config(config_tree, "SLPDExpire"), &tmp_expire))
|
||||||
|
my_slpd_expire = DEFAULT_SLPD_EXPIRE;
|
||||||
|
else
|
||||||
|
my_slpd_expire = atoi(tmp_expire);
|
||||||
|
}
|
||||||
|
|
||||||
int setup_slpd_in_socket(void) {
|
int setup_slpd_in_socket(void) {
|
||||||
int nfd;
|
int nfd;
|
||||||
char *my_slpd_port;
|
char *my_slpd_port;
|
||||||
|
@ -202,3 +220,123 @@ void handle_incoming_slpd_packet(listen_socket_t *ls, void *pkt, struct sockaddr
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void send_slpd_broadcast(node_t *myself, char *iface) {
|
||||||
|
int sd;
|
||||||
|
char *myname = myself->name;
|
||||||
|
struct addrinfo *mcast_addr;
|
||||||
|
struct addrinfo hints;
|
||||||
|
sockaddr_t r;
|
||||||
|
|
||||||
|
char slpd_msg[MAXSIZE] = "";
|
||||||
|
|
||||||
|
/* Check if interface is up */
|
||||||
|
struct ifreq ifr;
|
||||||
|
sd = socket(PF_INET6, SOCK_DGRAM, IPPROTO_IP);
|
||||||
|
memset(&ifr, 0, sizeof(ifr));
|
||||||
|
strcpy(ifr.ifr_name, iface);
|
||||||
|
if (ioctl(sd, SIOCGIFFLAGS, &ifr) < 0) {
|
||||||
|
logger(DEBUG_ALWAYS, LOG_INFO, "ioctl() on %s error: [%s:%d]", iface, strerror(errno), errno);
|
||||||
|
}
|
||||||
|
close(sd);
|
||||||
|
// Requested interface is down
|
||||||
|
if (!(ifr.ifr_flags & IFF_UP) || !(ifr.ifr_flags & IFF_RUNNING))
|
||||||
|
return;
|
||||||
|
|
||||||
|
bzero(&hints, sizeof(hints));
|
||||||
|
hints.ai_family = AF_INET6;
|
||||||
|
hints.ai_socktype = SOCK_DGRAM;
|
||||||
|
hints.ai_flags = AI_ADDRCONFIG | AI_CANONNAME;
|
||||||
|
|
||||||
|
int status;
|
||||||
|
if ((status = getaddrinfo(my_slpd_group, my_slpd_port, &hints, &mcast_addr)) != 0 ) {
|
||||||
|
logger(DEBUG_ALWAYS, LOG_INFO, "getaddrinfo() error: [%s:%d]", strerror(errno), errno);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((sd = socket(mcast_addr->ai_family, mcast_addr->ai_socktype, 0)) < 0 ) {
|
||||||
|
logger(DEBUG_ALWAYS, LOG_INFO, "socket() error: [%s:%d]", strerror(errno), errno);
|
||||||
|
freeaddrinfo(mcast_addr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int on = 1;
|
||||||
|
if (setsockopt(sd, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&on, sizeof(on)) < 0) {
|
||||||
|
logger(DEBUG_ALWAYS, LOG_ERR, "setsockopt() IPV6_V6ONLY failed [%s:%d]", strerror(errno), errno);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send SLPD only on this Interface */
|
||||||
|
|
||||||
|
unsigned int ifindex;
|
||||||
|
ifindex = if_nametoindex(iface);
|
||||||
|
if(setsockopt (sd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex)) != 0) {
|
||||||
|
logger(DEBUG_ALWAYS, LOG_ERR, "setsockopt() IPV6_MULTICAST_IF failed [%s:%d]", strerror(errno), errno);
|
||||||
|
freeaddrinfo(mcast_addr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int reuse = 1;
|
||||||
|
if(setsockopt (sd, IPPROTO_IPV6, SO_REUSEADDR, (char*)&reuse, sizeof(reuse)) != 0) {
|
||||||
|
logger(DEBUG_ALWAYS, LOG_ERR, "setsockopt() SO_REUSEADDR failed: [%s:%d]", strerror(errno), errno);
|
||||||
|
freeaddrinfo(mcast_addr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(slpd_msg, MAXSIZE, "sLPD 0 2 %s %d", myname, atoi(myport));
|
||||||
|
|
||||||
|
char signature[87];
|
||||||
|
char b64sig[255];
|
||||||
|
char pkt[MAXSIZE];
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (!node_read_ecdsa_public_key(myself)) {
|
||||||
|
logger(DEBUG_ALWAYS, LOG_ERR, "Can not load public key for SLPD");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!read_ecdsa_private_key()) {
|
||||||
|
logger(DEBUG_ALWAYS, LOG_ERR, "Can not load private key for SLPD");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
slpd_msg[MAXSIZE-1] = '\00';
|
||||||
|
|
||||||
|
if (!ecdsa_sign(myself->connection->ecdsa, slpd_msg, strlen(slpd_msg), &signature)) {
|
||||||
|
logger(DEBUG_ALWAYS, LOG_ERR, "Can not sign payload for SLPD");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b64encode(signature, b64sig, 64) != 86) {
|
||||||
|
logger(DEBUG_ALWAYS, LOG_ERR, "b64encode() failed!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int l = snprintf(pkt, strlen(slpd_msg) + strlen(b64sig) + 2, "%s %s", slpd_msg, b64sig);
|
||||||
|
pkt[l] = '\00';
|
||||||
|
|
||||||
|
if (sendto(sd, pkt, strlen(pkt), 0, mcast_addr->ai_addr, mcast_addr->ai_addrlen) != strlen(pkt) ) {
|
||||||
|
logger(DEBUG_ALWAYS, LOG_ERR, "SLPD send() error: [%s:%d]", strerror(errno), errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
close(sd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_incoming_slpd_data(void *data, int flags) {
|
||||||
|
listen_socket_t *ls = data;
|
||||||
|
|
||||||
|
char pkt[MAXSIZE];
|
||||||
|
struct sockaddr_in6 addr;
|
||||||
|
socklen_t addrlen = sizeof(addr);
|
||||||
|
|
||||||
|
size_t len = recvfrom(ls->udp.fd, pkt, MAXSIZE, 0, (struct sockaddr *)&addr, &addrlen);
|
||||||
|
|
||||||
|
if(len == 0 || len > MAXSIZE) {
|
||||||
|
if(!sockwouldblock(sockerrno))
|
||||||
|
logger(DEBUG_ALWAYS, LOG_ERR, "Receiving SLPD packet failed: %s", sockstrerror(sockerrno));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_incoming_slpd_packet(ls, &pkt, &addr, len);
|
||||||
|
}
|
||||||
|
|
|
@ -25,5 +25,7 @@
|
||||||
#include "xalloc.h"
|
#include "xalloc.h"
|
||||||
|
|
||||||
void periodic_slpd_handler(void);
|
void periodic_slpd_handler(void);
|
||||||
|
void setup_slpd(void);
|
||||||
int setup_slpd_in_socket(void);
|
int setup_slpd_in_socket(void);
|
||||||
void handle_incoming_slpd_packet(listen_socket_t *, void *, struct sockaddr_in6 *, size_t);
|
void handle_incoming_slpd_packet(listen_socket_t *, void *, struct sockaddr_in6 *, size_t);
|
||||||
|
void send_slpd_broadcast(node_t *, char *);
|
||||||
|
|
Loading…
Reference in a new issue