Fix interface name comparison for detecting real interfaces

This commit is contained in:
Jeremy Lakeman 2014-01-20 16:01:24 +10:30
parent e0c2d59ab5
commit 04955f1ddd
4 changed files with 40 additions and 31 deletions

View File

@ -42,7 +42,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#endif
int overlay_ready=0;
unsigned overlay_interface_count=0;
overlay_interface overlay_interfaces[OVERLAY_MAX_INTERFACES];
int overlay_last_interface_number=-1;
@ -378,11 +377,18 @@ overlay_interface_init(const char *name, struct socket_address *addr,
{
int cleanup_ret = -1;
/* Too many interfaces */
if (overlay_interface_count >= OVERLAY_MAX_INTERFACES)
int interface_id=-1;
int i;
for (i=0; i<OVERLAY_MAX_INTERFACES; i++){
if (overlay_interfaces[i].state==INTERFACE_STATE_DOWN){
interface_id=i;
break;
}
}
if (interface_id==-1)
return WHY("Too many interfaces -- Increase OVERLAY_MAX_INTERFACES");
overlay_interface *const interface = &overlay_interfaces[overlay_interface_count];
overlay_interface *const interface = &overlay_interfaces[interface_id];
bzero(interface, sizeof(overlay_interface));
interface->state=INTERFACE_STATE_DOWN;
@ -539,7 +545,6 @@ overlay_interface_init(const char *name, struct socket_address *addr,
interface->destination->transfer_limit.burst_size,
interface->destination->transfer_limit.burst_length);
overlay_interface_count++;
return 0;
cleanup:
@ -946,12 +951,6 @@ overlay_interface_register(char *name,
struct socket_address *addr,
struct socket_address *broadcast)
{
if (config.debug.overlayinterfaces) {
// note, inet_ntop doesn't seem to behave on android
DEBUGF("%s address: %s", name, alloca_socket_address(addr));
DEBUGF("%s broadcast address: %s", name, alloca_socket_address(broadcast));
}
// Find the matching non-dummy interface rule.
const struct config_network_interface *ifconfig = NULL;
unsigned i;
@ -984,15 +983,19 @@ overlay_interface_register(char *name,
if (broadcast->addr.sa_family==AF_INET)
broadcast->inet.sin_port = htons(ifconfig->port);
if (config.debug.overlayinterfaces) {
// note, inet_ntop doesn't seem to behave on android
DEBUGF("%s address: %s", name, alloca_socket_address(addr));
DEBUGF("%s broadcast address: %s", name, alloca_socket_address(broadcast));
}
/* Search in the exist list of interfaces */
for(i = 0; i < overlay_interface_count; i++){
if (overlay_interfaces[i].state==INTERFACE_STATE_DOWN){
for(i = 0; i < OVERLAY_MAX_INTERFACES; i++){
if (overlay_interfaces[i].state==INTERFACE_STATE_DOWN)
continue;
}
if (strcasecmp(overlay_interfaces[i].name, name)
&& cmp_sockaddr(addr, &overlay_interfaces[i].address)==0
&& overlay_interfaces[i].state!=INTERFACE_STATE_DOWN){
if (strcasecmp(overlay_interfaces[i].name, name)==0
&& cmp_sockaddr(addr, &overlay_interfaces[i].address)==0){
// mark this interface as still alive
if (overlay_interfaces[i].state==INTERFACE_STATE_DETECTING)
@ -1005,8 +1008,8 @@ overlay_interface_register(char *name,
/* New interface, so register it */
if (overlay_interface_init(name, addr, broadcast, ifconfig))
return WHYF("Could not initialise newly seen interface %s", name);
else
if (config.debug.overlayinterfaces) DEBUGF("Registered interface %s", name);
else if (config.debug.overlayinterfaces)
DEBUGF("Registered interface %s", name);
return 0;
}
@ -1015,7 +1018,7 @@ 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_interface_count; i++)
for (i = 0; i < OVERLAY_MAX_INTERFACES; i++)
if (overlay_interfaces[i].state==INTERFACE_STATE_UP)
overlay_interfaces[i].state=INTERFACE_STATE_DETECTING;
@ -1031,7 +1034,7 @@ void overlay_interface_discover(struct sched_ent *alarm)
continue;
}
unsigned j;
for (j = 0; j < overlay_interface_count; j++){
for (j = 0; j < OVERLAY_MAX_INTERFACES; j++){
if (overlay_interfaces[j].socket_type == ifconfig->socket_type &&
strcasecmp(overlay_interfaces[j].name, ifconfig->file) == 0 &&
overlay_interfaces[j].state==INTERFACE_STATE_DETECTING){
@ -1040,7 +1043,7 @@ void overlay_interface_discover(struct sched_ent *alarm)
}
}
if (j >= overlay_interface_count) {
if (j >= OVERLAY_MAX_INTERFACES) {
// New file interface, so register it.
struct socket_address addr, broadcast;
bzero(&addr, sizeof addr);
@ -1114,7 +1117,7 @@ void overlay_interface_discover(struct sched_ent *alarm)
}
// Close any interfaces that have gone away.
for(i = 0; i < overlay_interface_count; i++)
for(i = 0; i < OVERLAY_MAX_INTERFACES; i++)
if (overlay_interfaces[i].state==INTERFACE_STATE_DETECTING) {
overlay_interface_close(&overlay_interfaces[i]);
}

View File

@ -3,10 +3,9 @@
#include "socket.h"
#define INTERFACE_STATE_FREE 0
#define INTERFACE_STATE_DOWN 0
#define INTERFACE_STATE_UP 1
#define INTERFACE_STATE_DOWN 2
#define INTERFACE_STATE_DETECTING 3
#define INTERFACE_STATE_DETECTING 2
struct overlay_interface;
@ -122,8 +121,6 @@ typedef struct overlay_interface {
*/
extern overlay_interface overlay_interfaces[OVERLAY_MAX_INTERFACES];
extern unsigned overlay_interface_count;
struct network_destination * new_destination(struct overlay_interface *interface, char encapsulation);
struct network_destination * create_unicast_destination(struct socket_address *addr, struct overlay_interface *interface);
struct network_destination * add_destination_ref(struct network_destination *ref);

View File

@ -387,9 +387,7 @@ void crash_handler(int signal)
BACKTRACE;
if (config.server.respawn_on_crash) {
unsigned i;
for(i=0;i<overlay_interface_count;i++)
if (overlay_interfaces[i].alarm.poll.fd>-1)
close(overlay_interfaces[i].alarm.poll.fd);
overlay_interface_close_all();
char execpath[160];
if (get_self_executable_path(execpath, sizeof execpath) != -1) {
strbuf b = strbuf_alloca(1024);

View File

@ -133,6 +133,17 @@ int cmp_sockaddr(const struct socket_address *addrA, const struct socket_address
return 1;
// Both addresses are in the same family...
switch (addrA->addr.sa_family) {
case AF_INET: {
if (addrA->inet.sin_addr.s_addr < addrB->inet.sin_addr.s_addr)
return -1;
if (addrA->inet.sin_addr.s_addr > addrB->inet.sin_addr.s_addr)
return 1;
if (addrA->inet.sin_port < addrB->inet.sin_port)
return -1;
if (addrA->inet.sin_port > addrB->inet.sin_port)
return 1;
return 0;
}break;
case AF_UNIX: {
unsigned pathlenA = addrA->addrlen - sizeof (addrA->local.sun_family);
unsigned pathlenB = addrB->addrlen - sizeof (addrB->local.sun_family);