diff --git a/src/edge.c b/src/edge.c index 3022582..693c5e7 100644 --- a/src/edge.c +++ b/src/edge.c @@ -664,59 +664,6 @@ static int loadFromFile(const char *path, n2n_edge_conf_t *conf, n2n_tuntap_priv /* ************************************** */ -#if defined(DUMMY_ID_00001) /* Disabled waiting for config option to enable it */ - -static char gratuitous_arp[] = { - 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* Dest mac */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Src mac */ - 0x08, 0x06, /* ARP */ - 0x00, 0x01, /* Ethernet */ - 0x08, 0x00, /* IP */ - 0x06, /* Hw Size */ - 0x04, /* Protocol Size */ - 0x00, 0x01, /* ARP Request */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Src mac */ - 0x00, 0x00, 0x00, 0x00, /* Src IP */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Target mac */ - 0x00, 0x00, 0x00, 0x00 /* Target IP */ -}; - -/* ************************************** */ - -/** Build a gratuitous ARP packet for a /24 layer 3 (IP) network. */ -static int build_gratuitous_arp(char *buffer, uint16_t buffer_len) { - if(buffer_len < sizeof(gratuitous_arp)) return(-1); - - memcpy(buffer, gratuitous_arp, sizeof(gratuitous_arp)); - memcpy(&buffer[6], device.mac_addr, 6); - memcpy(&buffer[22], device.mac_addr, 6); - memcpy(&buffer[28], &device.ip_addr, 4); - - /* REVISIT: BbMaj7 - use a real netmask here. This is valid only by accident - * for /24 IPv4 networks. */ - buffer[31] = 0xFF; /* Use a faked broadcast address */ - memcpy(&buffer[38], &device.ip_addr, 4); - return(sizeof(gratuitous_arp)); -} - -/* ************************************** */ - -/** Called from update_supernode_reg to periodically send gratuitous ARP - * broadcasts. */ -static void send_grat_arps(n2n_edge_t * eee,) { - char buffer[48]; - size_t len; - - traceEvent(TRACE_NORMAL, "Sending gratuitous ARP..."); - len = build_gratuitous_arp(buffer, sizeof(buffer)); - send_packet2net(eee, buffer, len); - send_packet2net(eee, buffer, len); /* Two is better than one :-) */ -} - -#endif /* #if defined(DUMMY_ID_00001) */ - -/* ************************************** */ - static void daemonize() { #ifndef WIN32 int childpid; diff --git a/src/edge_utils.c b/src/edge_utils.c index 97030c6..6f3a04c 100644 --- a/src/edge_utils.c +++ b/src/edge_utils.c @@ -929,6 +929,49 @@ static void send_register_ack(n2n_edge_t * eee, /* ************************************** */ +static char gratuitous_arp[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* dest MAC */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* src MAC */ + 0x08, 0x06, /* ARP */ + 0x00, 0x01, /* ethernet */ + 0x08, 0x00, /* IP */ + 0x06, /* hw Size */ + 0x04, /* protocol Size */ + 0x00, 0x02, /* ARP reply */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* src MAC */ + 0x00, 0x00, 0x00, 0x00, /* src IP */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* target MAC */ + 0x00, 0x00, 0x00, 0x00 /* target IP */ +}; + +// build a gratuitous ARP packet */ +static int build_gratuitous_arp(n2n_edge_t * eee, char *buffer, uint16_t buffer_len) { + if(buffer_len < sizeof(gratuitous_arp)) return(-1); + + memcpy(buffer, gratuitous_arp, sizeof(gratuitous_arp)); + memcpy(&buffer[6], eee->device.mac_addr, 6); + memcpy(&buffer[22], eee->device.mac_addr, 6); + memcpy(&buffer[28], &(eee->device.ip_addr), 4); + + memcpy(&buffer[38], &(eee->device.ip_addr), 4); + return(sizeof(gratuitous_arp)); +} + +/** Called from update_supernode_reg to periodically send gratuitous ARP + * broadcasts. */ +static void send_grat_arps(n2n_edge_t * eee) { + char buffer[48]; + size_t len; + + traceEvent(TRACE_DEBUG, "Sending gratuitous ARP..."); + len = build_gratuitous_arp(eee, buffer, sizeof(buffer)); + + edge_send_packet2net(eee, buffer, len); + edge_send_packet2net(eee, buffer, len); /* Two is better than one :-) */ +} + +/* ************************************** */ + /** @brief Check to see if we should re-register with the supernode. * * This is frequently called by the main loop. @@ -982,8 +1025,7 @@ void update_supernode_reg(n2n_edge_t * eee, time_t nowTime) { eee->sn_wait=1; - /* REVISIT: turn-on gratuitous ARP with config option. */ - /* send_grat_arps(sock_fd, is_udp_sock); */ + send_grat_arps(eee); eee->last_register_req = nowTime; } diff --git a/src/sn_utils.c b/src/sn_utils.c index a24975a..4ddf4f5 100644 --- a/src/sn_utils.c +++ b/src/sn_utils.c @@ -323,7 +323,7 @@ static int update_edge(n2n_sn_t *sss, time_t now) { macstr_t mac_buf; n2n_sock_str_t sockbuf; - struct peer_info *scan; + struct peer_info *scan, *iter, *tmp; traceEvent(TRACE_DEBUG, "update_edge for %s [%s]", macaddr_str(mac_buf, reg->edgeMac), @@ -331,6 +331,19 @@ static int update_edge(n2n_sn_t *sss, HASH_FIND_PEER(comm->edges, reg->edgeMac, scan); + // if unknown, make sure it is also not known by IP address + if (NULL == scan) { + HASH_ITER(hh,comm->edges,iter,tmp) { + if(iter->dev_addr.net_addr == reg->dev_addr.net_addr) { + scan = iter; + HASH_DEL(comm->edges, scan); + memcpy(&(scan->mac_addr), reg->edgeMac, sizeof(n2n_mac_t)); + HASH_ADD_PEER(comm->edges, scan); + break; + } + } + } + if (NULL == scan) { /* Not known */