Browse Source

Minor cleanup

pull/282/head
Luca Deri 4 years ago
parent
commit
c6b7b67a6a
  1. 402
      android/edge_android.c
  2. 70
      src/edge_utils.c

402
android/edge_android.c

@ -49,235 +49,283 @@ n2n_edge_status_t* g_status;
static int scan_address(char * ip_addr, size_t addr_size, static int scan_address(char * ip_addr, size_t addr_size,
char * ip_mode, size_t mode_size, char * ip_mode, size_t mode_size,
const char * s) { const char * s) {
int retval = -1; int retval = -1;
char * p; 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 */ /* colon is present */
if(ip_mode) if(ip_mode)
{ {
size_t end=0; size_t end=0;
memset(ip_mode, 0, mode_size); memset(ip_mode, 0, mode_size);
end = MIN(p-s, (ssize_t)(mode_size-1)); /* ensure NULL term */ end = MIN(p-s, (ssize_t)(mode_size-1)); /* ensure NULL term */
strncpy(ip_mode, s, end); strncpy(ip_mode, s, end);
strncpy(ip_addr, p+1, addr_size-1); /* ensure NULL term */ strncpy(ip_addr, p+1, addr_size-1); /* ensure NULL term */
retval = 0; retval = 0;
} }
} }
else else
{ {
/* colon is not present */ /* colon is not present */
strncpy(ip_addr, s, addr_size); strncpy(ip_addr, s, addr_size);
} }
return retval; return retval;
} }
/* *************************************************** */ /* *************************************************** */
static const char *random_device_mac(void) static const char *random_device_mac(void)
{ {
const char key[] = "0123456789abcdef"; const char key[] = "0123456789abcdef";
static char mac[18]; static char mac[18];
int i; int i;
srand(getpid()); srand(getpid());
for (i = 0; i < sizeof(mac) - 1; ++i) { for (i = 0; i < sizeof(mac) - 1; ++i) {
if ((i + 1) % 3 == 0) { if ((i + 1) % 3 == 0) {
mac[i] = ':'; mac[i] = ':';
continue; continue;
}
mac[i] = key[random() % sizeof(key)];
} }
mac[sizeof(mac) - 1] = '\0'; mac[i] = key[random() % sizeof(key)];
return mac; }
mac[sizeof(mac) - 1] = '\0';
return mac;
} }
/* *************************************************** */ /* *************************************************** */
int start_edge_v2(n2n_edge_status_t* status) int start_edge_v2(n2n_edge_status_t* status)
{ {
int keep_on_running = 0; int keep_on_running = 0;
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;
struct in_addr gateway_ip = {0}; struct in_addr gateway_ip = {0};
n2n_edge_conf_t conf; n2n_edge_conf_t conf;
n2n_edge_t *eee = NULL; n2n_edge_t *eee = NULL;
int i; int i;
tuntap_dev dev; tuntap_dev dev;
if (!status) { if (!status) {
traceEvent( TRACE_ERROR, "Empty cmd struct" ); traceEvent( TRACE_ERROR, "Empty cmd struct" );
return 1; return 1;
} }
g_status = status; g_status = status;
n2n_edge_cmd_t* cmd = &status->cmd; n2n_edge_cmd_t* cmd = &status->cmd;
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;
} }
pthread_mutex_lock(&g_status->mutex); pthread_mutex_lock(&g_status->mutex);
g_status->running_status = EDGE_STAT_CONNECTING; g_status->running_status = EDGE_STAT_CONNECTING;
pthread_mutex_unlock(&g_status->mutex); pthread_mutex_unlock(&g_status->mutex);
g_status->report_edge_status(); g_status->report_edge_status();
edge_init_conf_defaults(&conf); edge_init_conf_defaults(&conf);
/* Load the configuration */ /* Load the configuration */
strncpy((char *)conf.community_name, cmd->community, N2N_COMMUNITY_SIZE-1); strncpy((char *)conf.community_name, cmd->community, N2N_COMMUNITY_SIZE-1);
if(cmd->enc_key && cmd->enc_key[0]) { if(cmd->enc_key && cmd->enc_key[0]) {
conf.transop_id = N2N_TRANSFORM_ID_TWOFISH; conf.transop_id = N2N_TRANSFORM_ID_TWOFISH;
conf.encrypt_key = strdup(cmd->enc_key); 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);
} }
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);
dev.fd = cmd->vpn_fd; dev.fd = cmd->vpn_fd;
conf.drop_multicast = cmd->drop_multicast == 0 ? 0 : 1; conf.drop_multicast = cmd->drop_multicast == 0 ? 0 : 1;
conf.allow_routing = cmd->allow_routing == 0 ? 0 : 1; conf.allow_routing = cmd->allow_routing == 0 ? 0 : 1;
conf.dyn_ip_mode = (strcmp("dhcp", ip_mode) == 0) ? 1 : 0; 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) 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(conf.sn_ip_array[conf.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)conf.sn_num, (conf.sn_ip_array[conf.sn_num])); traceEvent(TRACE_DEBUG, "Adding supernode[%u] = %s\n", (unsigned int)conf.sn_num, (conf.sn_ip_array[conf.sn_num]));
++conf.sn_num; ++conf.sn_num;
} }
} }
if (cmd->ip_netmask[0] != '\0') if (cmd->ip_netmask[0] != '\0')
strncpy(netmask, cmd->ip_netmask, N2N_NETMASK_STR_SIZE); strncpy(netmask, cmd->ip_netmask, N2N_NETMASK_STR_SIZE);
if (cmd->gateway_ip[0] != '\0') if (cmd->gateway_ip[0] != '\0')
inet_aton(cmd->gateway_ip, &gateway_ip); inet_aton(cmd->gateway_ip, &gateway_ip);
if (cmd->mac_addr[0] != '\0') if (cmd->mac_addr[0] != '\0')
strncpy(device_mac, cmd->mac_addr, N2N_MACNAMSIZ); strncpy(device_mac, cmd->mac_addr, N2N_MACNAMSIZ);
else { else {
strncpy(device_mac, random_device_mac(), N2N_MACNAMSIZ); strncpy(device_mac, random_device_mac(), N2N_MACNAMSIZ);
traceEvent(TRACE_DEBUG, "random device mac: %s\n", device_mac); traceEvent(TRACE_DEBUG, "random device mac: %s\n", device_mac);
}
if(edge_verify_conf(&conf) != 0) {
if(conf.encrypt_key) free(conf.encrypt_key);
traceEvent(TRACE_ERROR, "Bad configuration");
return 1;
}
/* 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;
}
/* 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;
int ip[4];
uip_ipaddr_t ipaddr;
struct uip_eth_addr eaddr;
match = sscanf(ip_addr, "%d.%d.%d.%d", ip, ip + 1, ip + 2, ip + 3);
if (match != 4) {
traceEvent(TRACE_ERROR, "scan ip failed, ip: %s", ip_addr);
return 1;
} }
uip_ipaddr(ipaddr, ip[0], ip[1], ip[2], ip[3]);
if(edge_verify_conf(&conf) != 0) { uip_sethostaddr(ipaddr);
if(conf.encrypt_key) free(conf.encrypt_key); match = sscanf(netmask, "%d.%d.%d.%d", ip, ip + 1, ip + 2, ip + 3);
traceEvent(TRACE_ERROR, "Bad configuration"); if (match != 4) {
return 1; traceEvent(TRACE_ERROR, "scan netmask error, ip: %s", netmask);
return 1;
} }
uip_ipaddr(ipaddr, ip[0], ip[1], ip[2], ip[3]);
/* Open the TAP device */ uip_setnetmask(ipaddr);
if(tuntap_open(&dev, tuntap_dev_name, ip_mode, ip_addr, netmask, device_mac, cmd->mtu) < 0) { for (i = 0; i < 6; ++i) {
traceEvent(TRACE_ERROR, "Failed in tuntap_open"); eaddr.addr[i] = eee->device.mac_addr[i];
free(encrypt_key);
return 1;
} }
uip_setethaddr(eaddr);
/* Start n2n */ uip_arp_init();
eee = edge_init(&dev, &conf, &i); }
if(eee == NULL) { keep_on_running = 1;
traceEvent( TRACE_ERROR, "Failed in edge_init" ); pthread_mutex_lock(&g_status->mutex);
return 1; g_status->running_status = EDGE_STAT_CONNECTED;
} pthread_mutex_unlock(&g_status->mutex);
g_status->report_edge_status();
traceEvent(TRACE_NORMAL, "edge started");
/* Set runtime information */ update_supernode_reg(eee, time(NULL));
eee->gateway_ip = gateway_ip.s_addr;
/* set host addr, netmask, mac addr for UIP and init arp*/ run_edge_loop(eee, &keep_on_running);
{
int match, i;
int ip[4];
uip_ipaddr_t ipaddr;
struct uip_eth_addr eaddr;
match = sscanf(ip_addr, "%d.%d.%d.%d", ip, ip + 1, ip + 2, ip + 3);
if (match != 4) {
traceEvent(TRACE_ERROR, "scan ip failed, ip: %s", ip_addr);
return 1;
}
uip_ipaddr(ipaddr, ip[0], ip[1], ip[2], ip[3]);
uip_sethostaddr(ipaddr);
match = sscanf(netmask, "%d.%d.%d.%d", ip, ip + 1, ip + 2, ip + 3);
if (match != 4) {
traceEvent(TRACE_ERROR, "scan netmask error, ip: %s", netmask);
return 1;
}
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];
}
uip_setethaddr(eaddr);
uip_arp_init(); /* Cleanup */
} edge_term(eee);
tuntap_close(&dev);
edge_term_conf(&conf);
keep_on_running = 1; traceEvent(TRACE_NORMAL, "Edge stopped");
pthread_mutex_lock(&g_status->mutex);
g_status->running_status = EDGE_STAT_CONNECTED; return 0;
pthread_mutex_unlock(&g_status->mutex); }
g_status->report_edge_status();
traceEvent(TRACE_NORMAL, "edge started"); int stop_edge_v2(void)
{
// quick stop
int fd = open_socket(0, 0 /* bind LOOPBACK*/ );
if (fd < 0) {
return 1;
}
struct sockaddr_in peer_addr;
peer_addr.sin_family = PF_INET;
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);
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;
}
update_supernode_reg(eee, time(NULL)); /* ************************************** */
run_edge_loop(eee, &keep_on_running); 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 */
};
/* Cleanup */ /* ************************************** */
edge_term(eee);
tuntap_close(&dev);
edge_term_conf(&conf);
traceEvent(TRACE_NORMAL, "Edge stopped"); 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);
return 0; 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));
} }
int stop_edge_v2(void) /* ************************************** */
{
// quick stop
int fd = open_socket(0, 0 /* bind LOOPBACK*/ );
if (fd < 0) {
return 1;
}
struct sockaddr_in peer_addr; /** Called periodically to update the gateway MAC address. The ARP reply packet
peer_addr.sin_family = PF_INET; is handled in handle_PACKET . */
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);
pthread_mutex_lock(&g_status->mutex); static void update_gateway_mac(n2n_edge_t *eee) {
g_status->running_status = EDGE_STAT_DISCONNECT; if(eee->gateway_ip != 0) {
pthread_mutex_unlock(&g_status->mutex); size_t len;
g_status->report_edge_status(); char buffer[48];
return 0; 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 __ANDROID_NDK__ */ #endif /* #ifdef __ANDROID_NDK__ */
/* ************************************** */ /* ************************************** */

70
src/edge_utils.c

@ -43,6 +43,12 @@ static void check_known_peer_sock_change(n2n_edge_t * eee,
/* ************************************** */ /* ************************************** */
#ifdef __ANDROID_NDK__
#include "../android/edge_android.c"
#endif
/* ************************************** */
int edge_verify_conf(const n2n_edge_conf_t *conf) { int edge_verify_conf(const n2n_edge_conf_t *conf) {
if(conf->community_name[0] == 0) if(conf->community_name[0] == 0)
return(-1); return(-1);
@ -320,12 +326,12 @@ static int is_valid_peer_sock(const n2n_sock_t *sock) {
case AF_INET: case AF_INET:
{ {
uint32_t *a = (uint32_t*)sock->addr.v4; uint32_t *a = (uint32_t*)sock->addr.v4;
if(*a != htonl(localhost_v4)) if(*a != htonl(localhost_v4))
return(1); return(1);
} }
break; break;
case AF_INET6: case AF_INET6:
if(memcmp(sock->addr.v6, localhost_v6, IPV6_SIZE)) if(memcmp(sock->addr.v6, localhost_v6, IPV6_SIZE))
return(1); return(1);
@ -1573,54 +1579,6 @@ 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
/* ************************************** */ /* ************************************** */
@ -1824,10 +1782,12 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
#ifdef __ANDROID_NDK__ #ifdef __ANDROID_NDK__
int change = 0; int change = 0;
pthread_mutex_lock(&g_status->mutex);
pthread_mutex_lock(&g_status->mutex);
change = g_status->running_status == EDGE_STAT_CONNECTED ? 0 : 1; change = g_status->running_status == EDGE_STAT_CONNECTED ? 0 : 1;
g_status->running_status = EDGE_STAT_CONNECTED; g_status->running_status = EDGE_STAT_CONNECTED;
pthread_mutex_unlock(&g_status->mutex); pthread_mutex_unlock(&g_status->mutex);
if (change) { if (change) {
g_status->report_edge_status(); g_status->report_edge_status();
} }
@ -2213,7 +2173,7 @@ static int rtattr_add(struct nlmsghdr *n, int maxlen, int type, const void *data
rta = NLMSG_TAIL(n); rta = NLMSG_TAIL(n);
rta->rta_type = type; rta->rta_type = type;
rta->rta_len = len; rta->rta_len = len;
if(alen) if(alen)
memcpy(RTA_DATA(rta), data, alen); memcpy(RTA_DATA(rta), data, alen);
@ -2390,7 +2350,7 @@ static int edge_init_routes(n2n_edge_t *eee, n2n_route_t *routes, uint16_t num_r
n2n_sock_t sn; n2n_sock_t sn;
n2n_route_t custom_route; n2n_route_t custom_route;
uint32_t *a; uint32_t *a;
if(eee->sn_route_to_clean) { if(eee->sn_route_to_clean) {
traceEvent(TRACE_ERROR, "Only one default gateway route allowed"); traceEvent(TRACE_ERROR, "Only one default gateway route allowed");
return(-1); return(-1);
@ -2557,7 +2517,3 @@ int quick_edge_init(char *device_name, char *community_name,
} }
/* ************************************** */ /* ************************************** */
#ifdef __ANDROID_NDK__
#include "../android/edge_android.c"
#endif

Loading…
Cancel
Save