From 81a3102661b8071b70686c9194740d2fbf40aaf1 Mon Sep 17 00:00:00 2001 From: emanuele-f Date: Wed, 10 Jun 2020 00:30:11 +0200 Subject: [PATCH] Compilation fixes for hin2n --- android/edge_android.c | 328 +++++++++++++++------------------------ android/edge_android.h | 64 -------- android/tuntap_android.c | 2 +- edge_utils.c | 111 ++++++++++++- n2n.c | 50 ++++++ n2n.h | 4 + speck.c | 4 + 7 files changed, 297 insertions(+), 266 deletions(-) delete mode 100644 android/edge_android.h diff --git a/android/edge_android.c b/android/edge_android.c index 00aec91..b61d609 100644 --- a/android/edge_android.c +++ b/android/edge_android.c @@ -19,65 +19,14 @@ #include "../n2n.h" #ifdef __ANDROID_NDK__ -#include "edge_android.h" +#include #include #define N2N_NETMASK_STR_SIZE 16 /* dotted decimal 12 numbers + 3 dots */ #define N2N_MACNAMSIZ 18 /* AA:BB:CC:DD:EE:FF + NULL*/ #define N2N_IF_MODE_SIZE 16 /* static | dhcp */ -/* *************************************************** */ - -#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) */ +n2n_edge_status_t* g_status; /* ***************************************************** */ @@ -98,201 +47,169 @@ static void send_grat_arps(n2n_edge_t * eee,) { * return 0 on success and -1 on error */ static int scan_address(char * ip_addr, size_t addr_size, - char * ip_mode, size_t mode_size, - const char * s) { - int retval = -1; - char * p; + char * ip_mode, size_t mode_size, + const char * s) { + int retval = -1; + char * p; - if((NULL == s) || (NULL == ip_addr)) + if((NULL == s) || (NULL == ip_addr)) { - return -1; + return -1; } - memset(ip_addr, 0, addr_size); + memset(ip_addr, 0, addr_size); - p = strpbrk(s, ":"); + p = strpbrk(s, ":"); - if(p) + if(p) { - /* colon is present */ - if(ip_mode) + /* colon is present */ + if(ip_mode) { - size_t end=0; + size_t end=0; - memset(ip_mode, 0, mode_size); - end = MIN(p-s, (ssize_t)(mode_size-1)); /* ensure NULL term */ - strncpy(ip_mode, s, end); - strncpy(ip_addr, p+1, addr_size-1); /* ensure NULL term */ - retval = 0; + memset(ip_mode, 0, mode_size); + end = MIN(p-s, (ssize_t)(mode_size-1)); /* ensure NULL term */ + strncpy(ip_mode, s, end); + strncpy(ip_addr, p+1, addr_size-1); /* ensure NULL term */ + retval = 0; } } - else + else { - /* colon is not present */ - strncpy(ip_addr, s, addr_size); + /* colon is not present */ + strncpy(ip_addr, s, addr_size); } - return retval; + return retval; } /* *************************************************** */ -//TODO use new API -int start_edge(const n2n_edge_cmd_t* cmd) +static const char *random_device_mac(void) +{ + const char key[] = "0123456789abcdef"; + static char mac[18]; + int i; + + srand(getpid()); + for (i = 0; i < sizeof(mac) - 1; ++i) { + if ((i + 1) % 3 == 0) { + mac[i] = ':'; + continue; + } + mac[i] = key[random() % sizeof(key)]; + } + mac[sizeof(mac) - 1] = '\0'; + return mac; +} + +/* *************************************************** */ + +int start_edge_v2(n2n_edge_status_t* status) { int keep_on_running = 0; - int local_port = 0 /* any port */; char tuntap_dev_name[N2N_IFNAMSIZ] = "tun0"; char ip_mode[N2N_IF_MODE_SIZE]="static"; char ip_addr[N2N_NETMASK_STR_SIZE] = ""; char netmask[N2N_NETMASK_STR_SIZE]="255.255.255.0"; char device_mac[N2N_MACNAMSIZ]=""; char * encrypt_key=NULL; - n2n_edge_t eee; + struct in_addr gateway_ip = {0}; + n2n_edge_conf_t conf; + n2n_edge_t *eee = NULL; int i; + tuntap_dev dev; - keep_on_running = 0; - pthread_mutex_lock(&status.mutex); - status.is_running = keep_on_running; - pthread_mutex_unlock(&status.mutex); - report_edge_status(); - if (!cmd) { + if (!status) { traceEvent( TRACE_ERROR, "Empty cmd struct" ); return 1; } - - traceLevel = cmd->trace_vlevel; - 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" ); - return 1; - } - memset(&(eee.supernode), 0, sizeof(eee.supernode)); - eee.supernode.family = AF_INET; + g_status = status; + n2n_edge_cmd_t* cmd = &status->cmd; if (cmd->vpn_fd < 0) { traceEvent(TRACE_ERROR, "VPN socket is invalid."); return 1; } - eee.device.fd = cmd->vpn_fd; - if (cmd->enc_key) - { - encrypt_key = strdup(cmd->enc_key); + + pthread_mutex_lock(&g_status->mutex); + g_status->running_status = EDGE_STAT_CONNECTING; + pthread_mutex_unlock(&g_status->mutex); + g_status->report_edge_status(); + + edge_init_conf_defaults(&conf); + + /* Load the configuration */ + strncpy((char *)conf.community_name, cmd->community, N2N_COMMUNITY_SIZE-1); + + if(cmd->enc_key && cmd->enc_key[0]) { + conf.transop_id = N2N_TRANSFORM_ID_TWOFISH; + conf.encrypt_key = strdup(cmd->enc_key); traceEvent(TRACE_DEBUG, "encrypt_key = '%s'\n", encrypt_key); } - if (cmd->ip_addr[0] != '\0') - { - scan_address(ip_addr, N2N_NETMASK_STR_SIZE, - ip_mode, N2N_IF_MODE_SIZE, - cmd->ip_addr); - } - else - { - traceEvent(TRACE_ERROR, "Ip address is not set."); - free(encrypt_key); - return 1; - } - if (cmd->community[0] != '\0') - { - strncpy((char *)eee.community_name, cmd->community, N2N_COMMUNITY_SIZE); - } - else - { - traceEvent(TRACE_ERROR, "Community is not set."); - free(encrypt_key); - return 1; - } - eee.drop_multicast = cmd->drop_multicast == 0 ? 0 : 1; - if (cmd->mac_addr[0] != '\0') - { - strncpy(device_mac, cmd->mac_addr, N2N_MACNAMSIZ); - } - else - { - strncpy(device_mac, random_device_mac(), N2N_MACNAMSIZ); - traceEvent(TRACE_DEBUG, "random device mac: %s\n", device_mac); - } - eee.allow_routing = cmd->allow_routing == 0 ? 0 : 1; + scan_address(ip_addr, N2N_NETMASK_STR_SIZE, + ip_mode, N2N_IF_MODE_SIZE, + cmd->ip_addr); + + dev.fd = cmd->vpn_fd; + + conf.drop_multicast = cmd->drop_multicast == 0 ? 0 : 1; + conf.allow_routing = cmd->allow_routing == 0 ? 0 : 1; + conf.dyn_ip_mode = (strcmp("dhcp", ip_mode) == 0) ? 1 : 0; + for (i = 0; i < N2N_EDGE_NUM_SUPERNODES && i < EDGE_CMD_SUPERNODES_NUM; ++i) { if (cmd->supernodes[i][0] != '\0') { - strncpy(eee.sn_ip_array[eee.sn_num], cmd->supernodes[i], N2N_EDGE_SN_HOST_SIZE); - traceEvent(TRACE_DEBUG, "Adding supernode[%u] = %s\n", (unsigned int)eee.sn_num, (eee.sn_ip_array[eee.sn_num])); - ++eee.sn_num; + strncpy(conf.sn_ip_array[conf.sn_num], cmd->supernodes[i], N2N_EDGE_SN_HOST_SIZE); + traceEvent(TRACE_DEBUG, "Adding supernode[%u] = %s\n", (unsigned int)conf.sn_num, (conf.sn_ip_array[conf.sn_num])); + ++conf.sn_num; } } - eee.re_resolve_supernode_ip = cmd->re_resolve_supernode_ip == 0 ? 0 : 1; + if (cmd->ip_netmask[0] != '\0') - { strncpy(netmask, cmd->ip_netmask, N2N_NETMASK_STR_SIZE); + + if (cmd->gateway_ip[0] != '\0') + inet_aton(cmd->gateway_ip, &gateway_ip); + + if (cmd->mac_addr[0] != '\0') + strncpy(device_mac, cmd->mac_addr, N2N_MACNAMSIZ); + else { + strncpy(device_mac, random_device_mac(), N2N_MACNAMSIZ); + traceEvent(TRACE_DEBUG, "random device mac: %s\n", device_mac); } - for (i=0; i< N2N_EDGE_NUM_SUPERNODES; ++i ) - { - traceEvent(TRACE_NORMAL, "supernode %u => %s\n", i, (eee.sn_ip_array[i])); + if(edge_verify_conf(&conf) != 0) { + if(conf.encrypt_key) free(conf.encrypt_key); + traceEvent(TRACE_ERROR, "Bad configuration"); + return 1; } - supernode2addr(&(eee.supernode), eee.sn_ip_array[eee.sn_idx]); - if (encrypt_key == NULL) - { - traceEvent(TRACE_WARNING, "Encryption is disabled in edge."); - eee.null_transop = 1; - } - if (0 == strcmp("dhcp", ip_mode)) - { - traceEvent(TRACE_NORMAL, "Dynamic IP address assignment enabled."); - eee.dyn_ip_mode = 1; - } - else - { - traceEvent(TRACE_NORMAL, "ip_mode='%s'", ip_mode); - } - if(tuntap_open(&(eee.device), tuntap_dev_name, ip_mode, ip_addr, netmask, device_mac, cmd->mtu) < 0) - { + + /* Open the TAP device */ + if(tuntap_open(&dev, tuntap_dev_name, ip_mode, ip_addr, netmask, device_mac, cmd->mtu) < 0) { traceEvent(TRACE_ERROR, "Failed in tuntap_open"); free(encrypt_key); return 1; } - if(local_port > 0) - { - traceEvent(TRACE_NORMAL, "Binding to local port %d", (signed int)local_port); - } - if (encrypt_key) - { - if(edge_init_twofish(&eee, (uint8_t *)(encrypt_key), strlen(encrypt_key)) < 0) - { - traceEvent(TRACE_ERROR, "twofish setup failed.\n"); - free(encrypt_key); - return 1; - } - free(encrypt_key); - encrypt_key = NULL; - } - /* else run in NULL mode */ - eee.udp_sock = open_socket(local_port, 1 /*bind ANY*/ ); - if(eee.udp_sock < 0) - { - traceEvent(TRACE_ERROR, "Failed to bind main UDP port %u", (signed int)local_port); - return 1; - } - eee.udp_mgmt_sock = open_socket(N2N_EDGE_MGMT_PORT, 0 /* bind LOOPBACK*/ ); - if(eee.udp_mgmt_sock < 0) - { - traceEvent( TRACE_ERROR, "Failed to bind management UDP port %u", (unsigned int)N2N_EDGE_MGMT_PORT ); + + /* Start n2n */ + eee = edge_init(&dev, &conf, &i); + + if(eee == NULL) { + traceEvent( TRACE_ERROR, "Failed in edge_init" ); return 1; } + /* Set runtime information */ + eee->gateway_ip = gateway_ip.s_addr; + /* set host addr, netmask, mac addr for UIP and init arp*/ { int match, i; - u8_t ip[4]; + int ip[4]; uip_ipaddr_t ipaddr; struct uip_eth_addr eaddr; @@ -311,7 +228,7 @@ int start_edge(const n2n_edge_cmd_t* cmd) uip_ipaddr(ipaddr, ip[0], ip[1], ip[2], ip[3]); uip_setnetmask(ipaddr); for (i = 0; i < 6; ++i) { - eaddr.addr[i] = eee.device.mac_addr[i]; + eaddr.addr[i] = eee->device.mac_addr[i]; } uip_setethaddr(eaddr); @@ -319,16 +236,27 @@ int start_edge(const n2n_edge_cmd_t* cmd) } keep_on_running = 1; - pthread_mutex_lock(&status.mutex); - status.is_running = keep_on_running; - pthread_mutex_unlock(&status.mutex); - report_edge_status(); + pthread_mutex_lock(&g_status->mutex); + g_status->running_status = EDGE_STAT_CONNECTED; + pthread_mutex_unlock(&g_status->mutex); + g_status->report_edge_status(); traceEvent(TRACE_NORMAL, "edge started"); - return run_edge_loop(&eee, &keep_on_running); + update_supernode_reg(eee, time(NULL)); + + run_edge_loop(eee, &keep_on_running); + + /* Cleanup */ + edge_term(eee); + tuntap_close(&dev); + edge_term_conf(&conf); + + traceEvent(TRACE_NORMAL, "Edge stopped"); + + return 0; } -int stop_edge(void) +int stop_edge_v2(void) { // quick stop int fd = open_socket(0, 0 /* bind LOOPBACK*/ ); @@ -341,12 +269,12 @@ int stop_edge(void) peer_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); peer_addr.sin_port = htons(N2N_EDGE_MGMT_PORT); sendto(fd, "stop", 4, 0, (struct sockaddr *)&peer_addr, sizeof(struct sockaddr_in)); - close(fd); + close(fd); - pthread_mutex_lock(&status.mutex); - status.is_running = 0; - pthread_mutex_unlock(&status.mutex); - report_edge_status(); + pthread_mutex_lock(&g_status->mutex); + g_status->running_status = EDGE_STAT_DISCONNECT; + pthread_mutex_unlock(&g_status->mutex); + g_status->report_edge_status(); return 0; } diff --git a/android/edge_android.h b/android/edge_android.h deleted file mode 100644 index d7dc503..0000000 --- a/android/edge_android.h +++ /dev/null @@ -1,64 +0,0 @@ -// -// Created by switchwang(https://github.com/switch-st) on 2018-04-13. -// - -#ifndef _EDGE_ANDROID_H_ -#define _EDGE_ANDROID_H_ - -#ifdef __ANDROID_NDK__ - -#include "../n2n.h" -#include - -#define EDGE_CMD_IPSTR_SIZE 16 -#define EDGE_CMD_SUPERNODES_NUM 2 -#define EDGE_CMD_SN_HOST_SIZE 48 -#define EDGE_CMD_MACNAMSIZ 18 - - -typedef struct n2n_edge_cmd_st -{ - char ip_addr[EDGE_CMD_IPSTR_SIZE]; - char ip_netmask[EDGE_CMD_IPSTR_SIZE]; - char supernodes[EDGE_CMD_SUPERNODES_NUM][EDGE_CMD_SN_HOST_SIZE]; - char community[N2N_COMMUNITY_SIZE]; - char* enc_key; - char* enc_key_file; - char mac_addr[EDGE_CMD_MACNAMSIZ]; - unsigned int mtu; - int re_resolve_supernode_ip; - unsigned int local_port; - int allow_routing; - int drop_multicast; - int trace_vlevel; - int vpn_fd; -} n2n_edge_cmd_t; - -typedef struct n2n_edge_status_st -{ - pthread_mutex_t mutex; - uint8_t is_running; -} n2n_edge_status; - -#define INIT_EDGE_CMD(cmd) do {\ - memset(&(cmd), 0, sizeof((cmd))); \ - (cmd).enc_key = NULL; \ - (cmd).enc_key_file = NULL; \ - (cmd).mtu = 1400; \ - (cmd).re_resolve_supernode_ip = 0;\ - (cmd).local_port = 0; \ - (cmd).allow_routing = 0; \ - (cmd).drop_multicast = 1; \ - (cmd).trace_vlevel = 2; \ - (cmd).vpn_fd = -1; \ -} while (0); - -n2n_edge_status status; - -int start_edge(const n2n_edge_cmd_t* cmd); -int stop_edge(void); -void report_edge_status(void); - -#endif /* __ANDROID_NDK__ */ - -#endif //_EDGE_ANDROID_H_ diff --git a/android/tuntap_android.c b/android/tuntap_android.c index 14548e0..5a1c711 100644 --- a/android/tuntap_android.c +++ b/android/tuntap_android.c @@ -57,7 +57,7 @@ int tuntap_open(tuntap_dev *device, device->ip_addr = inet_addr(device_ip); device->device_mask = inet_addr(device_mask); device->mtu = mtu; - strncpy(device->dev_name, dev, MIN(IFNAMSIZ, N2N_IFNAMSIZ)); + strncpy(device->dev_name, dev, N2N_IFNAMSIZ); return device->fd; } diff --git a/edge_utils.c b/edge_utils.c index 825b8ef..0fad3d2 100644 --- a/edge_utils.c +++ b/edge_utils.c @@ -31,8 +31,8 @@ #endif #ifdef __ANDROID_NDK__ -#include "android/edge_android.h" #include +#include #endif /* __ANDROID_NDK__ */ @@ -134,6 +134,11 @@ struct n2n_edge { int multicast_joined; /**< 1 if the group has been joined.*/ #endif +#ifdef __ANDROID_NDK__ + uint32_t gateway_ip; /**< The IP address of the gateway */ + n2n_mac_t gateway_mac; /**< The MAC address of the gateway */ +#endif + /* Peers */ struct peer_info * known_peers; /**< Edges we are connected to. */ struct peer_info * pending_peers; /**< Edges we have tried to register with. */ @@ -281,9 +286,11 @@ n2n_edge_t* edge_init(const tuntap_dev *dev, const n2n_edge_conf_t *conf, int *r rc = n2n_transop_cc20_init(&eee->conf, &eee->transop); break; #endif +#ifndef __ANDROID_NDK__ case N2N_TRANSFORM_ID_SPECK: rc = n2n_transop_speck_init(&eee->conf, &eee->transop); break; +#endif default: rc = n2n_transop_null_init(&eee->conf, &eee->transop); } @@ -642,6 +649,7 @@ int is_empty_ip_address(const n2n_sock_t * sock) { /* ************************************** */ static n2n_mac_t broadcast_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; +static n2n_mac_t null_mac = {0, 0, 0, 0, 0, 0}; /** Check if a known peer socket has changed and possibly register again. */ @@ -916,6 +924,17 @@ static void update_supernode_reg(n2n_edge_t * eee, time_t nowTime) { traceEvent(TRACE_WARNING, "Supernode not responding, now trying %s", supernode_ip(eee)); +#ifdef __ANDROID_NDK__ + int change = 0; + pthread_mutex_lock(&g_status->mutex); + change = g_status->running_status == EDGE_STAT_SUPERNODE_DISCONNECT ? 0 : 1; + g_status->running_status = EDGE_STAT_SUPERNODE_DISCONNECT; + pthread_mutex_unlock(&g_status->mutex); + if (change) { + g_status->report_edge_status(); + } +#endif /* #ifdef __ANDROID_NDK__ */ + eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS; } else @@ -1094,6 +1113,19 @@ static int handle_PACKET(n2n_edge_t * eee, } } +#ifdef __ANDROID_NDK__ + if((psize >= 36) && + (ntohs(*((uint16_t*)ð_payload[12])) == 0x0806) && /* ARP */ + (ntohs(*((uint16_t*)ð_payload[20])) == 0x0002) && /* REPLY */ + (!memcmp(ð_payload[28], &eee->gateway_ip, 4))) { /* From gateway */ + memcpy(eee->gateway_mac, ð_payload[22], 6); + + traceEvent(TRACE_INFO, "Gateway MAC: %02X:%02X:%02X:%02X:%02X:%02X", + eee->gateway_mac[0], eee->gateway_mac[1], eee->gateway_mac[2], + eee->gateway_mac[3], eee->gateway_mac[4], eee->gateway_mac[5]); + } +#endif + /* Write ethernet packet to tap device. */ traceEvent(TRACE_DEBUG, "sending to TAP %u", (unsigned int)eth_size); data_sent_len = tuntap_write(&(eee->device), eth_payload, eth_size); @@ -1383,6 +1415,13 @@ static void send_packet2net(n2n_edge_t * eee, ether_hdr_t eh; +#ifdef __ANDROID_NDK__ + if(!memcmp(tap_pkt, null_mac, 6)) { + traceEvent(TRACE_DEBUG, "Detected packet for the gateway"); + memcpy(tap_pkt, eee->gateway_mac, 6); + } +#endif + /* tap_pkt is not aligned so we have to copy to aligned memory */ memcpy(&eh, tap_pkt, sizeof(ether_hdr_t)); @@ -1554,6 +1593,57 @@ static void readFromTAPSocket(n2n_edge_t * eee) { /* ************************************** */ +#ifdef __ANDROID_NDK__ + +static char arp_packet[] = { + 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 */ +}; + +/* ************************************** */ + +static int build_unicast_arp(char *buffer, size_t buffer_len, uint32_t target, tuntap_dev *device) { + if(buffer_len < sizeof(arp_packet)) return(-1); + + memcpy(buffer, arp_packet, sizeof(arp_packet)); + memcpy(&buffer[6], device->mac_addr, 6); + memcpy(&buffer[22], device->mac_addr, 6); + memcpy(&buffer[28], &device->ip_addr, 4); + memcpy(&buffer[32], broadcast_mac, 6); + memcpy(&buffer[38], &target, 4); + return(sizeof(arp_packet)); +} + +/* ************************************** */ + +/** Called periodically to update the gateway MAC address. The ARP reply packet + is handled in handle_PACKET . */ + +static void update_gateway_mac(n2n_edge_t *eee) { + if(eee->gateway_ip != 0) { + size_t len; + char buffer[48]; + + len = build_unicast_arp(buffer, sizeof(buffer), eee->gateway_ip, &eee->device); + traceEvent(TRACE_DEBUG, "Updating gateway mac"); + send_packet2net(eee, (uint8_t*)buffer, len); + } +} + +#endif + +/* ************************************** */ + #ifdef WIN32 struct tunread_arg { @@ -1780,6 +1870,19 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) { eee->sn_wait=0; eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS; /* refresh because we got a response */ +#ifdef __ANDROID_NDK__ + int change = 0; + pthread_mutex_lock(&g_status->mutex); + change = g_status->running_status == EDGE_STAT_CONNECTED ? 0 : 1; + g_status->running_status = EDGE_STAT_CONNECTED; + pthread_mutex_unlock(&g_status->mutex); + if (change) { + g_status->report_edge_status(); + } + + update_gateway_mac(eee); +#endif /* #ifdef __ANDROID_NDK__ */ + /* NOTE: the register_interval should be chosen by the edge node * based on its NAT configuration. */ //eee->conf.register_interval = ra.lifetime; @@ -2489,3 +2592,9 @@ quick_edge_init_end: tuntap_close(&tuntap); return(rv); } + +/* ************************************** */ + +#ifdef __ANDROID_NDK__ +#include "android/edge_android.c" +#endif diff --git a/n2n.c b/n2n.c index b3479ce..c7cc414 100644 --- a/n2n.c +++ b/n2n.c @@ -22,6 +22,10 @@ #include +#ifdef __ANDROID_NDK__ +#include +#endif + #define PURGE_REGISTRATION_FREQUENCY 30 #define REGISTRATION_TIMEOUT 60 @@ -31,6 +35,47 @@ static const uint8_t ipv6_multicast_addr[6] = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x /* ************************************** */ +#ifdef __ANDROID_NDK__ + +static int protect_socket(int sock) { + JNIEnv *env = NULL; + + if(!g_status) + return(-1); + + if ((*g_status->jvm)->GetEnv(g_status->jvm, &env, JNI_VERSION_1_1) != JNI_OK || !env) { + traceEvent(TRACE_ERROR, "GetEnv failed"); + return(-1); + } + + jclass vpn_service_cls = (*env)->GetObjectClass(env, g_status->jobj_service); + + if(!vpn_service_cls) { + traceEvent(TRACE_ERROR, "GetObjectClass(VpnService) failed"); + return(-1); + } + + /* Call VpnService protect */ + jmethodID midProtect = (*env)->GetMethodID(env, vpn_service_cls, "protect", "(I)Z"); + if(!midProtect) { + traceEvent(TRACE_ERROR, "Could not resolve VpnService::protect"); + return(-1); + } + + jboolean isProtected = (*env)->CallBooleanMethod(env, g_status->jobj_service, midProtect, sock); + + if(!isProtected) { + traceEvent(TRACE_ERROR, "VpnService::protect failed"); + return(-1); + } + + return(0); +} + +#endif + +/* ************************************** */ + SOCKET open_socket(int local_port, int bind_any) { SOCKET sock_fd; struct sockaddr_in local_address; @@ -59,6 +104,11 @@ SOCKET open_socket(int local_port, int bind_any) { return(-1); } +#ifdef __ANDROID_NDK__ + /* Protect the socket so that the supernode traffic won't go inside the n2n VPN */ + protect_socket(sock_fd); +#endif + return(sock_fd); } diff --git a/n2n.h b/n2n.h index 7041fa3..cf7b6c7 100644 --- a/n2n.h +++ b/n2n.h @@ -108,8 +108,12 @@ typedef struct ether_hdr ether_hdr_t; #include #include #include + +#ifdef N2N_HAVE_AES #include #include +#endif + #include "minilzo.h" #define closesocket(a) close(a) diff --git a/speck.c b/speck.c index 23aefd7..c929f08 100644 --- a/speck.c +++ b/speck.c @@ -6,6 +6,8 @@ #include #include +#ifndef __ANDROID_NDK__ + #include "speck.h" @@ -687,3 +689,5 @@ int speck_test () { fprintf (stdout, "SPECK SELF TEST RESULT: %u\n", speck_test (0,NULL)); } */ + +#endif \ No newline at end of file