mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-02-07 03:29:15 +00:00
Poll netlink socket for interface changes on linux systems
This commit is contained in:
parent
e770998372
commit
3049252c8a
@ -16,6 +16,7 @@ SQLITE3_INC := $(LOCAL_PATH)/sqlite-amalgamation-3070900
|
|||||||
|
|
||||||
SERVALD_LOCAL_CFLAGS = \
|
SERVALD_LOCAL_CFLAGS = \
|
||||||
-g \
|
-g \
|
||||||
|
-Wall -Wno-unused-value -Werror \
|
||||||
-DSERVALD_VERSION="\"Android\"" -DSERVALD_COPYRIGHT="\"Android\"" \
|
-DSERVALD_VERSION="\"Android\"" -DSERVALD_COPYRIGHT="\"Android\"" \
|
||||||
-DINSTANCE_PATH="\"/data/data/org.servalproject/var/serval-node\"" \
|
-DINSTANCE_PATH="\"/data/data/org.servalproject/var/serval-node\"" \
|
||||||
-DSHELL -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" \
|
-DSHELL -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" \
|
||||||
@ -29,7 +30,7 @@ SERVALD_LOCAL_CFLAGS = \
|
|||||||
-DHAVE_JNI_H=1 -DHAVE_STRUCT_UCRED=1 -DHAVE_CRYPTO_SIGN_NACL_GE25519_H=1 \
|
-DHAVE_JNI_H=1 -DHAVE_STRUCT_UCRED=1 -DHAVE_CRYPTO_SIGN_NACL_GE25519_H=1 \
|
||||||
-DBYTE_ORDER=_BYTE_ORDER -DHAVE_LINUX_STRUCT_UCRED -DUSE_ABSTRACT_NAMESPACE \
|
-DBYTE_ORDER=_BYTE_ORDER -DHAVE_LINUX_STRUCT_UCRED -DUSE_ABSTRACT_NAMESPACE \
|
||||||
-DHAVE_BCOPY -DHAVE_BZERO -DHAVE_NETINET_IN_H -DHAVE_LSEEK64 -DSIZEOF_OFF_T=4 \
|
-DHAVE_BCOPY -DHAVE_BZERO -DHAVE_NETINET_IN_H -DHAVE_LSEEK64 -DSIZEOF_OFF_T=4 \
|
||||||
-DHAVE_LINUX_IF_H -DHAVE_SYS_STAT_H -DHAVE_SYS_VFS_H \
|
-DHAVE_LINUX_IF_H -DHAVE_SYS_STAT_H -DHAVE_SYS_VFS_H -DHAVE_LINUX_NETLINK_H -DHAVE_LINUX_RTNETLINK_H \
|
||||||
-DSQLITE_OMIT_DATETIME_FUNCS -DSQLITE_OMIT_COMPILEOPTION_DIAGS -DSQLITE_OMIT_DEPRECATED \
|
-DSQLITE_OMIT_DATETIME_FUNCS -DSQLITE_OMIT_COMPILEOPTION_DIAGS -DSQLITE_OMIT_DEPRECATED \
|
||||||
-DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_OMIT_VIRTUALTABLE -DSQLITE_OMIT_AUTHORIZATION \
|
-DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_OMIT_VIRTUALTABLE -DSQLITE_OMIT_AUTHORIZATION \
|
||||||
-I$(NACL_INC) \
|
-I$(NACL_INC) \
|
||||||
|
62
lsif.c
62
lsif.c
@ -74,9 +74,8 @@
|
|||||||
#ifdef linux
|
#ifdef linux
|
||||||
/* for when all other options fail, as can happen on Android,
|
/* for when all other options fail, as can happen on Android,
|
||||||
if the permissions for the socket-based method are broken.
|
if the permissions for the socket-based method are broken.
|
||||||
Down side is that it while it gets the interface name and
|
While it gets the interface name and broadcast, it doesn't
|
||||||
broadcast, it doesn't get the local address for that
|
get the local address for that interface.
|
||||||
interface.
|
|
||||||
*/
|
*/
|
||||||
int scrapeProcNetRoute()
|
int scrapeProcNetRoute()
|
||||||
{
|
{
|
||||||
@ -97,27 +96,26 @@ int scrapeProcNetRoute()
|
|||||||
if (fgets(line,1024,f) == NULL)
|
if (fgets(line,1024,f) == NULL)
|
||||||
return WHYF_perror("fgets(%p,1024,\"/proc/net/route\")", line);
|
return WHYF_perror("fgets(%p,1024,\"/proc/net/route\")", line);
|
||||||
|
|
||||||
struct socket_address addr, broadcast;
|
struct socket_address addr, broadcast, netmask;
|
||||||
bzero(&addr, sizeof(addr));
|
bzero(&addr, sizeof(addr));
|
||||||
bzero(&broadcast, sizeof(broadcast));
|
bzero(&broadcast, sizeof(broadcast));
|
||||||
|
bzero(&netmask, sizeof(netmask));
|
||||||
|
|
||||||
addr.addrlen = sizeof(addr.inet);
|
addr.addrlen = sizeof(addr.inet);
|
||||||
addr.inet.sin_family = AF_INET;
|
addr.inet.sin_family = AF_INET;
|
||||||
broadcast.addrlen = sizeof(addr.inet);
|
broadcast.addrlen = sizeof(addr.inet);
|
||||||
broadcast.inet.sin_family = AF_INET;
|
broadcast.inet.sin_family = AF_INET;
|
||||||
|
netmask.addrlen = sizeof(netmask.inet);
|
||||||
|
netmask.inet.sin_family=AF_INET;
|
||||||
|
|
||||||
while(line[0]) {
|
while(line[0]) {
|
||||||
int r;
|
int r;
|
||||||
if ((r=sscanf(line,"%s %s %*s %*s %*s %*s %*s %s",name,dest,mask))==3) {
|
if ((r=sscanf(line,"%s %s %*s %*s %*s %*s %*s %s",name,dest,mask))==3) {
|
||||||
addr.inet.sin_addr.s_addr=strtol(dest,NULL,16);
|
addr.inet.sin_addr.s_addr=strtol(dest,NULL,16);
|
||||||
struct in_addr netmask = {.s_addr=strtol(mask,NULL,16)};
|
netmask.inet.sin_addr.s_addr=strtol(mask,NULL,16);
|
||||||
broadcast.inet.sin_addr.s_addr=addr.inet.sin_addr.s_addr | ~netmask.s_addr;
|
broadcast.inet.sin_addr.s_addr=addr.inet.sin_addr.s_addr | ~netmask.inet.sin_addr.s_addr;
|
||||||
|
|
||||||
struct socket_address netmask_addr;
|
overlay_interface_register(name,&addr,&netmask,&broadcast);
|
||||||
netmask_addr.addrlen = sizeof(netmask_addr.inet);
|
|
||||||
netmask_addr.inet.sin_family=AF_INET;
|
|
||||||
netmask_addr.inet.sin_addr.s_addr=netmask.s_addr;
|
|
||||||
|
|
||||||
overlay_interface_register(name,&addr,&netmask_addr,&broadcast);
|
|
||||||
}
|
}
|
||||||
line[0] = '\0';
|
line[0] = '\0';
|
||||||
if (fgets(line,1024,f) == NULL)
|
if (fgets(line,1024,f) == NULL)
|
||||||
@ -141,10 +139,10 @@ lsif(void) {
|
|||||||
struct ifconf ifc;
|
struct ifconf ifc;
|
||||||
int sck;
|
int sck;
|
||||||
struct ifreq *ifr;
|
struct ifreq *ifr;
|
||||||
struct in_addr netmask;
|
struct socket_address addr, broadcast, netmask;
|
||||||
struct socket_address addr, broadcast;
|
|
||||||
bzero(&addr, sizeof(addr));
|
bzero(&addr, sizeof(addr));
|
||||||
bzero(&broadcast, sizeof(broadcast));
|
bzero(&broadcast, sizeof(broadcast));
|
||||||
|
bzero(&netmask, sizeof(netmask));
|
||||||
|
|
||||||
DEBUG(overlayinterfaces, "called");
|
DEBUG(overlayinterfaces, "called");
|
||||||
|
|
||||||
@ -198,16 +196,13 @@ lsif(void) {
|
|||||||
WHY_perror("ioctl(SIOCGIFNETMASK)");
|
WHY_perror("ioctl(SIOCGIFNETMASK)");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
netmask = ((struct sockaddr_in *)&ifr->ifr_ifru.ifru_addr)->sin_addr;
|
|
||||||
|
|
||||||
broadcast.inet.sin_addr.s_addr=addr.inet.sin_addr.s_addr | ~netmask.s_addr;
|
netmask.addrlen = sizeof(netmask.inet);
|
||||||
|
bcopy(&ifr->ifr_ifru.ifru_addr, &netmask.inet, sizeof(netmask.inet));
|
||||||
|
|
||||||
struct socket_address netmask_addr;
|
broadcast.inet.sin_addr.s_addr=addr.inet.sin_addr.s_addr | ~netmask.inet.sin_addr.s_addr;
|
||||||
netmask_addr.addrlen = sizeof(netmask_addr.inet);
|
|
||||||
netmask_addr.inet.sin_family=AF_INET;
|
|
||||||
netmask_addr.inet.sin_addr.s_addr=netmask.s_addr;
|
|
||||||
|
|
||||||
overlay_interface_register(ifr->ifr_name, &addr, &netmask_addr, &broadcast);
|
overlay_interface_register(ifr->ifr_name, &addr, &netmask, &broadcast);
|
||||||
nInterfaces++;
|
nInterfaces++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,21 +219,18 @@ int
|
|||||||
doifaddrs(void) {
|
doifaddrs(void) {
|
||||||
struct ifaddrs *ifaddr, *ifa;
|
struct ifaddrs *ifaddr, *ifa;
|
||||||
char *name;
|
char *name;
|
||||||
struct socket_address addr, broadcast;
|
struct socket_address addr, broadcast, netmask;
|
||||||
struct in_addr netmask;
|
|
||||||
bzero(&addr, sizeof(addr));
|
bzero(&addr, sizeof(addr));
|
||||||
bzero(&broadcast, sizeof(broadcast));
|
bzero(&broadcast, sizeof(broadcast));
|
||||||
|
bzero(&netmask, sizeof(netmask));
|
||||||
|
|
||||||
DEBUGF(overlayinterfaces, "called");
|
DEBUGF(overlayinterfaces, "called");
|
||||||
|
|
||||||
if (getifaddrs(&ifaddr) == -1)
|
if (getifaddrs(&ifaddr) == -1)
|
||||||
return WHY_perror("getifaddr()");
|
return WHY_perror("getifaddr()");
|
||||||
|
|
||||||
broadcast.addrlen = sizeof(addr.inet);
|
|
||||||
broadcast.inet.sin_family = AF_INET;
|
|
||||||
|
|
||||||
for (ifa = ifaddr; ifa != NULL ; ifa = ifa->ifa_next) {
|
for (ifa = ifaddr; ifa != NULL ; ifa = ifa->ifa_next) {
|
||||||
if (!ifa->ifa_addr || !ifa->ifa_netmask)
|
if (!ifa->ifa_addr || !ifa->ifa_netmask || !ifa->ifa_broadaddr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* We're only interested in IPv4 addresses */
|
/* We're only interested in IPv4 addresses */
|
||||||
@ -254,22 +246,16 @@ doifaddrs(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
name = ifa->ifa_name;
|
name = ifa->ifa_name;
|
||||||
addr.addrlen = sizeof(addr.inet);
|
broadcast.addrlen = netmask.addrlen = addr.addrlen = sizeof(addr.inet);
|
||||||
bcopy(ifa->ifa_addr, &addr.addr, addr.addrlen);
|
|
||||||
|
|
||||||
netmask = ((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;
|
bcopy(ifa->ifa_addr, &addr.inet, addr.addrlen);
|
||||||
|
bcopy(ifa->ifa_netmask, &netmask.inet, netmask.addrlen);
|
||||||
|
bcopy(ifa->ifa_broadaddr, &broadcast.inet, broadcast.addrlen);
|
||||||
|
|
||||||
struct socket_address netmask_addr;
|
overlay_interface_register(name, &addr, &netmask, &broadcast);
|
||||||
netmask_addr.inet.sin_family=AF_INET;
|
|
||||||
netmask_addr.inet.sin_addr.s_addr=netmask.s_addr;
|
|
||||||
|
|
||||||
broadcast.inet.sin_addr.s_addr=addr.inet.sin_addr.s_addr | ~netmask.s_addr;
|
|
||||||
|
|
||||||
overlay_interface_register(name, &addr, &netmask_addr, &broadcast);
|
|
||||||
}
|
}
|
||||||
freeifaddrs(ifaddr);
|
freeifaddrs(ifaddr);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
|
|
||||||
#include "serval.h"
|
#include "serval.h"
|
||||||
#include "conf.h"
|
#include "conf.h"
|
||||||
#include "net.h"
|
#include "net.h"
|
||||||
@ -40,9 +41,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "route_link.h"
|
#include "route_link.h"
|
||||||
|
|
||||||
#ifdef HAVE_IFADDRS_H
|
|
||||||
#include <ifaddrs.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// The size of the receive buffer. This effectively sets the MRU for packet radio interfaces where
|
// The size of the receive buffer. This effectively sets the MRU for packet radio interfaces where
|
||||||
// we have to buffer packets on the receive side.
|
// we have to buffer packets on the receive side.
|
||||||
@ -59,6 +58,7 @@ struct socket_address sock_any_addr;
|
|||||||
struct profile_total sock_any_stats;
|
struct profile_total sock_any_stats;
|
||||||
|
|
||||||
static void overlay_interface_poll(struct sched_ent *alarm);
|
static void overlay_interface_poll(struct sched_ent *alarm);
|
||||||
|
static int inet_up_count=0;
|
||||||
|
|
||||||
void overlay_interface_close(overlay_interface *interface)
|
void overlay_interface_close(overlay_interface *interface)
|
||||||
{
|
{
|
||||||
@ -67,6 +67,17 @@ void overlay_interface_close(overlay_interface *interface)
|
|||||||
unlink(interface->address.local.sun_path);
|
unlink(interface->address.local.sun_path);
|
||||||
if (is_watching(&interface->alarm))
|
if (is_watching(&interface->alarm))
|
||||||
unwatch(&interface->alarm);
|
unwatch(&interface->alarm);
|
||||||
|
|
||||||
|
if (interface->address.addr.sa_family == AF_INET &&
|
||||||
|
inet_up_count>0 &&
|
||||||
|
--inet_up_count==0 &&
|
||||||
|
sock_any.poll.fd>0){
|
||||||
|
|
||||||
|
unwatch(&sock_any);
|
||||||
|
close(sock_any.poll.fd);
|
||||||
|
sock_any.poll.fd=-1;
|
||||||
|
}
|
||||||
|
|
||||||
close(interface->alarm.poll.fd);
|
close(interface->alarm.poll.fd);
|
||||||
interface->alarm.poll.fd=-1;
|
interface->alarm.poll.fd=-1;
|
||||||
}
|
}
|
||||||
@ -293,6 +304,21 @@ overlay_interface * overlay_interface_find_name_addr(const char *name, struct so
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// find an interface by name and socket type
|
||||||
|
overlay_interface * overlay_interface_find_name_type(const char *name, int socket_type){
|
||||||
|
int i;
|
||||||
|
for(i = 0; i < OVERLAY_MAX_INTERFACES; i++){
|
||||||
|
if (overlay_interfaces[i].state==INTERFACE_STATE_DOWN)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strcasecmp(overlay_interfaces[i].name, name)==0 &&
|
||||||
|
overlay_interfaces[i].ifconfig.socket_type == socket_type)
|
||||||
|
return &overlay_interfaces[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int interface_type_priority(int type)
|
static int interface_type_priority(int type)
|
||||||
{
|
{
|
||||||
switch(type){
|
switch(type){
|
||||||
@ -365,8 +391,20 @@ overlay_interface_read_any(struct sched_ent *alarm)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// bind a socket to INADDR_ANY:port
|
/*
|
||||||
// for now, we don't have a graceful close for this interface but it should go away when the process dies
|
bind a socket to INADDR_ANY:port
|
||||||
|
|
||||||
|
On linux you can bind to the broadcast address to receive broadcast packets per interface [or subnet],
|
||||||
|
but then you can't receive unicast packets on the same socket.
|
||||||
|
|
||||||
|
On osx, you can only receive broadcast packets if you bind to INADDR_ANY.
|
||||||
|
|
||||||
|
So the most portable way to do this is to bind to each interface's IP address for sending broadcasts
|
||||||
|
and receiving unicasts, and bind a separate socket to INADDR_ANY just for receiving broadcast packets.
|
||||||
|
|
||||||
|
Sending packets from INADDR_ANY would probably work, but gives us less control over which interfaces are sending packets.
|
||||||
|
But there may be some platforms that need some other combination for everything to work.
|
||||||
|
*/
|
||||||
static int overlay_interface_init_any(int port)
|
static int overlay_interface_init_any(int port)
|
||||||
{
|
{
|
||||||
if (sock_any.poll.fd>0){
|
if (sock_any.poll.fd>0){
|
||||||
@ -423,20 +461,6 @@ static void calc_next_tick(struct overlay_interface *interface)
|
|||||||
static int
|
static int
|
||||||
overlay_interface_init_socket(overlay_interface *interface)
|
overlay_interface_init_socket(overlay_interface *interface)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
On linux you can bind to the broadcast address to receive broadcast packets per interface [or subnet],
|
|
||||||
but then you can't receive unicast packets on the same socket.
|
|
||||||
|
|
||||||
On osx, you can only receive broadcast packets if you bind to INADDR_ANY.
|
|
||||||
|
|
||||||
So the most portable way to do this is to bind to each interface's IP address for sending broadcasts
|
|
||||||
and receiving unicasts, and bind a separate socket to INADDR_ANY just for receiving broadcast packets.
|
|
||||||
|
|
||||||
Sending packets from INADDR_ANY would probably work, but gives us less control over which interfaces are sending packets.
|
|
||||||
But there may be some platforms that need some other combination for everything to work.
|
|
||||||
*/
|
|
||||||
|
|
||||||
overlay_interface_init_any(interface->ifconfig.port);
|
|
||||||
|
|
||||||
interface->alarm.poll.fd = overlay_bind_socket(&interface->address);
|
interface->alarm.poll.fd = overlay_bind_socket(&interface->address);
|
||||||
|
|
||||||
@ -531,9 +555,10 @@ int overlay_interface_configure(struct overlay_interface *interface, const struc
|
|||||||
* Returns -1 in case of error (misconfiguration or system error).
|
* Returns -1 in case of error (misconfiguration or system error).
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
overlay_interface_init(const char *name, struct socket_address *addr,
|
overlay_interface_init(const char *name,
|
||||||
struct socket_address *netmask,
|
const struct socket_address *addr,
|
||||||
struct socket_address *broadcast,
|
const struct socket_address *netmask,
|
||||||
|
const struct socket_address *broadcast,
|
||||||
const struct config_network_interface *ifconfig)
|
const struct config_network_interface *ifconfig)
|
||||||
{
|
{
|
||||||
int cleanup_ret = -1;
|
int cleanup_ret = -1;
|
||||||
@ -578,10 +603,7 @@ overlay_interface_init(const char *name, struct socket_address *addr,
|
|||||||
case SOCK_DGRAM:
|
case SOCK_DGRAM:
|
||||||
if (ifconfig->broadcast.drop || ifconfig->unicast.drop || ifconfig->drop_packets)
|
if (ifconfig->broadcast.drop || ifconfig->unicast.drop || ifconfig->drop_packets)
|
||||||
FATALF("Invalid interface definition. We only support dropping packets on dummy file interfaces");
|
FATALF("Invalid interface definition. We only support dropping packets on dummy file interfaces");
|
||||||
if (netmask)
|
|
||||||
interface->netmask = netmask->inet.sin_addr;
|
interface->netmask = netmask->inet.sin_addr;
|
||||||
else
|
|
||||||
interface->netmask = ifconfig->dummy_netmask;
|
|
||||||
interface->local_echo = 1;
|
interface->local_echo = 1;
|
||||||
|
|
||||||
if (overlay_interface_init_socket(interface))
|
if (overlay_interface_init_socket(interface))
|
||||||
@ -1056,30 +1078,52 @@ int overlay_broadcast_ensemble(struct network_destination *destination, struct o
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register the real interface, or update the existing interface registration. */
|
static const struct config_network_interface *find_interface_config(const char *name, int socket_type)
|
||||||
int
|
|
||||||
overlay_interface_register(char *name,
|
|
||||||
struct socket_address *addr,
|
|
||||||
struct socket_address *netmask,
|
|
||||||
struct socket_address *broadcast)
|
|
||||||
{
|
{
|
||||||
// Find the matching non-dummy interface rule.
|
// Find a matching non-dummy interface rule.
|
||||||
const struct config_network_interface *ifconfig = NULL;
|
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for (i = 0; i < config.interfaces.ac; ++i, ifconfig = NULL) {
|
for (i = 0; i < config.interfaces.ac; ++i) {
|
||||||
ifconfig = &config.interfaces.av[i].value;
|
const struct config_network_interface *ifconfig = &config.interfaces.av[i].value;
|
||||||
if (ifconfig->socket_type==SOCK_DGRAM) {
|
if (ifconfig->socket_type==socket_type) {
|
||||||
unsigned j;
|
unsigned j;
|
||||||
for (j = 0; j < ifconfig->match.patc; ++j){
|
for (j = 0; j < ifconfig->match.patc; ++j){
|
||||||
if (fnmatch(ifconfig->match.patv[j], name, 0) == 0)
|
if (fnmatch(ifconfig->match.patv[j], name, 0) == 0)
|
||||||
break;
|
return ifconfig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (j < ifconfig->match.patc)
|
static int interface_unregister(const char *name,
|
||||||
break;
|
struct socket_address *addr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// Find the matching non-dummy interface rule.
|
||||||
|
const struct config_network_interface *ifconfig = find_interface_config(name, SOCK_DGRAM);
|
||||||
|
if (!ifconfig)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (addr->addr.sa_family==AF_INET)
|
||||||
|
addr->inet.sin_port = htons(ifconfig->port);
|
||||||
|
|
||||||
|
struct overlay_interface *interface = overlay_interface_find_name_addr(name, addr);
|
||||||
|
if (interface)
|
||||||
|
overlay_interface_close(interface);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (ifconfig == NULL) {
|
/* Register the real interface, or update the existing interface registration. */
|
||||||
|
int
|
||||||
|
overlay_interface_register(const char *name,
|
||||||
|
struct socket_address *addr,
|
||||||
|
const struct socket_address *netmask,
|
||||||
|
struct socket_address *broadcast)
|
||||||
|
{
|
||||||
|
// Find the matching non-dummy interface rule.
|
||||||
|
const struct config_network_interface *ifconfig = find_interface_config(name, SOCK_DGRAM);
|
||||||
|
if (!ifconfig) {
|
||||||
DEBUGF(overlayinterfaces, "Interface %s does not match any rule", name);
|
DEBUGF(overlayinterfaces, "Interface %s does not match any rule", name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1093,119 +1137,187 @@ overlay_interface_register(char *name,
|
|||||||
if (broadcast->addr.sa_family==AF_INET)
|
if (broadcast->addr.sa_family==AF_INET)
|
||||||
broadcast->inet.sin_port = htons(ifconfig->port);
|
broadcast->inet.sin_port = htons(ifconfig->port);
|
||||||
|
|
||||||
// note, inet_ntop doesn't seem to behave on android
|
|
||||||
DEBUGF(overlayinterfaces, "%s address: %s", name, alloca_socket_address(addr));
|
|
||||||
DEBUGF(overlayinterfaces, "%s netmask: %s", name, alloca_socket_address(netmask));
|
|
||||||
DEBUGF(overlayinterfaces, "%s broadcast address: %s", name, alloca_socket_address(broadcast));
|
|
||||||
|
|
||||||
struct overlay_interface *interface = overlay_interface_find_name_addr(name, addr);
|
struct overlay_interface *interface = overlay_interface_find_name_addr(name, addr);
|
||||||
if (interface){
|
// nothing to do if a matching interface is already up
|
||||||
// mark this interface as still alive
|
if (interface)
|
||||||
if (interface->state == INTERFACE_STATE_DETECTING)
|
|
||||||
interface->state = INTERFACE_STATE_UP;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
/* New interface, so register it */
|
/* New interface, so register it */
|
||||||
if (overlay_interface_init(name, addr, netmask, broadcast, ifconfig))
|
if (overlay_interface_init(name, addr, netmask, broadcast, ifconfig))
|
||||||
return WHYF("Could not initialise newly seen interface %s", name);
|
return WHYF("Could not initialise newly seen interface %s", name);
|
||||||
|
|
||||||
DEBUGF(overlayinterfaces, "Registered interface %s", name);
|
overlay_interface_init_any(ifconfig->port);
|
||||||
|
inet_up_count++;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_LINUX_NETLINK_H
|
||||||
|
|
||||||
|
DEFINE_ALARM(netlink_poll);
|
||||||
|
void netlink_poll(struct sched_ent *alarm)
|
||||||
|
{
|
||||||
|
uint8_t buff[4096];
|
||||||
|
ssize_t len = recv(alarm->poll.fd, buff, sizeof buff, 0);
|
||||||
|
if (len<=0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
DEBUGF(overlayinterfaces, "recv(%d) len %u", alarm->poll.fd, len);
|
||||||
|
|
||||||
|
struct nlmsghdr *nlh = (struct nlmsghdr *)buff;
|
||||||
|
for (nlh = (struct nlmsghdr *)buff; (NLMSG_OK (nlh, len)) && (nlh->nlmsg_type != NLMSG_DONE); nlh = NLMSG_NEXT(nlh, len)){
|
||||||
|
|
||||||
|
switch(nlh->nlmsg_type){
|
||||||
|
case RTM_NEWADDR:
|
||||||
|
case RTM_DELADDR:
|
||||||
|
{
|
||||||
|
struct ifaddrmsg *ifa = (struct ifaddrmsg *) NLMSG_DATA (nlh);
|
||||||
|
|
||||||
|
// ignore loopback addresses
|
||||||
|
if (ifa->ifa_scope == RT_SCOPE_HOST)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
struct rtattr *rth = IFA_RTA (ifa);
|
||||||
|
int rtl = IFA_PAYLOAD (nlh);
|
||||||
|
|
||||||
|
// ifa->ifa_family;
|
||||||
|
// ifa->ifa_prefixlen;
|
||||||
|
const char *name=NULL;
|
||||||
|
|
||||||
|
struct socket_address addr, broadcast, netmask_addr;
|
||||||
|
bzero(&addr, sizeof(addr));
|
||||||
|
bzero(&broadcast, sizeof(broadcast));
|
||||||
|
bzero(&netmask_addr, sizeof(netmask_addr));
|
||||||
|
|
||||||
|
addr.addr.sa_family = broadcast.addr.sa_family = netmask_addr.addr.sa_family = ifa->ifa_family;
|
||||||
|
|
||||||
|
if (ifa->ifa_family == AF_INET){
|
||||||
|
addr.addrlen = broadcast.addrlen = netmask_addr.addrlen = sizeof(addr.inet);
|
||||||
|
}else{
|
||||||
|
DEBUGF(overlayinterfaces, "Ignoring family %d", ifa->ifa_family);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;rtl && RTA_OK (rth, rtl); rth = RTA_NEXT (rth,rtl)){
|
||||||
|
void *data = RTA_DATA(rth);
|
||||||
|
|
||||||
|
switch(rth->rta_type){
|
||||||
|
case IFA_LOCAL:
|
||||||
|
addr.inet.sin_addr.s_addr = *((uint32_t *)data);
|
||||||
|
break;
|
||||||
|
case IFA_LABEL:
|
||||||
|
name = RTA_DATA(rth);
|
||||||
|
break;
|
||||||
|
case IFA_BROADCAST:
|
||||||
|
broadcast.inet.sin_addr.s_addr = *((uint32_t *)data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!name){
|
||||||
|
WARNF_perror("Interface name not provided by IFA_LABEL");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
//calculate netmask
|
||||||
|
unsigned prefix = ifa->ifa_prefixlen;
|
||||||
|
if (prefix>32)
|
||||||
|
prefix=32;
|
||||||
|
char *c = (char *)&netmask_addr.inet.sin_addr.s_addr;
|
||||||
|
unsigned i;
|
||||||
|
for (i=0;i<(prefix/8);i++)
|
||||||
|
*c++ = 0xFF;
|
||||||
|
if (prefix %8)
|
||||||
|
*c = 0xFF << (8 - (prefix %8));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nlh->nlmsg_type==RTM_NEWADDR){
|
||||||
|
DEBUGF(overlayinterfaces, "New addr %s, %s, %s, %s",
|
||||||
|
name,
|
||||||
|
alloca_socket_address(&addr),
|
||||||
|
alloca_socket_address(&broadcast),
|
||||||
|
alloca_socket_address(&netmask_addr)
|
||||||
|
);
|
||||||
|
overlay_interface_register(name, &addr, &netmask_addr, &broadcast);
|
||||||
|
}else if (nlh->nlmsg_type==RTM_DELADDR){
|
||||||
|
DEBUGF(overlayinterfaces, "Del addr %s, %s",
|
||||||
|
name,
|
||||||
|
alloca_socket_address(&addr)
|
||||||
|
);
|
||||||
|
interface_unregister(name, &addr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int netlink_socket()
|
||||||
|
{
|
||||||
|
int sock = esocket(AF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
|
||||||
|
if (sock<0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
struct sockaddr_nl addr;
|
||||||
|
memset (&addr,0,sizeof(addr));
|
||||||
|
addr.nl_family = AF_NETLINK;
|
||||||
|
addr.nl_groups = RTMGRP_IPV4_IFADDR;
|
||||||
|
|
||||||
|
if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == -1)
|
||||||
|
return WHYF_perror("bind(%d,AF_NETLINK,%lu)", sock, (unsigned long)sizeof(addr));
|
||||||
|
|
||||||
|
DEBUGF(overlayinterfaces, "bind(%d,AF_NETLINK,%lu)", sock, (unsigned long)sizeof(addr));
|
||||||
|
|
||||||
|
return sock;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int netlink_send_get(int fd)
|
||||||
|
{
|
||||||
|
struct {
|
||||||
|
struct nlmsghdr n;
|
||||||
|
struct ifaddrmsg r;
|
||||||
|
} req;
|
||||||
|
|
||||||
|
memset(&req, 0, sizeof(req));
|
||||||
|
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
|
||||||
|
req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
|
||||||
|
req.n.nlmsg_type = RTM_GETADDR;
|
||||||
|
req.r.ifa_family = AF_INET;
|
||||||
|
struct rtattr *rta = (struct rtattr *)(((char *)&req) + NLMSG_ALIGN(req.n.nlmsg_len));
|
||||||
|
rta->rta_len = RTA_LENGTH(4);
|
||||||
|
|
||||||
|
if (send(fd, &req, req.n.nlmsg_len, 0)<0)
|
||||||
|
return WHYF_perror("send(%d)", fd);
|
||||||
|
|
||||||
|
DEBUG(overlayinterfaces, "Sent RTM_GETADDR");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// send a request to the kernel to get all interface addresses now
|
||||||
|
// eg on config change
|
||||||
|
static int netlink_init()
|
||||||
|
{
|
||||||
|
struct sched_ent *alarm=&ALARM_STRUCT(netlink_poll);
|
||||||
|
if (!is_watching(alarm)){
|
||||||
|
alarm->poll.fd = netlink_socket();
|
||||||
|
if (alarm->poll.fd<0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
alarm->poll.events = POLLIN;
|
||||||
|
watch(alarm);
|
||||||
|
}
|
||||||
|
|
||||||
|
return netlink_send_get(alarm->poll.fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
// poll the OS's network interfaces
|
// poll the OS's network interfaces
|
||||||
DEFINE_ALARM(overlay_interface_discover);
|
DEFINE_ALARM(overlay_interface_discover);
|
||||||
void overlay_interface_discover(struct sched_ent *alarm)
|
void overlay_interface_discover(struct sched_ent *alarm)
|
||||||
{
|
{
|
||||||
/* Mark all UP interfaces as DETECTING, so we can tell which interfaces are new, and which are dead */
|
|
||||||
unsigned i;
|
|
||||||
for (i = 0; i < OVERLAY_MAX_INTERFACES; i++)
|
|
||||||
if (overlay_interfaces[i].state==INTERFACE_STATE_UP)
|
|
||||||
overlay_interfaces[i].state=INTERFACE_STATE_DETECTING;
|
|
||||||
|
|
||||||
/* Register new file interfaces */
|
|
||||||
int detect_real_interfaces = 0;
|
|
||||||
const struct config_network_interface *ifconfig = NULL;
|
|
||||||
for (i = 0; i < config.interfaces.ac; ++i, ifconfig = NULL) {
|
|
||||||
ifconfig = &config.interfaces.av[i].value;
|
|
||||||
if (ifconfig->exclude)
|
|
||||||
continue;
|
|
||||||
if (!*ifconfig->file) {
|
|
||||||
detect_real_interfaces = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
unsigned j;
|
|
||||||
for (j = 0; j < OVERLAY_MAX_INTERFACES; j++){
|
|
||||||
if (overlay_interfaces[j].ifconfig.socket_type == ifconfig->socket_type &&
|
|
||||||
strcasecmp(overlay_interfaces[j].name, ifconfig->file) == 0 &&
|
|
||||||
overlay_interfaces[j].state==INTERFACE_STATE_DETECTING){
|
|
||||||
overlay_interfaces[j].state=INTERFACE_STATE_UP;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j >= OVERLAY_MAX_INTERFACES) {
|
|
||||||
// New file interface, so register it.
|
|
||||||
struct socket_address addr, netmask, broadcast;
|
|
||||||
bzero(&addr, sizeof addr);
|
|
||||||
bzero(&netmask, sizeof addr);
|
|
||||||
bzero(&broadcast, sizeof broadcast);
|
|
||||||
|
|
||||||
switch(ifconfig->socket_type){
|
|
||||||
case SOCK_FILE:
|
|
||||||
// use a fake inet address
|
|
||||||
addr.addrlen=sizeof addr.inet;
|
|
||||||
addr.inet.sin_family=AF_INET;
|
|
||||||
addr.inet.sin_port=htons(ifconfig->port);
|
|
||||||
addr.inet.sin_addr=ifconfig->dummy_address;
|
|
||||||
|
|
||||||
netmask.addrlen=sizeof addr.inet;
|
|
||||||
netmask.inet.sin_family=AF_INET;
|
|
||||||
netmask.inet.sin_port=htons(ifconfig->port);
|
|
||||||
netmask.inet.sin_addr.s_addr=ifconfig->dummy_netmask.s_addr;
|
|
||||||
|
|
||||||
broadcast.addrlen=sizeof addr.inet;
|
|
||||||
broadcast.inet.sin_family=AF_INET;
|
|
||||||
broadcast.inet.sin_port=htons(ifconfig->port);
|
|
||||||
broadcast.inet.sin_addr.s_addr=ifconfig->dummy_address.s_addr | ~ifconfig->dummy_netmask.s_addr;
|
|
||||||
// Fallthrough
|
|
||||||
case SOCK_STREAM:
|
|
||||||
overlay_interface_init(ifconfig->file, &addr, NULL, &broadcast, ifconfig);
|
|
||||||
break;
|
|
||||||
case SOCK_EXT:
|
|
||||||
// FAIL?
|
|
||||||
break;
|
|
||||||
case SOCK_DGRAM:
|
|
||||||
{
|
|
||||||
// use a local dgram socket
|
|
||||||
// no abstract sockets for now
|
|
||||||
if (!FORMF_SERVAL_RUN_PATH(addr.local.sun_path, "%s/%s", config.server.interface_path, ifconfig->file)) {
|
|
||||||
// TODO set ifconfig->exclude to prevent spam??
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
unlink(addr.local.sun_path);
|
|
||||||
addr.local.sun_family=AF_UNIX;
|
|
||||||
size_t len = strlen(addr.local.sun_path);
|
|
||||||
|
|
||||||
addr.addrlen=sizeof addr.local.sun_family + len + 1;
|
|
||||||
|
|
||||||
broadcast = addr;
|
|
||||||
while(len && broadcast.local.sun_path[len]!='/')
|
|
||||||
broadcast.local.sun_path[len--]='\0';
|
|
||||||
broadcast.addrlen = sizeof addr.local.sun_family + len + 2;
|
|
||||||
|
|
||||||
INFOF("Attempting to bind local socket w. addr %s, broadcast %s",
|
|
||||||
alloca_socket_address(&addr), alloca_socket_address(&broadcast));
|
|
||||||
overlay_interface_init(ifconfig->file, &addr, &netmask, &broadcast, ifconfig);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Register new real interfaces
|
// Register new real interfaces
|
||||||
if (detect_real_interfaces) {
|
|
||||||
int no_route = 1;
|
int no_route = 1;
|
||||||
#ifdef HAVE_IFADDRS_H
|
#ifdef HAVE_IFADDRS_H
|
||||||
if (no_route != 0)
|
if (no_route != 0)
|
||||||
@ -1222,31 +1334,124 @@ void overlay_interface_discover(struct sched_ent *alarm)
|
|||||||
if (no_route != 0) {
|
if (no_route != 0) {
|
||||||
FATAL("Unable to get any interface information");
|
FATAL("Unable to get any interface information");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Close any interfaces that have gone away.
|
|
||||||
unsigned inet_up_count=0;
|
|
||||||
for(i = 0; i < OVERLAY_MAX_INTERFACES; i++){
|
|
||||||
if (overlay_interfaces[i].state==INTERFACE_STATE_DETECTING)
|
|
||||||
overlay_interface_close(&overlay_interfaces[i]);
|
|
||||||
if (overlay_interfaces[i].state==INTERFACE_STATE_UP &&
|
|
||||||
overlay_interfaces[i].address.addr.sa_family == AF_INET)
|
|
||||||
inet_up_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inet_up_count==0 && sock_any.poll.fd>0){
|
|
||||||
unwatch(&sock_any);
|
|
||||||
close(sock_any.poll.fd);
|
|
||||||
sock_any.poll.fd=-1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if there are no real interfaces to detect, we can wait for the config file to change
|
|
||||||
if (detect_real_interfaces){
|
|
||||||
alarm->alarm = gettime_ms()+5000;
|
alarm->alarm = gettime_ms()+5000;
|
||||||
alarm->deadline = alarm->alarm + 10000;
|
alarm->deadline = alarm->alarm + 10000;
|
||||||
schedule(alarm);
|
schedule(alarm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void file_interface_init(const struct config_network_interface *ifconfig)
|
||||||
|
{
|
||||||
|
struct socket_address addr, netmask, broadcast;
|
||||||
|
bzero(&addr, sizeof addr);
|
||||||
|
bzero(&netmask, sizeof addr);
|
||||||
|
bzero(&broadcast, sizeof broadcast);
|
||||||
|
|
||||||
|
switch(ifconfig->socket_type){
|
||||||
|
case SOCK_FILE:
|
||||||
|
// use a fake inet address
|
||||||
|
addr.addrlen=sizeof addr.inet;
|
||||||
|
addr.inet.sin_family=AF_INET;
|
||||||
|
addr.inet.sin_port=htons(ifconfig->port);
|
||||||
|
addr.inet.sin_addr=ifconfig->dummy_address;
|
||||||
|
|
||||||
|
netmask.addrlen=sizeof addr.inet;
|
||||||
|
netmask.inet.sin_family=AF_INET;
|
||||||
|
netmask.inet.sin_port=htons(ifconfig->port);
|
||||||
|
netmask.inet.sin_addr=ifconfig->dummy_netmask;
|
||||||
|
|
||||||
|
broadcast.addrlen=sizeof addr.inet;
|
||||||
|
broadcast.inet.sin_family=AF_INET;
|
||||||
|
broadcast.inet.sin_port=htons(ifconfig->port);
|
||||||
|
broadcast.inet.sin_addr.s_addr=ifconfig->dummy_address.s_addr | ~ifconfig->dummy_netmask.s_addr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SOCK_STREAM:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SOCK_DGRAM:
|
||||||
|
{
|
||||||
|
// use a local dgram socket
|
||||||
|
// no abstract sockets for now
|
||||||
|
if (!FORMF_SERVAL_RUN_PATH(addr.local.sun_path, "%s/%s", config.server.interface_path, ifconfig->file))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
unlink(addr.local.sun_path);
|
||||||
|
addr.local.sun_family=AF_UNIX;
|
||||||
|
size_t len = strlen(addr.local.sun_path);
|
||||||
|
|
||||||
|
addr.addrlen=sizeof addr.local.sun_family + len + 1;
|
||||||
|
|
||||||
|
broadcast = addr;
|
||||||
|
while(len && broadcast.local.sun_path[len]!='/')
|
||||||
|
broadcast.local.sun_path[len--]='\0';
|
||||||
|
broadcast.addrlen = sizeof addr.local.sun_family + len + 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
// ignore
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
overlay_interface_init(ifconfig->file, &addr, &netmask, &broadcast, ifconfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
void overlay_interface_config_change()
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
int real_interface = 0;
|
||||||
|
|
||||||
|
// bring down any interface that no longer matches configuration
|
||||||
|
for (i = 0; i < OVERLAY_MAX_INTERFACES; i++){
|
||||||
|
if (overlay_interfaces[i].state!=INTERFACE_STATE_UP ||
|
||||||
|
overlay_interfaces[i].ifconfig.socket_type == SOCK_EXT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const struct config_network_interface *ifconfig = find_interface_config(
|
||||||
|
overlay_interfaces[i].name,
|
||||||
|
overlay_interfaces[i].ifconfig.socket_type
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!ifconfig || ifconfig->exclude){
|
||||||
|
overlay_interface_close(&overlay_interfaces[i]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create dummy file or AF_UNIX interfaces
|
||||||
|
for (i = 0; i < config.interfaces.ac; ++i) {
|
||||||
|
const struct config_network_interface *ifconfig = &config.interfaces.av[i].value;
|
||||||
|
if (ifconfig->exclude)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// ignore real interfaces, we'll deal with them later
|
||||||
|
if (!*ifconfig->file) {
|
||||||
|
real_interface = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
overlay_interface *interface = overlay_interface_find_name_type(ifconfig->file, ifconfig->socket_type);
|
||||||
|
// ignore interfaces that are already up
|
||||||
|
if (interface)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// New file interface, so register it.
|
||||||
|
file_interface_init(ifconfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (real_interface){
|
||||||
|
#ifdef HAVE_LINUX_NETLINK_H
|
||||||
|
// start listening for network changes & request current interface addresses
|
||||||
|
netlink_init();
|
||||||
|
#else
|
||||||
|
// re-check all interfaces periodically
|
||||||
|
time_ms_t now = gettime_ms();
|
||||||
|
RESCHEDULE(&ALARM_STRUCT(overlay_interface_discover), now, now, now);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void logServalPacket(int level, struct __sourceloc __whence, const char *message, const unsigned char *packet, size_t len) {
|
void logServalPacket(int level, struct __sourceloc __whence, const char *message, const unsigned char *packet, size_t len) {
|
||||||
|
@ -26,7 +26,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||||||
|
|
||||||
#define INTERFACE_STATE_DOWN 0
|
#define INTERFACE_STATE_DOWN 0
|
||||||
#define INTERFACE_STATE_UP 1
|
#define INTERFACE_STATE_UP 1
|
||||||
#define INTERFACE_STATE_DETECTING 2
|
|
||||||
|
|
||||||
struct overlay_interface;
|
struct overlay_interface;
|
||||||
|
|
||||||
@ -107,8 +106,7 @@ struct network_destination * create_unicast_destination(struct socket_address *a
|
|||||||
struct network_destination * add_destination_ref(struct network_destination *ref);
|
struct network_destination * add_destination_ref(struct network_destination *ref);
|
||||||
void release_destination_ref(struct network_destination *ref);
|
void release_destination_ref(struct network_destination *ref);
|
||||||
int set_destination_ref(struct network_destination **ptr, struct network_destination *ref);
|
int set_destination_ref(struct network_destination **ptr, struct network_destination *ref);
|
||||||
|
void overlay_interface_config_change();
|
||||||
DECLARE_ALARM(overlay_interface_discover);
|
|
||||||
|
|
||||||
struct config_mdp_iftype;
|
struct config_mdp_iftype;
|
||||||
int overlay_destination_configure(struct network_destination *dest, const struct config_mdp_iftype *ifconfig);
|
int overlay_destination_configure(struct network_destination *dest, const struct config_mdp_iftype *ifconfig);
|
||||||
@ -117,15 +115,16 @@ struct config_network_interface;
|
|||||||
int overlay_interface_configure(struct overlay_interface *interface, const struct config_network_interface *ifconfig);
|
int overlay_interface_configure(struct overlay_interface *interface, const struct config_network_interface *ifconfig);
|
||||||
|
|
||||||
int
|
int
|
||||||
overlay_interface_init(const char *name, struct socket_address *addr,
|
overlay_interface_init(const char *name,
|
||||||
struct socket_address *netmask,
|
const struct socket_address *addr,
|
||||||
struct socket_address *broadcast,
|
const struct socket_address *netmask,
|
||||||
|
const struct socket_address *broadcast,
|
||||||
const struct config_network_interface *ifconfig);
|
const struct config_network_interface *ifconfig);
|
||||||
void overlay_interface_close(overlay_interface *interface);
|
void overlay_interface_close(overlay_interface *interface);
|
||||||
|
|
||||||
int overlay_interface_register(char *name,
|
int overlay_interface_register(const char *name,
|
||||||
struct socket_address *addr,
|
struct socket_address *addr,
|
||||||
struct socket_address *netmask,
|
const struct socket_address *netmask,
|
||||||
struct socket_address *broadcast);
|
struct socket_address *broadcast);
|
||||||
void overlay_interface_close_all();
|
void overlay_interface_close_all();
|
||||||
overlay_interface * overlay_interface_get_default();
|
overlay_interface * overlay_interface_get_default();
|
||||||
|
3
server.c
3
server.c
@ -564,8 +564,7 @@ void cf_on_config_change()
|
|||||||
dna_helper_start();
|
dna_helper_start();
|
||||||
directory_service_init();
|
directory_service_init();
|
||||||
|
|
||||||
// check for interfaces at least once after config change
|
overlay_interface_config_change();
|
||||||
RESCHEDULE(&ALARM_STRUCT(overlay_interface_discover), now, now, now);
|
|
||||||
|
|
||||||
if (link_has_neighbours())
|
if (link_has_neighbours())
|
||||||
// send rhizome sync periodically
|
// send rhizome sync periodically
|
||||||
|
Loading…
x
Reference in New Issue
Block a user