mirror of
https://github.com/ntop/n2n.git
synced 2024-09-20 00:51:10 +02:00
Merge pull request #259 from emanuele-f/hin2n_android
Compilation fixes for hin2n
This commit is contained in:
commit
590800c996
|
@ -16,68 +16,17 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../n2n.h"
|
#include "n2n.h"
|
||||||
|
|
||||||
#ifdef __ANDROID_NDK__
|
#ifdef __ANDROID_NDK__
|
||||||
#include "edge_android.h"
|
#include <edge_jni/edge_jni.h>
|
||||||
#include <tun2tap/tun2tap.h>
|
#include <tun2tap/tun2tap.h>
|
||||||
|
|
||||||
#define N2N_NETMASK_STR_SIZE 16 /* dotted decimal 12 numbers + 3 dots */
|
#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_MACNAMSIZ 18 /* AA:BB:CC:DD:EE:FF + NULL*/
|
||||||
#define N2N_IF_MODE_SIZE 16 /* static | dhcp */
|
#define N2N_IF_MODE_SIZE 16 /* static | dhcp */
|
||||||
|
|
||||||
/* *************************************************** */
|
n2n_edge_status_t* g_status;
|
||||||
|
|
||||||
#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) */
|
|
||||||
|
|
||||||
/* ***************************************************** */
|
/* ***************************************************** */
|
||||||
|
|
||||||
|
@ -137,162 +86,130 @@ static int scan_address(char * ip_addr, size_t addr_size,
|
||||||
|
|
||||||
/* *************************************************** */
|
/* *************************************************** */
|
||||||
|
|
||||||
//TODO use new API
|
static const char *random_device_mac(void)
|
||||||
int start_edge(const n2n_edge_cmd_t* cmd)
|
{
|
||||||
|
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 keep_on_running = 0;
|
||||||
int local_port = 0 /* any port */;
|
|
||||||
char tuntap_dev_name[N2N_IFNAMSIZ] = "tun0";
|
char tuntap_dev_name[N2N_IFNAMSIZ] = "tun0";
|
||||||
char ip_mode[N2N_IF_MODE_SIZE]="static";
|
char ip_mode[N2N_IF_MODE_SIZE]="static";
|
||||||
char ip_addr[N2N_NETMASK_STR_SIZE] = "";
|
char ip_addr[N2N_NETMASK_STR_SIZE] = "";
|
||||||
char netmask[N2N_NETMASK_STR_SIZE]="255.255.255.0";
|
char netmask[N2N_NETMASK_STR_SIZE]="255.255.255.0";
|
||||||
char device_mac[N2N_MACNAMSIZ]="";
|
char device_mac[N2N_MACNAMSIZ]="";
|
||||||
char * encrypt_key=NULL;
|
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;
|
int i;
|
||||||
|
tuntap_dev dev;
|
||||||
|
|
||||||
keep_on_running = 0;
|
if (!status) {
|
||||||
pthread_mutex_lock(&status.mutex);
|
|
||||||
status.is_running = keep_on_running;
|
|
||||||
pthread_mutex_unlock(&status.mutex);
|
|
||||||
report_edge_status();
|
|
||||||
if (!cmd) {
|
|
||||||
traceEvent( TRACE_ERROR, "Empty cmd struct" );
|
traceEvent( TRACE_ERROR, "Empty cmd struct" );
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
g_status = status;
|
||||||
traceLevel = cmd->trace_vlevel;
|
n2n_edge_cmd_t* cmd = &status->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" );
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
memset(&(eee.supernode), 0, sizeof(eee.supernode));
|
|
||||||
eee.supernode.family = AF_INET;
|
|
||||||
|
|
||||||
if (cmd->vpn_fd < 0) {
|
if (cmd->vpn_fd < 0) {
|
||||||
traceEvent(TRACE_ERROR, "VPN socket is invalid.");
|
traceEvent(TRACE_ERROR, "VPN socket is invalid.");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
eee.device.fd = cmd->vpn_fd;
|
|
||||||
if (cmd->enc_key)
|
pthread_mutex_lock(&g_status->mutex);
|
||||||
{
|
g_status->running_status = EDGE_STAT_CONNECTING;
|
||||||
encrypt_key = strdup(cmd->enc_key);
|
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);
|
traceEvent(TRACE_DEBUG, "encrypt_key = '%s'\n", encrypt_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd->ip_addr[0] != '\0')
|
|
||||||
{
|
|
||||||
scan_address(ip_addr, N2N_NETMASK_STR_SIZE,
|
scan_address(ip_addr, N2N_NETMASK_STR_SIZE,
|
||||||
ip_mode, N2N_IF_MODE_SIZE,
|
ip_mode, N2N_IF_MODE_SIZE,
|
||||||
cmd->ip_addr);
|
cmd->ip_addr);
|
||||||
}
|
|
||||||
else
|
dev.fd = cmd->vpn_fd;
|
||||||
{
|
|
||||||
traceEvent(TRACE_ERROR, "Ip address is not set.");
|
conf.drop_multicast = cmd->drop_multicast == 0 ? 0 : 1;
|
||||||
free(encrypt_key);
|
conf.allow_routing = cmd->allow_routing == 0 ? 0 : 1;
|
||||||
return 1;
|
conf.dyn_ip_mode = (strcmp("dhcp", ip_mode) == 0) ? 1 : 0;
|
||||||
}
|
|
||||||
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;
|
|
||||||
for (i = 0; i < N2N_EDGE_NUM_SUPERNODES && i < EDGE_CMD_SUPERNODES_NUM; ++i)
|
for (i = 0; i < N2N_EDGE_NUM_SUPERNODES && i < EDGE_CMD_SUPERNODES_NUM; ++i)
|
||||||
{
|
{
|
||||||
if (cmd->supernodes[i][0] != '\0')
|
if (cmd->supernodes[i][0] != '\0')
|
||||||
{
|
{
|
||||||
strncpy(eee.sn_ip_array[eee.sn_num], cmd->supernodes[i], N2N_EDGE_SN_HOST_SIZE);
|
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)eee.sn_num, (eee.sn_ip_array[eee.sn_num]));
|
traceEvent(TRACE_DEBUG, "Adding supernode[%u] = %s\n", (unsigned int)conf.sn_num, (conf.sn_ip_array[conf.sn_num]));
|
||||||
++eee.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);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i=0; i< N2N_EDGE_NUM_SUPERNODES; ++i )
|
if (cmd->ip_netmask[0] != '\0')
|
||||||
{
|
strncpy(netmask, cmd->ip_netmask, N2N_NETMASK_STR_SIZE);
|
||||||
traceEvent(TRACE_NORMAL, "supernode %u => %s\n", i, (eee.sn_ip_array[i]));
|
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
supernode2addr(&(eee.supernode), eee.sn_ip_array[eee.sn_idx]);
|
|
||||||
if (encrypt_key == NULL)
|
if(edge_verify_conf(&conf) != 0) {
|
||||||
{
|
if(conf.encrypt_key) free(conf.encrypt_key);
|
||||||
traceEvent(TRACE_WARNING, "Encryption is disabled in edge.");
|
traceEvent(TRACE_ERROR, "Bad configuration");
|
||||||
eee.null_transop = 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (0 == strcmp("dhcp", ip_mode))
|
|
||||||
{
|
/* Open the TAP device */
|
||||||
traceEvent(TRACE_NORMAL, "Dynamic IP address assignment enabled.");
|
if(tuntap_open(&dev, tuntap_dev_name, ip_mode, ip_addr, netmask, device_mac, cmd->mtu) < 0) {
|
||||||
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)
|
|
||||||
{
|
|
||||||
traceEvent(TRACE_ERROR, "Failed in tuntap_open");
|
traceEvent(TRACE_ERROR, "Failed in tuntap_open");
|
||||||
free(encrypt_key);
|
free(encrypt_key);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if(local_port > 0)
|
|
||||||
{
|
/* Start n2n */
|
||||||
traceEvent(TRACE_NORMAL, "Binding to local port %d", (signed int)local_port);
|
eee = edge_init(&dev, &conf, &i);
|
||||||
}
|
|
||||||
if (encrypt_key)
|
if(eee == NULL) {
|
||||||
{
|
traceEvent( TRACE_ERROR, "Failed in edge_init" );
|
||||||
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 );
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set runtime information */
|
||||||
|
eee->gateway_ip = gateway_ip.s_addr;
|
||||||
|
|
||||||
/* set host addr, netmask, mac addr for UIP and init arp*/
|
/* set host addr, netmask, mac addr for UIP and init arp*/
|
||||||
{
|
{
|
||||||
int match, i;
|
int match, i;
|
||||||
u8_t ip[4];
|
int ip[4];
|
||||||
uip_ipaddr_t ipaddr;
|
uip_ipaddr_t ipaddr;
|
||||||
struct uip_eth_addr eaddr;
|
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_ipaddr(ipaddr, ip[0], ip[1], ip[2], ip[3]);
|
||||||
uip_setnetmask(ipaddr);
|
uip_setnetmask(ipaddr);
|
||||||
for (i = 0; i < 6; ++i) {
|
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);
|
uip_setethaddr(eaddr);
|
||||||
|
|
||||||
|
@ -319,16 +236,27 @@ int start_edge(const n2n_edge_cmd_t* cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
keep_on_running = 1;
|
keep_on_running = 1;
|
||||||
pthread_mutex_lock(&status.mutex);
|
pthread_mutex_lock(&g_status->mutex);
|
||||||
status.is_running = keep_on_running;
|
g_status->running_status = EDGE_STAT_CONNECTED;
|
||||||
pthread_mutex_unlock(&status.mutex);
|
pthread_mutex_unlock(&g_status->mutex);
|
||||||
report_edge_status();
|
g_status->report_edge_status();
|
||||||
traceEvent(TRACE_NORMAL, "edge started");
|
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
|
// quick stop
|
||||||
int fd = open_socket(0, 0 /* bind LOOPBACK*/ );
|
int fd = open_socket(0, 0 /* bind LOOPBACK*/ );
|
||||||
|
@ -343,10 +271,10 @@ int stop_edge(void)
|
||||||
sendto(fd, "stop", 4, 0, (struct sockaddr *)&peer_addr, sizeof(struct sockaddr_in));
|
sendto(fd, "stop", 4, 0, (struct sockaddr *)&peer_addr, sizeof(struct sockaddr_in));
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
pthread_mutex_lock(&status.mutex);
|
pthread_mutex_lock(&g_status->mutex);
|
||||||
status.is_running = 0;
|
g_status->running_status = EDGE_STAT_DISCONNECT;
|
||||||
pthread_mutex_unlock(&status.mutex);
|
pthread_mutex_unlock(&g_status->mutex);
|
||||||
report_edge_status();
|
g_status->report_edge_status();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 <pthread.h>
|
|
||||||
|
|
||||||
#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_
|
|
|
@ -15,7 +15,7 @@
|
||||||
* along with this program; if not, see <http://www.gnu.org/licenses/>
|
* along with this program; if not, see <http://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../n2n.h"
|
#include "n2n.h"
|
||||||
|
|
||||||
#ifdef __ANDROID_NDK__
|
#ifdef __ANDROID_NDK__
|
||||||
#include <tun2tap/tun2tap.h>
|
#include <tun2tap/tun2tap.h>
|
||||||
|
@ -57,7 +57,7 @@ int tuntap_open(tuntap_dev *device,
|
||||||
device->ip_addr = inet_addr(device_ip);
|
device->ip_addr = inet_addr(device_ip);
|
||||||
device->device_mask = inet_addr(device_mask);
|
device->device_mask = inet_addr(device_mask);
|
||||||
device->mtu = mtu;
|
device->mtu = mtu;
|
||||||
strncpy(device->dev_name, dev, MIN(IFNAMSIZ, N2N_IFNAMSIZ));
|
strncpy(device->dev_name, dev, N2N_IFNAMSIZ);
|
||||||
return device->fd;
|
return device->fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,8 +118,8 @@ typedef struct ether_hdr ether_hdr_t;
|
||||||
#undef N2N_HAVE_DAEMON
|
#undef N2N_HAVE_DAEMON
|
||||||
#undef N2N_HAVE_SETUID
|
#undef N2N_HAVE_SETUID
|
||||||
#undef N2N_CAN_NAME_IFACE
|
#undef N2N_CAN_NAME_IFACE
|
||||||
#include "android/edge_android.h"
|
|
||||||
#include <tun2tap/tun2tap.h>
|
#include <tun2tap/tun2tap.h>
|
||||||
|
#include <edge_jni/edge_jni.h>
|
||||||
#define ARP_PERIOD_INTERVAL (10) /* sec */
|
#define ARP_PERIOD_INTERVAL (10) /* sec */
|
||||||
#endif /* #ifdef __ANDROID_NDK__ */
|
#endif /* #ifdef __ANDROID_NDK__ */
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
# include <endian.h>
|
# include <endian.h>
|
||||||
# include <features.h>
|
# include <features.h>
|
||||||
/* See http://linux.die.net/man/3/endian */
|
/* See http://linux.die.net/man/3/endian */
|
||||||
# if defined(htobe16) && defined(htole16) && defined(be16toh) && defined(le16toh) && defined(htobe32) && defined(htole32) && defined(be32toh) && defined(htole32) && defined(htobe64) && defined(htole64) && defined(be64) && defined(le64)
|
# if defined(htobe16) && defined(htole16) && defined(be16toh) && defined(le16toh) && defined(htobe32) && defined(htole32) && defined(be32toh) && defined(htole32) && defined(htobe64) && defined(htole64) && defined(htobe64) && defined(be64toh) && defined(htole64) && defined(le64toh)
|
||||||
/* Do nothing. The macros we need already exist. */
|
/* Do nothing. The macros we need already exist. */
|
||||||
# elif !defined(__GLIBC__) || !defined(__GLIBC_MINOR__) || ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 9)))
|
# elif !defined(__GLIBC__) || !defined(__GLIBC_MINOR__) || ((__GLIBC__ < 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 9)))
|
||||||
# include <arpa/inet.h>
|
# include <arpa/inet.h>
|
||||||
|
|
109
src/edge_utils.c
109
src/edge_utils.c
|
@ -96,6 +96,11 @@ struct n2n_edge {
|
||||||
int multicast_joined; /**< 1 if the group has been joined.*/
|
int multicast_joined; /**< 1 if the group has been joined.*/
|
||||||
#endif
|
#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 */
|
/* Peers */
|
||||||
struct peer_info * known_peers; /**< Edges we are connected to. */
|
struct peer_info * known_peers; /**< Edges we are connected to. */
|
||||||
struct peer_info * pending_peers; /**< Edges we have tried to register with. */
|
struct peer_info * pending_peers; /**< Edges we have tried to register with. */
|
||||||
|
@ -243,9 +248,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);
|
rc = n2n_transop_cc20_init(&eee->conf, &eee->transop);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef __ANDROID_NDK__
|
||||||
case N2N_TRANSFORM_ID_SPECK:
|
case N2N_TRANSFORM_ID_SPECK:
|
||||||
rc = n2n_transop_speck_init(&eee->conf, &eee->transop);
|
rc = n2n_transop_speck_init(&eee->conf, &eee->transop);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
rc = n2n_transop_null_init(&eee->conf, &eee->transop);
|
rc = n2n_transop_null_init(&eee->conf, &eee->transop);
|
||||||
}
|
}
|
||||||
|
@ -610,6 +617,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 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.
|
/** Check if a known peer socket has changed and possibly register again.
|
||||||
*/
|
*/
|
||||||
|
@ -895,6 +903,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));
|
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;
|
eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1073,6 +1092,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. */
|
/* Write ethernet packet to tap device. */
|
||||||
traceEvent(TRACE_DEBUG, "sending to TAP %u", (unsigned int)eth_size);
|
traceEvent(TRACE_DEBUG, "sending to TAP %u", (unsigned int)eth_size);
|
||||||
data_sent_len = tuntap_write(&(eee->device), eth_payload, eth_size);
|
data_sent_len = tuntap_write(&(eee->device), eth_payload, eth_size);
|
||||||
|
@ -1362,6 +1394,13 @@ static void send_packet2net(n2n_edge_t * eee,
|
||||||
|
|
||||||
ether_hdr_t eh;
|
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 */
|
/* tap_pkt is not aligned so we have to copy to aligned memory */
|
||||||
memcpy(&eh, tap_pkt, sizeof(ether_hdr_t));
|
memcpy(&eh, tap_pkt, sizeof(ether_hdr_t));
|
||||||
|
|
||||||
|
@ -1534,6 +1573,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
|
||||||
|
|
||||||
|
/* ************************************** */
|
||||||
|
|
||||||
/** Read a datagram from the main UDP socket to the internet. */
|
/** Read a datagram from the main UDP socket to the internet. */
|
||||||
static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
n2n_common_t cmn; /* common fields in the packet header */
|
n2n_common_t cmn; /* common fields in the packet header */
|
||||||
|
@ -1732,6 +1822,19 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
|
||||||
eee->sn_wait=0;
|
eee->sn_wait=0;
|
||||||
eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS; /* refresh because we got a response */
|
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
|
/* NOTE: the register_interval should be chosen by the edge node
|
||||||
* based on its NAT configuration. */
|
* based on its NAT configuration. */
|
||||||
//eee->conf.register_interval = ra.lifetime;
|
//eee->conf.register_interval = ra.lifetime;
|
||||||
|
@ -2452,3 +2555,9 @@ int quick_edge_init(char *device_name, char *community_name,
|
||||||
tuntap_close(&tuntap);
|
tuntap_close(&tuntap);
|
||||||
return(rv);
|
return(rv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ************************************** */
|
||||||
|
|
||||||
|
#ifdef __ANDROID_NDK__
|
||||||
|
#include "../android/edge_android.c"
|
||||||
|
#endif
|
||||||
|
|
50
src/n2n.c
50
src/n2n.c
|
@ -22,6 +22,10 @@
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#ifdef __ANDROID_NDK__
|
||||||
|
#include <edge_jni/edge_jni.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define PURGE_REGISTRATION_FREQUENCY 30
|
#define PURGE_REGISTRATION_FREQUENCY 30
|
||||||
#define REGISTRATION_TIMEOUT 60
|
#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 open_socket(int local_port, int bind_any) {
|
||||||
SOCKET sock_fd;
|
SOCKET sock_fd;
|
||||||
struct sockaddr_in local_address;
|
struct sockaddr_in local_address;
|
||||||
|
@ -59,6 +104,11 @@ SOCKET open_socket(int local_port, int bind_any) {
|
||||||
return(-1);
|
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);
|
return(sock_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user