From 8f3009c448a3cb2e7398b717c584abf936464f72 Mon Sep 17 00:00:00 2001 From: emanuele-f Date: Sun, 22 Sep 2019 20:16:01 +0200 Subject: [PATCH] Fix occasional connection issues on startup due to bad MAC address read --- android/edge_android.c | 3 +++ edge.c | 3 +++ edge_utils.c | 4 --- example_edge_embed.c | 3 +++ tuntap_linux.c | 60 +++++++++++++++++------------------------- 5 files changed, 33 insertions(+), 40 deletions(-) diff --git a/android/edge_android.c b/android/edge_android.c index 68376a8..00aec91 100644 --- a/android/edge_android.c +++ b/android/edge_android.c @@ -165,6 +165,9 @@ int start_edge(const n2n_edge_cmd_t* cmd) traceLevel = traceLevel < 0 ? 0 : traceLevel; /* TRACE_ERROR */ traceLevel = traceLevel > 4 ? 4 : traceLevel; /* TRACE_DEBUG */ + /* Random seed */ + srand(time(NULL)); + if (-1 == edge_init(&eee) ) { traceEvent( TRACE_ERROR, "Failed in edge_init" ); diff --git a/edge.c b/edge.c index ac0b0b9..c5184ca 100644 --- a/edge.c +++ b/edge.c @@ -666,6 +666,9 @@ int main(int argc, char* argv[]) { traceEvent(TRACE_NORMAL, "Starting n2n edge %s %s", PACKAGE_VERSION, PACKAGE_BUILDDATE); + /* Random seed */ + srand(time(NULL)); + if(0 == strcmp("dhcp", ec.ip_mode)) { traceEvent(TRACE_NORMAL, "Dynamic IP address assignment enabled."); diff --git a/edge_utils.c b/edge_utils.c index b99f91e..9e7dc0a 100644 --- a/edge_utils.c +++ b/edge_utils.c @@ -171,10 +171,6 @@ n2n_edge_t* edge_init(const tuntap_dev *dev, const n2n_edge_conf_t *conf, int *r memcpy(&eee->device, dev, sizeof(*dev)); eee->start_time = time(NULL); - /* REVISIT: BbMaj7 : Should choose something with less predictability - * particularly for embedded targets with no real-time clock. */ - srand(eee->start_time); - eee->known_peers = NULL; eee->pending_peers = NULL; eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS; diff --git a/example_edge_embed.c b/example_edge_embed.c index 954d5b1..477c209 100644 --- a/example_edge_embed.c +++ b/example_edge_embed.c @@ -35,6 +35,9 @@ int main(int argc, char* argv[]) { /* Increase tracelevel to see what's happening */ setTraceLevel(10); + /* Random seed */ + srand(time(NULL)); + /* NOTE diff --git a/tuntap_linux.c b/tuntap_linux.c index 740c289..ae10445 100644 --- a/tuntap_linux.c +++ b/tuntap_linux.c @@ -24,36 +24,10 @@ #include #include -/* *************************************************** */ - -static void read_mac(char *ifname, n2n_mac_t mac_addr) { - int _sock, res; - struct ifreq ifr; - macstr_t mac_addr_buf; - - memset (&ifr,0,sizeof(struct ifreq)); - - /* Dummy socket, just to make ioctls with */ - _sock=socket(PF_INET, SOCK_DGRAM, 0); - strcpy(ifr.ifr_name, ifname); - res = ioctl(_sock,SIOCGIFHWADDR,&ifr); - - if(res < 0) { - perror ("Get hw addr"); - traceEvent(TRACE_ERROR, "Unable to read interfce %s MAC", ifname); - } else - memcpy(mac_addr, ifr.ifr_ifru.ifru_hwaddr.sa_data, 6); - - traceEvent(TRACE_NORMAL, "Interface %s has MAC %s", - ifname, - macaddr_str(mac_addr_buf, mac_addr )); - close(_sock); -} - /* ********************************** */ static int setup_ifname(int fd, const char *ifname, const char *ipaddr, - const char *netmask, const char *mac, int mtu) { + const char *netmask, uint8_t *mac, int mtu) { struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); @@ -61,14 +35,12 @@ static int setup_ifname(int fd, const char *ifname, const char *ipaddr, strncpy(ifr.ifr_name, ifname, IFNAMSIZ); ifr.ifr_name[IFNAMSIZ-1] = '\0'; - if(mac && mac[0]) { - str2mac((uint8_t *)ifr.ifr_hwaddr.sa_data, mac); - ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; + ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER; + memcpy(ifr.ifr_hwaddr.sa_data, mac, 6); - if(ioctl(fd, SIOCSIFHWADDR, &ifr) == -1) { - traceEvent(TRACE_ERROR, "ioctl(SIOCSIFHWADDR) failed [%d]: %s", errno, strerror(errno)); - return(-1); - } + if(ioctl(fd, SIOCSIFHWADDR, &ifr) == -1) { + traceEvent(TRACE_ERROR, "ioctl(SIOCSIFHWADDR) failed [%d]: %s", errno, strerror(errno)); + return(-1); } ifr.ifr_addr.sa_family = AF_INET; @@ -168,6 +140,23 @@ int tuntap_open(tuntap_dev *device, /* Store the device name for later reuse */ strncpy(device->dev_name, ifr.ifr_name, MIN(IFNAMSIZ, N2N_IFNAMSIZ) ); + if(device_mac && device_mac[0]) { + /* Use the user-provided MAC */ + str2mac(device->mac_addr, device_mac); + } else { + /* Set an explicit random MAC to know the exact MAC in use. Manually + * reading the MAC address is not safe as it may change internally + * also after the TAP interface UP status has been notified. */ + int i; + + for(i = 0; i < 6; i++) + device->mac_addr[i] = rand(); + + device->mac_addr[0] &= ~0x01; /* Clear multicast bit */ + device->mac_addr[0] |= 0x02; /* Set locally-assigned bit */ + } + + /* Initialize Netlink socket */ if((nl_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) == -1) { traceEvent(TRACE_ERROR, "netlink socket creation failed [%d]: %s", errno, strerror(errno)); return -1; @@ -198,7 +187,7 @@ int tuntap_open(tuntap_dev *device, return -1; } - if(setup_ifname(ioctl_fd, device->dev_name, device_ip, device_mask, device_mac, mtu) < 0) { + if(setup_ifname(ioctl_fd, device->dev_name, device_ip, device_mask, device->mac_addr, mtu) < 0) { close(nl_fd); close(ioctl_fd); close(device->fd); @@ -240,7 +229,6 @@ int tuntap_open(tuntap_dev *device, device->ip_addr = inet_addr(device_ip); device->device_mask = inet_addr(device_mask); - read_mac(dev, device->mac_addr); return(device->fd); }