Browse Source

Merge pull request #355 from fengdaolong/dev

Added DHCP function embedded in sn.
pull/357/head
Luca Deri 4 years ago
committed by GitHub
parent
commit
9928ccaeea
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 172
      include/n2n.h
  2. 9
      include/n2n_define.h
  3. 93
      include/n2n_wire.h
  4. 76
      src/edge.c
  5. 152
      src/edge_utils.c
  6. 4
      src/example_edge_embed.c
  7. 58
      src/n2n.c
  8. 165
      src/sn.c
  9. 337
      src/sn_utils.c
  10. 260
      src/wire.c
  11. 15
      win32/n2n_win32.h
  12. 7
      win32/winconfig.h

172
include/n2n.h

@ -36,8 +36,6 @@
/* Moved here to define _CRT_SECURE_NO_WARNINGS before all the including takes place */
#ifdef WIN32
#include "win32/n2n_win32.h"
#ifdef _MSC_VER
#include "config.h" /* Visual C++ */
#else
@ -171,12 +169,13 @@ typedef struct ether_hdr ether_hdr_t;
#ifndef WIN32
typedef struct tuntap_dev {
int fd;
int if_idx;
uint8_t mac_addr[6];
uint32_t ip_addr, device_mask;
uint16_t mtu;
char dev_name[N2N_IFNAMSIZ];
int fd;
int if_idx;
n2n_mac_t mac_addr;
uint32_t ip_addr;
uint32_t device_mask;
uint16_t mtu;
char dev_name[N2N_IFNAMSIZ];
} tuntap_dev;
#define SOCKET int
@ -192,26 +191,31 @@ typedef char ipstr_t[32];
/** Common type used to hold stringified MAC addresses. */
#define N2N_MACSTR_SIZE 32
typedef char macstr_t[N2N_MACSTR_SIZE];
typedef char dec_ip_str_t[N2N_NETMASK_STR_SIZE];
typedef char dec_ip_bit_str_t[N2N_NETMASK_STR_SIZE + 4];
struct peer_info {
n2n_mac_t mac_addr;
n2n_sock_t sock;
int timeout;
time_t last_seen;
time_t last_p2p;
time_t last_sent_query;
uint64_t last_valid_time_stamp;
UT_hash_handle hh; /* makes this structure hashable */
struct peer_info {
n2n_mac_t mac_addr;
n2n_ip_subnet_t dev_addr;
n2n_sock_t sock;
int timeout;
time_t last_seen;
time_t last_p2p;
time_t last_sent_query;
uint64_t last_valid_time_stamp;
UT_hash_handle hh; /* makes this structure hashable */
};
typedef struct speck_context_t he_context_t;
typedef char n2n_sn_name_t[N2N_EDGE_SN_HOST_SIZE];
typedef struct n2n_route {
in_addr_t net_addr;
int net_bitlen;
in_addr_t gateway;
in_addr_t net_addr;
uint8_t net_bitlen;
in_addr_t gateway;
} n2n_route_t;
typedef struct n2n_edge n2n_edge_t;
@ -253,8 +257,8 @@ typedef struct n2n_edge_callbacks {
typedef struct n2n_tuntap_priv_config {
char tuntap_dev_name[N2N_IFNAMSIZ];
char ip_mode[N2N_IF_MODE_SIZE];
char ip_addr[N2N_NETMASK_STR_SIZE];
char netmask[N2N_NETMASK_STR_SIZE];
dec_ip_str_t ip_addr;
dec_ip_str_t netmask;
char device_mac[N2N_MACNAMSIZ];
int mtu;
uint8_t got_s;
@ -267,30 +271,32 @@ typedef struct n2n_tuntap_priv_config {
/* *************************************************** */
typedef struct n2n_edge_conf {
n2n_sn_name_t sn_ip_array[N2N_EDGE_NUM_SUPERNODES];
n2n_route_t *routes; /**< Networks to route through n2n */
n2n_community_t community_name; /**< The community. 16 full octets. */
uint8_t header_encryption; /**< Header encryption indicator. */
he_context_t *header_encryption_ctx; /**< Header encryption cipher context. */
he_context_t *header_iv_ctx; /**< Header IV ecnryption cipher context, REMOVE as soon as seperte fileds for checksum and replay protection available */
n2n_transform_t transop_id; /**< The transop to use. */
uint16_t compression; /**< Compress outgoing data packets before encryption */
uint16_t num_routes; /**< Number of routes in routes */
uint8_t dyn_ip_mode; /**< Interface IP address is dynamically allocated, eg. DHCP. */
uint8_t allow_routing; /**< Accept packet no to interface address. */
uint8_t drop_multicast; /**< Multicast ethernet addresses. */
uint8_t disable_pmtu_discovery; /**< Disable the Path MTU discovery. */
uint8_t allow_p2p; /**< Allow P2P connection */
uint8_t sn_num; /**< Number of supernode addresses defined. */
uint8_t tos; /** TOS for sent packets */
char *encrypt_key;
int register_interval; /**< Interval for supernode registration, also used for UDP NAT hole punching. */
int register_ttl; /**< TTL for registration packet when UDP NAT hole punching through supernode. */
int local_port;
int mgmt_port;
n2n_sn_name_t sn_ip_array[N2N_EDGE_NUM_SUPERNODES];
n2n_route_t *routes; /**< Networks to route through n2n */
n2n_community_t community_name; /**< The community. 16 full octets. */
uint8_t header_encryption; /**< Header encryption indicator. */
he_context_t *header_encryption_ctx; /**< Header encryption cipher context. */
he_context_t *header_iv_ctx; /**< Header IV ecnryption cipher context, REMOVE as soon as seperte fileds for checksum and replay protection available */
n2n_transform_t transop_id; /**< The transop to use. */
uint16_t compression; /**< Compress outgoing data packets before encryption */
uint16_t num_routes; /**< Number of routes in routes */
uint8_t tuntap_ip_mode; /**< Interface IP address allocated mode, eg. DHCP. */
uint8_t allow_routing; /**< Accept packet no to interface address. */
uint8_t drop_multicast; /**< Multicast ethernet addresses. */
uint8_t disable_pmtu_discovery; /**< Disable the Path MTU discovery. */
uint8_t allow_p2p; /**< Allow P2P connection */
uint8_t sn_num; /**< Number of supernode addresses defined. */
uint8_t tos; /** TOS for sent packets */
char *encrypt_key;
int register_interval; /**< Interval for supernode registration, also used for UDP NAT hole punching. */
int register_ttl; /**< TTL for registration packet when UDP NAT hole punching through supernode. */
int local_port;
int mgmt_port;
} n2n_edge_conf_t;
struct n2n_edge_stats {
uint32_t tx_p2p;
uint32_t rx_p2p;
@ -304,44 +310,45 @@ struct n2n_edge {
n2n_edge_conf_t conf;
/* Status */
uint8_t sn_idx; /**< Currently active supernode. */
uint8_t sn_wait; /**< Whether we are waiting for a supernode response. */
size_t sup_attempts; /**< Number of remaining attempts to this supernode. */
tuntap_dev device; /**< All about the TUNTAP device */
n2n_trans_op_t transop; /**< The transop to use when encoding */
n2n_cookie_t last_cookie; /**< Cookie sent in last REGISTER_SUPER. */
n2n_route_t *sn_route_to_clean; /**< Supernode route to clean */
n2n_edge_callbacks_t cb; /**< API callbacks */
void *user_data; /**< Can hold user data */
uint64_t sn_last_valid_time_stamp;/*< last valid time stamp from supernode */
uint8_t sn_idx; /**< Currently active supernode. */
uint8_t sn_wait; /**< Whether we are waiting for a supernode response. */
size_t sup_attempts; /**< Number of remaining attempts to this supernode. */
tuntap_dev device; /**< All about the TUNTAP device */
n2n_trans_op_t transop; /**< The transop to use when encoding */
n2n_cookie_t last_cookie; /**< Cookie sent in last REGISTER_SUPER. */
n2n_route_t *sn_route_to_clean; /**< Supernode route to clean */
n2n_edge_callbacks_t cb; /**< API callbacks */
void *user_data; /**< Can hold user data */
uint64_t sn_last_valid_time_stamp;/**< last valid time stamp from supernode */
/* Sockets */
n2n_sock_t supernode;
int udp_sock;
int udp_mgmt_sock; /**< socket for status info. */
int udp_mgmt_sock; /**< socket for status info. */
#ifndef SKIP_MULTICAST_PEERS_DISCOVERY
n2n_sock_t multicast_peer; /**< Multicast peer group (for local edges) */
int udp_multicast_sock; /**< socket for local multicast registrations. */
int multicast_joined; /**< 1 if the group has been joined.*/
n2n_sock_t multicast_peer; /**< Multicast peer group (for local edges) */
int udp_multicast_sock; /**< socket for local multicast registrations. */
int multicast_joined; /**< 1 if the group has been joined.*/
#endif
/* Peers */
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 * known_peers; /**< Edges we are connected to. */
struct peer_info * pending_peers; /**< Edges we have tried to register with. */
/* Timers */
time_t last_register_req; /**< Check if time to re-register with super*/
time_t last_p2p; /**< Last time p2p traffic was received. */
time_t last_sup; /**< Last time a packet arrived from supernode. */
time_t start_time; /**< For calculating uptime */
/* Statistics */
struct n2n_edge_stats stats;
/* Tuntap config */
n2n_tuntap_priv_config_t tuntap_priv_conf;
time_t last_register_req; /**< Check if time to re-register with super*/
time_t last_p2p; /**< Last time p2p traffic was received. */
time_t last_sup; /**< Last time a packet arrived from supernode. */
time_t start_time; /**< For calculating uptime */
struct n2n_edge_stats stats; /**< Statistics */
n2n_tuntap_priv_config_t tuntap_priv_conf; /**< Tuntap config */
};
typedef struct sn_stats
{
size_t errors; /* Number of errors encountered. */
@ -365,21 +372,21 @@ struct sn_community
UT_hash_handle hh; /* makes this structure hashable */
};
typedef struct n2n_sn
{
time_t start_time; /* Used to measure uptime. */
sn_stats_t stats;
int daemon; /* If non-zero then daemonise. */
uint16_t lport; /* Local UDP port to bind to. */
uint16_t mport; /* Management UDP port to bind to. */
int sock; /* Main socket for UDP traffic with edges. */
int mgmt_sock; /* management socket. */
typedef struct n2n_sn {
time_t start_time; /* Used to measure uptime. */
sn_stats_t stats;
int daemon; /* If non-zero then daemonise. */
uint16_t lport; /* Local UDP port to bind to. */
uint16_t mport; /* Management UDP port to bind to. */
int sock; /* Main socket for UDP traffic with edges. */
int mgmt_sock; /* management socket. */
n2n_ip_subnet_t dhcp_addr; /* Address range of dhcp service. */
#ifndef WIN32
uid_t userid;
gid_t groupid;
#endif
int lock_communities; /* If true, only loaded communities can be used. */
struct sn_community *communities;
int lock_communities; /* If true, only loaded communities can be used. */
struct sn_community *communities;
} n2n_sn_t;
/* ************************************** */
@ -426,6 +433,8 @@ void tuntap_get_address(struct tuntap_dev *tuntap);
/* Utils */
char* intoa(uint32_t addr, char* buf, uint16_t buf_len);
uint32_t bitlen2mask(uint8_t bitlen);
uint8_t mask2bitlen(uint32_t mask);
char* macaddr_str(macstr_t buf, const n2n_mac_t mac);
int str2mac( uint8_t * outmac /* 6 bytes */, const char * s );
uint8_t is_multi_broadcast(const uint8_t * dest_mac);
@ -438,6 +447,7 @@ void print_edge_stats(const n2n_edge_t *eee);
/* Sockets */
char* sock_to_cstr( n2n_sock_str_t out,
const n2n_sock_t * sock );
char * ip_subnet_to_str(dec_ip_bit_str_t buf, const n2n_ip_subnet_t *ipaddr);
SOCKET open_socket(int local_port, int bind_any);
int sock_equal( const n2n_sock_t * a,
const n2n_sock_t * b );
@ -461,7 +471,9 @@ const n2n_edge_conf_t* edge_get_conf(const n2n_edge_t *eee);
void edge_term_conf(n2n_edge_conf_t *conf);
/* Public functions */
n2n_edge_t* edge_init(const tuntap_dev *dev, const n2n_edge_conf_t *conf, int *rv);
n2n_edge_t* edge_init(const n2n_edge_conf_t *conf, int *rv);
void update_supernode_reg(n2n_edge_t * eee, time_t nowTime);
void readFromIPSocket(n2n_edge_t * eee, int in_sock);
void edge_term(n2n_edge_t *eee);
void edge_set_callbacks(n2n_edge_t *eee, const n2n_edge_callbacks_t *callbacks);
void edge_set_userdata(n2n_edge_t *eee, void *user_data);

9
include/n2n_define.h

@ -97,6 +97,15 @@
#define N2N_SN_PKTBUF_SIZE 2048
/* The way TUNTAP allocated IP. */
#define TUNTAP_IP_MODE_SN_ASSIGN 0
#define TUNTAP_IP_MODE_STATIC 1
#define TUNTAP_IP_MODE_DHCP 2
/* Default network segment of the dhcp service provided by sn. */
#define N2N_SN_DHCP_NET_ADDR_DEFAULT "172.17.12.0"
#define N2N_SN_DHCP_NET_BIT_DEFAULT 24
/* ************************************** */
#define SUPERNODE_IP "127.0.0.1"

93
include/n2n_wire.h

@ -20,19 +20,10 @@
#define N2N_WIRE_H_
#include <stdlib.h>
#if defined(WIN32)
#include "win32/n2n_win32.h"
#if defined(__MINGW32__)
#include <stdint.h>
#endif /* #ifdef __MINGW32__ */
#else /* #if defined(WIN32) */
#ifndef _MSC_VER
/* Not included in Visual Studio 2008 */
#include <stdint.h>
#include <netinet/in.h>
#include <sys/socket.h> /* AF_INET and AF_INET6 */
#endif /* #if defined(WIN32) */
#endif
#define N2N_PKT_VERSION 2
#define N2N_DEFAULT_TTL 2 /* can be forwarded twice at most */
@ -51,6 +42,13 @@ typedef uint8_t n2n_cookie_t[N2N_COOKIE_SIZE];
typedef char n2n_sock_str_t[N2N_SOCKBUF_SIZE]; /* tracing string buffer */
#if defined(WIN32)
#include "win32/n2n_win32.h"
#else /* #if defined(WIN32) */
#include <netinet/in.h>
#include <sys/socket.h> /* AF_INET and AF_INET6 */
#endif /* #if defined(WIN32) */
typedef enum n2n_pc
{
n2n_ping=0, /* Not used */
@ -86,6 +84,12 @@ typedef enum n2n_pc
#define N2N_EINVAL -3
#define N2N_ENOSPACE -4
typedef struct n2n_ip_subnet {
uint32_t net_addr; /* Host order IP address. */
uint8_t net_bitlen; /* Subnet prefix. */
} n2n_ip_subnet_t;
typedef struct n2n_sock
{
uint8_t family; /* AF_INET or AF_INET6; or 0 if invalid */
@ -117,18 +121,18 @@ typedef struct n2n_common
typedef struct n2n_REGISTER
{
n2n_cookie_t cookie; /* Link REGISTER and REGISTER_ACK */
n2n_mac_t srcMac; /* MAC of registering party */
n2n_mac_t dstMac; /* MAC of target edge */
n2n_sock_t sock; /* REVISIT: unused? */
n2n_cookie_t cookie; /**< Link REGISTER and REGISTER_ACK */
n2n_mac_t srcMac; /**< MAC of registering party */
n2n_mac_t dstMac; /**< MAC of target edge */
n2n_sock_t sock; /**< REVISIT: unused? */
} n2n_REGISTER_t;
typedef struct n2n_REGISTER_ACK
{
n2n_cookie_t cookie; /* Return cookie from REGISTER */
n2n_mac_t srcMac; /* MAC of acknowledging party (supernode or edge) */
n2n_mac_t dstMac; /* Reflected MAC of registering edge from REGISTER */
n2n_sock_t sock; /* Supernode's view of edge socket (IP Addr, port) */
n2n_cookie_t cookie; /**< Return cookie from REGISTER */
n2n_mac_t srcMac; /**< MAC of acknowledging party (supernode or edge) */
n2n_mac_t dstMac; /**< Reflected MAC of registering edge from REGISTER */
n2n_sock_t sock; /**< Supernode's view of edge socket (IP Addr, port) */
} n2n_REGISTER_ACK_t;
typedef struct n2n_PACKET
@ -141,30 +145,30 @@ typedef struct n2n_PACKET
} n2n_PACKET_t;
/* Linked with n2n_register_super in n2n_pc_t. Only from edge to supernode. */
typedef struct n2n_REGISTER_SUPER
{
n2n_cookie_t cookie; /* Link REGISTER_SUPER and REGISTER_SUPER_ACK */
n2n_mac_t edgeMac; /* MAC to register with edge sending socket */
n2n_auth_t auth; /* Authentication scheme and tokens */
typedef struct n2n_REGISTER_SUPER {
n2n_cookie_t cookie; /**< Link REGISTER_SUPER and REGISTER_SUPER_ACK */
n2n_mac_t edgeMac; /**< MAC to register with edge sending socket */
n2n_ip_subnet_t dev_addr; /**< IP address of the tuntap adapter. */
n2n_auth_t auth; /**< Authentication scheme and tokens */
} n2n_REGISTER_SUPER_t;
/* Linked with n2n_register_super_ack in n2n_pc_t. Only from supernode to edge. */
typedef struct n2n_REGISTER_SUPER_ACK
{
n2n_cookie_t cookie; /* Return cookie from REGISTER_SUPER */
n2n_mac_t edgeMac; /* MAC registered to edge sending socket */
uint16_t lifetime; /* How long the registration will live */
n2n_sock_t sock; /* Sending sockets associated with edgeMac */
/* The packet format provides additional supernode definitions here.
* uint8_t count, then for each count there is one
* n2n_sock_t.
*/
uint8_t num_sn; /* Number of supernodes that were send
typedef struct n2n_REGISTER_SUPER_ACK {
n2n_cookie_t cookie; /**< Return cookie from REGISTER_SUPER */
n2n_mac_t edgeMac; /**< MAC registered to edge sending socket */
n2n_ip_subnet_t dev_addr; /**< Assign an IP address to the tuntap adapter of edge. */
uint16_t lifetime; /**< How long the registration will live */
n2n_sock_t sock; /**< Sending sockets associated with edgeMac */
/** The packet format provides additional supernode definitions here.
* uint8_t count, then for each count there is one
* n2n_sock_t.
*/
uint8_t num_sn; /**< Number of supernodes that were send
* even if we cannot store them all. If
* non-zero then sn_bak is valid. */
n2n_sock_t sn_bak; /* Socket of the first backup supernode */
n2n_sock_t sn_bak; /**< Socket of the first backup supernode */
} n2n_REGISTER_SUPER_ACK_t;
@ -174,13 +178,14 @@ typedef struct n2n_REGISTER_SUPER_NAK
n2n_cookie_t cookie; /* Return cookie from REGISTER_SUPER */
} n2n_REGISTER_SUPER_NAK_t;
typedef struct n2n_PEER_INFO
{
uint16_t aflags;
n2n_mac_t mac;
n2n_sock_t sock;
typedef struct n2n_PEER_INFO {
uint16_t aflags;
n2n_mac_t mac;
n2n_sock_t sock;
} n2n_PEER_INFO_t;
typedef struct n2n_QUERY_PEER
{
n2n_mac_t srcMac;

76
src/edge.c

@ -450,7 +450,7 @@ static int setOption(int optkey, char *optargument, n2n_tuntap_priv_config_t *ec
char cidr_net[64], gateway[64];
n2n_route_t route;
if(sscanf(optargument, "%63[^/]/%d:%63s", cidr_net, &route.net_bitlen, gateway) != 3) {
if(sscanf(optargument, "%63[^/]/%hhd:%63s", cidr_net, &route.net_bitlen, gateway) != 3) {
traceEvent(TRACE_WARNING, "Bad cidr/gateway format '%d'. See -h.", optargument);
break;
}
@ -818,7 +818,6 @@ int main(int argc, char* argv[]) {
#else
snprintf(ec.tuntap_dev_name, sizeof(ec.tuntap_dev_name), "edge0");
#endif
snprintf(ec.ip_mode, sizeof(ec.ip_mode), "static");
snprintf(ec.netmask, sizeof(ec.netmask), "255.255.255.0");
if((argc >= 2) && (argv[1][0] != '-')) {
@ -861,21 +860,6 @@ int main(int argc, char* argv[]) {
/* Random seed */
n2n_srand (n2n_seed());
if(0 == strcmp("dhcp", ec.ip_mode)) {
traceEvent(TRACE_NORMAL, "Dynamic IP address assignment enabled.");
conf.dyn_ip_mode = 1;
} else
traceEvent(TRACE_NORMAL, "ip_mode='%s'", ec.ip_mode);
if(!(
#ifdef __linux__
(ec.tuntap_dev_name[0] != 0) &&
#endif
(ec.ip_addr[0] != 0)
))
help();
#ifndef WIN32
/* If running suid root then we need to setuid before using the force. */
if(setuid(0) != 0)
@ -886,17 +870,51 @@ int main(int argc, char* argv[]) {
if(conf.encrypt_key && !strcmp((char*)conf.community_name, conf.encrypt_key))
traceEvent(TRACE_WARNING, "Community and encryption key must differ, otherwise security will be compromised");
if(tuntap_open(&tuntap, ec.tuntap_dev_name, ec.ip_mode, ec.ip_addr, ec.netmask, ec.device_mac, ec.mtu) < 0)
exit(1);
if((eee = edge_init(&tuntap, &conf, &rc)) == NULL) {
if((eee = edge_init(&conf, &rc)) == NULL) {
traceEvent(TRACE_ERROR, "Failed in edge_init");
exit(1);
}
memcpy(&(eee->tuntap_priv_conf), &ec, sizeof(ec));
if ((0 == strcmp("static", eee->tuntap_priv_conf.ip_mode)) ||
((eee->tuntap_priv_conf.ip_mode[0] == '\0') && (eee->tuntap_priv_conf.ip_addr[0] != '\0'))) {
traceEvent(TRACE_NORMAL, "Use manually set IP address.");
eee->conf.tuntap_ip_mode = TUNTAP_IP_MODE_STATIC;
} else if (0 == strcmp("dhcp", eee->tuntap_priv_conf.ip_mode)) {
traceEvent(TRACE_NORMAL, "Obtain IP from other edge DHCP services.");
eee->conf.tuntap_ip_mode = TUNTAP_IP_MODE_DHCP;
} else {
traceEvent(TRACE_NORMAL, "Automatically assign IP address by supernode.");
eee->conf.tuntap_ip_mode = TUNTAP_IP_MODE_SN_ASSIGN;
do {
fd_set socket_mask;
struct timeval wait_time;
update_supernode_reg(eee, time(NULL));
FD_ZERO(&socket_mask);
FD_SET(eee->udp_sock, &socket_mask);
wait_time.tv_sec = SOCKET_TIMEOUT_INTERVAL_SECS;
wait_time.tv_usec = 0;
if (select(eee->udp_sock + 1, &socket_mask, NULL, NULL, &wait_time) > 0) {
if (FD_ISSET(eee->udp_sock, &socket_mask)) {
readFromIPSocket(eee, eee->udp_sock);
}
}
} while (eee->sn_wait);
eee->last_register_req = 0;
}
if (tuntap_open(&tuntap, eee->tuntap_priv_conf.tuntap_dev_name, eee->tuntap_priv_conf.ip_mode,
eee->tuntap_priv_conf.ip_addr, eee->tuntap_priv_conf.netmask,
eee->tuntap_priv_conf.device_mac, eee->tuntap_priv_conf.mtu) < 0) exit(1);
traceEvent(TRACE_NORMAL, "Local tuntap IP: %s, Mask: %s",
eee->tuntap_priv_conf.ip_addr, eee->tuntap_priv_conf.netmask);
memcpy(&eee->device, &tuntap, sizeof(tuntap));
// hexdump((unsigned char*)&tuntap,sizeof(tuntap_dev));
#ifndef WIN32
if(ec.daemon) {
if(eee->tuntap_priv_conf.daemon) {
setUseSyslog(1); /* traceEvent output now goes to syslog. */
daemonize();
}
@ -919,13 +937,13 @@ int main(int argc, char* argv[]) {
#endif
#endif /* HAVE_LIBCAP */
if((ec.userid != 0) || (ec.groupid != 0)) {
if((eee->tuntap_priv_conf.userid != 0) || (eee->tuntap_priv_conf.groupid != 0)) {
traceEvent(TRACE_NORMAL, "Dropping privileges to uid=%d, gid=%d",
(signed int)ec.userid, (signed int)ec.groupid);
(signed int)eee->tuntap_priv_conf.userid, (signed int)eee->tuntap_priv_conf.groupid);
/* Finished with the need for root privileges. Drop to unprivileged user. */
if((setgid(ec.groupid) != 0)
|| (setuid(ec.userid) != 0)) {
if((setgid(eee->tuntap_priv_conf.groupid) != 0)
|| (setuid(eee->tuntap_priv_conf.userid) != 0)) {
traceEvent(TRACE_ERROR, "Unable to drop privileges [%u/%s]", errno, strerror(errno));
exit(1);
}
@ -961,10 +979,8 @@ int main(int argc, char* argv[]) {
/* Cleanup */
edge_term(eee);
edge_term_conf(&conf);
tuntap_close(&tuntap);
if(conf.encrypt_key) free(conf.encrypt_key);
edge_term_conf(&eee->conf);
tuntap_close(&eee->device);
return(rc);
}

152
src/edge_utils.c

@ -167,7 +167,7 @@ static int is_ip6_discovery(const void * buf, size_t bufsize) {
*
* This also initialises the NULL transform operation opstruct.
*/
n2n_edge_t* edge_init(const tuntap_dev *dev, const n2n_edge_conf_t *conf, int *rv) {
n2n_edge_t* edge_init(const n2n_edge_conf_t *conf, int *rv) {
n2n_transform_t transop_id = conf->transop_id;
n2n_edge_t *eee = calloc(1, sizeof(n2n_edge_t));
int rc = -1, i;
@ -187,7 +187,6 @@ n2n_edge_t* edge_init(const tuntap_dev *dev, const n2n_edge_conf_t *conf, int *r
#endif
memcpy(&eee->conf, conf, sizeof(*conf));
memcpy(&eee->device, dev, sizeof(*dev));
eee->start_time = time(NULL);
eee->known_peers = NULL;
@ -207,11 +206,11 @@ n2n_edge_t* edge_init(const tuntap_dev *dev, const n2n_edge_conf_t *conf, int *r
// zstd does not require initialization. if it were required, this would be a good place
#endif
for(i=0; i<conf->sn_num; ++i)
traceEvent(TRACE_NORMAL, "supernode %u => %s\n", i, (conf->sn_ip_array[i]));
for(i=0; i<eee->conf.sn_num; ++i)
traceEvent(TRACE_NORMAL, "supernode %u => %s\n", i, (eee->conf.sn_ip_array[i]));
/* Set the active supernode */
supernode2addr(&(eee->supernode), conf->sn_ip_array[eee->sn_idx]);
supernode2addr(&(eee->supernode), eee->conf.sn_ip_array[eee->sn_idx]);
/* Set active transop */
switch(transop_id) {
@ -243,18 +242,18 @@ n2n_edge_t* edge_init(const tuntap_dev *dev, const n2n_edge_conf_t *conf, int *r
/* Set the key schedule (context) for header encryption if enabled */
if(conf->header_encryption == HEADER_ENCRYPTION_ENABLED) {
traceEvent(TRACE_NORMAL, "Header encryption is enabled.");
packet_header_setup_key ((char *)(conf->community_name), &(eee->conf.header_encryption_ctx),&(eee->conf.header_iv_ctx));
packet_header_setup_key ((char *)(eee->conf.community_name), &(eee->conf.header_encryption_ctx),&(eee->conf.header_iv_ctx));
}
if(eee->transop.no_encryption)
traceEvent(TRACE_WARNING, "Encryption is disabled in edge");
if(edge_init_sockets(eee, conf->local_port, conf->mgmt_port, conf->tos) < 0) {
if(edge_init_sockets(eee, eee->conf.local_port, eee->conf.mgmt_port, eee->conf.tos) < 0) {
traceEvent(TRACE_ERROR, "socket setup failed");
goto edge_init_error;
}
if(edge_init_routes(eee, conf->routes, conf->num_routes) < 0) {
if(edge_init_routes(eee, eee->conf.routes, eee->conf.num_routes) < 0) {
traceEvent(TRACE_ERROR, "routes setup failed");
goto edge_init_error;
}
@ -389,7 +388,7 @@ static const int definitely_from_supernode = 1;
* and verify it (and also update, if applicable).
*/
static int find_peer_time_stamp_and_verify (n2n_edge_t * eee,
int from_supernode, n2n_mac_t mac,
int from_supernode, const n2n_mac_t mac,
uint64_t stamp) {
uint64_t * previous_stamp = NULL;
@ -628,8 +627,8 @@ 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};
static const n2n_mac_t broadcast_mac = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
static const n2n_mac_t null_mac = {0, 0, 0, 0, 0, 0};
/** Check if a known peer socket has changed and possibly register again.
*/
@ -736,41 +735,44 @@ static void check_join_multicast_group(n2n_edge_t *eee) {
/** Send a REGISTER_SUPER packet to the current supernode. */
static void send_register_super(n2n_edge_t *eee, const n2n_sock_t *supernode, int sn_idx) {
uint8_t pktbuf[N2N_PKT_BUF_SIZE] = {0};
size_t idx;
/* ssize_t sent; */
n2n_common_t cmn;
n2n_REGISTER_SUPER_t reg;
n2n_sock_str_t sockbuf;
uint8_t pktbuf[N2N_PKT_BUF_SIZE] = {0};
size_t idx;
/* ssize_t sent; */
n2n_common_t cmn;
n2n_REGISTER_SUPER_t reg;
n2n_sock_str_t sockbuf;
memset(&cmn, 0, sizeof(cmn));
memset(&reg, 0, sizeof(reg));
cmn.ttl=N2N_DEFAULT_TTL;
cmn.pc = n2n_register_super;
cmn.flags = 0;
memcpy(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE);
memset(&cmn, 0, sizeof(cmn));
memset(&reg, 0, sizeof(reg));
for (idx = 0; (sn_idx==0) && (idx < N2N_COOKIE_SIZE); ++idx)
eee->last_cookie[idx] = n2n_rand() % 0xff;
cmn.ttl = N2N_DEFAULT_TTL;
cmn.pc = n2n_register_super;
cmn.flags = 0;
memcpy(cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE);
memcpy(reg.cookie, eee->last_cookie, N2N_COOKIE_SIZE);
reg.auth.scheme=0; /* No auth yet */
for (idx = 0; (sn_idx==0) && (idx < N2N_COOKIE_SIZE); ++idx)
eee->last_cookie[idx] = n2n_rand() % 0xff;
idx=0;
encode_mac(reg.edgeMac, &idx, eee->device.mac_addr);
memcpy(reg.cookie, eee->last_cookie, N2N_COOKIE_SIZE);
reg.dev_addr.net_addr = ntohl(eee->device.ip_addr);
reg.dev_addr.net_bitlen = mask2bitlen(ntohl(eee->device.device_mask));
reg.auth.scheme = 0; /* No auth yet */
idx=0;
encode_REGISTER_SUPER(pktbuf, &idx, &cmn, &reg);
idx = 0;
encode_mac(reg.edgeMac, &idx, eee->device.mac_addr);
traceEvent(TRACE_DEBUG, "send REGISTER_SUPER to %s",
sock_to_cstr(sockbuf, supernode));
idx = 0;
encode_REGISTER_SUPER(pktbuf, &idx, &cmn, &reg);
if(eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED)
packet_header_encrypt (pktbuf, idx, eee->conf.header_encryption_ctx,
eee->conf.header_iv_ctx,
time_stamp (), pearson_hash_16 (pktbuf, idx));
traceEvent(TRACE_DEBUG, "send REGISTER_SUPER to %s",
sock_to_cstr(sockbuf, supernode));
/* sent = */ sendto_sock(eee->udp_sock, pktbuf, idx, supernode);
if (eee->conf.header_encryption == HEADER_ENCRYPTION_ENABLED)
packet_header_encrypt(pktbuf, idx, eee->conf.header_encryption_ctx,
eee->conf.header_iv_ctx,
time_stamp(), pearson_hash_16(pktbuf, idx));
/* sent = */ sendto_sock(eee->udp_sock, pktbuf, idx, supernode);
}
/* ************************************** */
@ -904,7 +906,7 @@ static void send_register_ack(n2n_edge_t * eee,
*
* This is frequently called by the main loop.
*/
static void update_supernode_reg(n2n_edge_t * eee, time_t nowTime) {
void update_supernode_reg(n2n_edge_t * eee, time_t nowTime) {
u_int sn_idx;
if(eee->sn_wait && (nowTime > (eee->last_register_req + (eee->conf.register_interval/10)))) {
@ -1588,7 +1590,7 @@ void edge_read_from_tap(n2n_edge_t * eee) {
/* ************************************** */
/** Read a datagram from the main UDP socket to the internet. */
static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
n2n_common_t cmn; /* common fields in the packet header */
n2n_sock_str_t sockbuf1;
@ -1750,14 +1752,14 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
* to double check this.
*/
traceEvent(TRACE_DEBUG, "Got P2P register");
traceEvent(TRACE_NORMAL, "[P2P] Rx REGISTER from %s", sock_to_cstr(sockbuf1, &sender));
traceEvent(TRACE_INFO, "[P2P] Rx REGISTER from %s", sock_to_cstr(sockbuf1, &sender));
find_and_remove_peer(&eee->pending_peers, reg.srcMac);
/* NOTE: only ACK to peers */
send_register_ack(eee, orig_sender, &reg);
}
else {
traceEvent(TRACE_NORMAL, "[PsP] Rx REGISTER src=%s dst=%s from sn=%s (edge:%s)",
traceEvent(TRACE_INFO, "[PsP] Rx REGISTER src=%s dst=%s from sn=%s (edge:%s)",
macaddr_str(mac_buf1, reg.srcMac), macaddr_str(mac_buf2, reg.dstMac),
sock_to_cstr(sockbuf1, &sender), sock_to_cstr(sockbuf2, orig_sender));
}
@ -1793,7 +1795,13 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
}
case MSG_TYPE_REGISTER_SUPER_ACK:
{
// Indicates successful connection between the edge and SN nodes
in_addr_t net;
char * ip_str = NULL;
n2n_REGISTER_SUPER_ACK_t ra;
memset(&ra, 0, sizeof(n2n_REGISTER_SUPER_ACK_t));
// Indicates successful connection between the edge and SN nodes
static int bTrace = 1;
if (bTrace)
{
@ -1801,7 +1809,6 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
bTrace = 0;
}
n2n_REGISTER_SUPER_ACK_t ra;
if(eee->sn_wait)
{
@ -1839,6 +1846,20 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
eee->last_sup = now;
eee->sn_wait=0;
eee->sup_attempts = N2N_EDGE_SUP_ATTEMPTS; /* refresh because we got a response */
if (eee->conf.tuntap_ip_mode == TUNTAP_IP_MODE_SN_ASSIGN) {
if ((ra.dev_addr.net_addr != 0) && (ra.dev_addr.net_bitlen != 0)) {
net = htonl(ra.dev_addr.net_addr);
if ((ip_str = inet_ntoa(*(struct in_addr *) &net)) != NULL) {
strncpy(eee->tuntap_priv_conf.ip_addr, ip_str,
N2N_NETMASK_STR_SIZE);
}
net = htonl(bitlen2mask(ra.dev_addr.net_bitlen));
if ((ip_str = inet_ntoa(*(struct in_addr *) &net)) != NULL) {
strncpy(eee->tuntap_priv_conf.netmask, ip_str,
N2N_NETMASK_STR_SIZE);
}
}
}
if(eee->cb.sn_registration_updated)
eee->cb.sn_registration_updated(eee, now, &sender);
@ -1857,7 +1878,8 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
traceEvent(TRACE_INFO, "Rx REGISTER_SUPER_ACK with no outstanding REGISTER_SUPER.");
}
break;
} case MSG_TYPE_PEER_INFO: {
}
case MSG_TYPE_PEER_INFO: {
n2n_PEER_INFO_t pi;
struct peer_info * scan;
decode_PEER_INFO( &pi, &cmn, udp_buf, &rem, &idx );
@ -2024,7 +2046,7 @@ int run_edge_loop(n2n_edge_t * eee, int *keep_running) {
HASH_COUNT(eee->known_peers));
}
if(eee->conf.dyn_ip_mode &&
if((eee->conf.tuntap_ip_mode == TUNTAP_IP_MODE_DHCP) &&
((nowTime - lastIfaceCheck) > IFACE_UPDATE_INTERVAL)) {
uint32_t old_ip = eee->device.ip_addr;
@ -2535,28 +2557,30 @@ static void edge_cleanup_routes(n2n_edge_t *eee) {
/* ************************************** */
void edge_init_conf_defaults(n2n_edge_conf_t *conf) {
memset(conf, 0, sizeof(*conf));
conf->local_port = 0 /* any port */;
conf->mgmt_port = N2N_EDGE_MGMT_PORT; /* 5644 by default */
conf->transop_id = N2N_TRANSFORM_ID_NULL;
conf->header_encryption = HEADER_ENCRYPTION_NONE;
conf->compression = N2N_COMPRESSION_ID_NONE;
conf->drop_multicast = 1;
conf->allow_p2p = 1;
conf->disable_pmtu_discovery = 1;
conf->register_interval = REGISTER_SUPER_INTERVAL_DFL;
if(getenv("N2N_KEY")) {
conf->encrypt_key = strdup(getenv("N2N_KEY"));
conf->transop_id = N2N_TRANSFORM_ID_TWOFISH;
}
memset(conf, 0, sizeof(*conf));
conf->local_port = 0 /* any port */;
conf->mgmt_port = N2N_EDGE_MGMT_PORT; /* 5644 by default */
conf->transop_id = N2N_TRANSFORM_ID_NULL;
conf->header_encryption = HEADER_ENCRYPTION_NONE;
conf->compression = N2N_COMPRESSION_ID_NONE;
conf->drop_multicast = 1;
conf->allow_p2p = 1;
conf->disable_pmtu_discovery = 1;
conf->register_interval = REGISTER_SUPER_INTERVAL_DFL;
conf->tuntap_ip_mode = TUNTAP_IP_MODE_SN_ASSIGN;
if (getenv("N2N_KEY")) {
conf->encrypt_key = strdup(getenv("N2N_KEY"));
conf->transop_id = N2N_TRANSFORM_ID_TWOFISH;
}
}
/* ************************************** */
void edge_term_conf(n2n_edge_conf_t *conf) {
if(conf->routes) free(conf->routes);
if (conf->routes) free(conf->routes);
if (conf->encrypt_key) free(conf->encrypt_key);
}
/* ************************************** */
@ -2608,7 +2632,7 @@ int quick_edge_init(char *device_name, char *community_name,
return(-2);
/* Init edge */
if((eee = edge_init(&tuntap, &conf, &rv)) == NULL)
if((eee = edge_init(&conf, &rv)) == NULL)
goto quick_edge_init_end;
rv = run_edge_loop(eee, keep_on_running);

4
src/example_edge_embed.c

@ -33,7 +33,7 @@ int main()
snprintf((char *)conf.community_name, sizeof(conf.community_name), "%s", "mycommunity"); // Community to connect to
conf.disable_pmtu_discovery = 1; // Whether to disable the path MTU discovery
conf.drop_multicast = 0; // Whether to disable multicast
conf.dyn_ip_mode = 0; // Whether the IP address is set dynamically (see IP mode; 0 if static, 1 if dynamic)
conf.tuntap_ip_mode = TUNTAP_IP_MODE_SN_ASSIGN; // How to set the IP address
conf.encrypt_key = "mysecret"; // Secret to decrypt & encrypt with
conf.local_port = 0; // What port to use (0 = any port)
conf.mgmt_port = N2N_EDGE_MGMT_PORT; // Edge management port (5644 by default)
@ -59,7 +59,7 @@ int main()
return -1;
}
eee = edge_init(&tuntap, &conf, &rc);
eee = edge_init(&conf, &rc);
if (eee == NULL)
{
exit(1);

58
src/n2n.c

@ -185,6 +185,29 @@ char* intoa(uint32_t /* host order */ addr, char* buf, uint16_t buf_len) {
return(retStr);
}
/** Convert subnet prefix bit length to host order subnet mask. */
uint32_t bitlen2mask(uint8_t bitlen) {
uint8_t i;
uint32_t mask = 0;
for (i = 1; i <= bitlen; ++i) {
mask |= 1 << (32 - i);
}
return mask;
}
/** Convert host order subnet mask to subnet prefix bit length. */
uint8_t mask2bitlen(uint32_t mask) {
uint8_t i, bitlen = 0;
for (i = 0; i < 32; ++i) {
if ((mask << i) & 0x80000000) ++bitlen;
else break;
}
return bitlen;
}
/* *********************************************** */
char * macaddr_str(macstr_t buf,
@ -231,21 +254,21 @@ char* msg_type2str(uint16_t msg_type) {
/* *********************************************** */
void hexdump(const uint8_t * buf, size_t len)
{
size_t i;
if(0 == len) { return; }
void hexdump(const uint8_t *buf, size_t len) {
size_t i;
for(i=0; i<len; i++)
{
if((i > 0) &&((i % 16) == 0)) { printf("\n"); }
printf("%02X ", buf[i] & 0xFF);
}
if (0 == len) { return; }
printf("\n");
printf("-----------------------------------------------\n");
for (i = 0; i < len; i++) {
if ((i > 0) && ((i % 16) == 0)) { printf("\n"); }
printf("%02X ", buf[i] & 0xFF);
}
printf("\n");
printf("-----------------------------------------------\n");
}
/* *********************************************** */
void print_n2n_version() {
@ -360,6 +383,17 @@ extern char * sock_to_cstr(n2n_sock_str_t out,
}
}
char *ip_subnet_to_str(dec_ip_bit_str_t buf, const n2n_ip_subnet_t *ipaddr) {
snprintf(buf, sizeof(dec_ip_bit_str_t), "%hhu.%hhu.%hhu.%hhu/%hhu",
(uint8_t) ((ipaddr->net_addr >> 24) & 0xFF),
(uint8_t) ((ipaddr->net_addr >> 16) & 0xFF),
(uint8_t) ((ipaddr->net_addr >> 8) & 0xFF),
(uint8_t) (ipaddr->net_addr & 0xFF),
ipaddr->net_bitlen);
return buf;
}
/* @return 1 if the two sockets are equivalent. */
int sock_equal(const n2n_sock_t * a,
const n2n_sock_t * b) {
@ -383,7 +417,7 @@ int sock_equal(const n2n_sock_t * a,
/* *********************************************** */
#if defined(WIN32) && !defined(__GNUC__)
#if defined(WIN32)
int gettimeofday(struct timeval *tp, void *tzp) {
time_t clock;
struct tm tm;

165
src/sn.c

@ -92,100 +92,137 @@ static int load_allowed_sn_community(n2n_sn_t *sss, char *path) {
/** Help message to print if the command line arguments are not valid. */
static void help() {
print_n2n_version();
printf("supernode <config file> (see supernode.conf)\n"
"or\n"
);
printf("supernode ");
printf("-l <local port> ");
printf("-c <path> ");
print_n2n_version();
printf("supernode <config file> (see supernode.conf)\n"
"or\n"
);
printf("supernode ");
printf("-l <local port> ");
printf("-c <path> ");
#if defined(N2N_HAVE_DAEMON)
printf("[-f] ");
printf("[-f] ");
#endif
#ifndef WIN32
printf("[-u <uid> -g <gid>] ");
printf("[-u <uid> -g <gid>] ");
#endif /* ifndef WIN32 */
printf("[-t <mgmt port>] ");
printf("[-v] ");
printf("\n\n");
printf("[-t <mgmt port>] ");
printf("[-d <net/bit>] ");
printf("[-v] ");
printf("\n\n");
printf("-l <port>\tSet UDP main listen port to <port>\n");
printf("-c <path>\tFile containing the allowed communities.\n");
printf("-l <port> | Set UDP main listen port to <port>\n");
printf("-c <path> | File containing the allowed communities.\n");
#if defined(N2N_HAVE_DAEMON)
printf("-f \tRun in foreground.\n");
printf("-f | Run in foreground.\n");
#endif /* #if defined(N2N_HAVE_DAEMON) */
#ifndef WIN32
printf("-u <UID>\tUser ID (numeric) to use when privileges are dropped.\n");
printf("-g <GID>\tGroup ID (numeric) to use when privileges are dropped.\n");
printf("-u <UID> | User ID (numeric) to use when privileges are dropped.\n");
printf("-g <GID> | Group ID (numeric) to use when privileges are dropped.\n");
#endif /* ifndef WIN32 */
printf("-t <port>\tManagement UDP Port (for multiple supernodes on a machine).\n");
printf("-v \tIncrease verbosity. Can be used multiple times.\n");
printf("-h \tThis help message.\n");
printf("\n");
printf("-t <port> | Management UDP Port (for multiple supernodes on a machine).\n");
printf("-d <net/bit> | Subnet that provides dhcp service for edge. eg. -d 172.17.12.0/24\n");
printf("-v | Increase verbosity. Can be used multiple times.\n");
printf("-h | This help message.\n");
printf("\n");
exit(1);
exit(1);
}
/* *************************************************** */
static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) {
//traceEvent(TRACE_NORMAL, "Option %c = %s", optkey, _optarg ? _optarg : "");
switch(optkey) {
case 'l': /* local-port */
sss->lport = atoi(_optarg);
break;
case 't': /* mgmt-port */
sss->mport = atoi(_optarg);
break;
//traceEvent(TRACE_NORMAL, "Option %c = %s", optkey, _optarg ? _optarg : "");
switch (optkey) {
case 'l': /* local-port */
sss->lport = atoi(_optarg);
break;
case 't': /* mgmt-port */
sss->mport = atoi(_optarg);
break;
case 'd': {
dec_ip_str_t ip_str = {'\0'};
in_addr_t net;
uint8_t bitlen;
if (sscanf(_optarg, "%15[^/]/%hhu", ip_str, &bitlen) != 2) {
traceEvent(TRACE_WARNING, "Bad net/bit format '%s'. See -h.", _optarg);
break;
}
net = inet_addr(ip_str);
if ((net < 0) || (net == INADDR_NONE) || (net == INADDR_ANY)) {
traceEvent(TRACE_WARNING, "Bad network '%s' in '%s', Use default: '%s/%d'",
ip_str, _optarg,
N2N_SN_DHCP_NET_ADDR_DEFAULT, N2N_SN_DHCP_NET_BIT_DEFAULT);
break;
}
if (bitlen > 32) {
traceEvent(TRACE_WARNING, "Bad prefix '%hhu' in '%s', Use default: '%s/%d'",
bitlen, _optarg,
N2N_SN_DHCP_NET_ADDR_DEFAULT, N2N_SN_DHCP_NET_BIT_DEFAULT);
break;
}
traceEvent(TRACE_NORMAL, "The subnet of DHCP service is: '%s/%hhu'.", ip_str, bitlen);
sss->dhcp_addr.net_addr = ntohl(net);
sss->dhcp_addr.net_bitlen = bitlen;
break;
}
#ifndef WIN32
case 'u': /* unprivileged uid */
sss->userid = atoi(_optarg);
break;
case 'u': /* unprivileged uid */
sss->userid = atoi(_optarg);
break;
case 'g': /* unprivileged uid */
sss->groupid = atoi(_optarg);
break;
case 'g': /* unprivileged uid */
sss->groupid = atoi(_optarg);
break;
#endif
case 'c': /* community file */
load_allowed_sn_community(sss, _optarg);
break;
case 'c': /* community file */
load_allowed_sn_community(sss, _optarg);
break;
case 'f': /* foreground */
sss->daemon = 0;
break;
case 'f': /* foreground */
sss->daemon = 0;
break;
case 'h': /* help */
help();
break;
case 'h': /* help */
help();
break;
case 'v': /* verbose */
setTraceLevel(getTraceLevel() + 1);
break;
case 'v': /* verbose */
setTraceLevel(getTraceLevel() + 1);
break;
default:
traceEvent(TRACE_WARNING, "Unknown option -%c: Ignored.", (char)optkey);
return(-1);
}
default:
traceEvent(TRACE_WARNING, "Unknown option -%c: Ignored.", (char) optkey);
return (-1);
}
return(0);
return (0);
}
/* *********************************************** */
static const struct option long_options[] = {
{ "communities", required_argument, NULL, 'c' },
{ "foreground", no_argument, NULL, 'f' },
{ "local-port", required_argument, NULL, 'l' },
{ "mgmt-port", required_argument, NULL, 't' },
{ "help" , no_argument, NULL, 'h' },
{ "verbose", no_argument, NULL, 'v' },
{ NULL, 0, NULL, 0 }
{"communities", required_argument, NULL, 'c'},
{"foreground", no_argument, NULL, 'f'},
{"local-port", required_argument, NULL, 'l'},
{"mgmt-port", required_argument, NULL, 't'},
{"dhcp", required_argument, NULL, 'd'},
{"help", no_argument, NULL, 'h'},
{"verbose", no_argument, NULL, 'v'},
{NULL, 0, NULL, 0}
};
/* *************************************************** */
@ -194,7 +231,7 @@ static const struct option long_options[] = {
static int loadFromCLI(int argc, char * const argv[], n2n_sn_t *sss) {
u_char c;
while((c = getopt_long(argc, argv, "fl:u:g:t:c:vh",
while((c = getopt_long(argc, argv, "fl:u:g:t:d:c:vh",
long_options, NULL)) != '?') {
if(c == 255) break;
setOption(c, optarg, sss);

337
src/sn_utils.c

@ -47,7 +47,7 @@ static int try_broadcast(n2n_sn_t * sss,
static uint16_t reg_lifetime(n2n_sn_t *sss);
static int update_edge(n2n_sn_t *sss,
const n2n_mac_t edgeMac,
const n2n_REGISTER_SUPER_t* reg,
struct sn_community *comm,
const n2n_sock_t *sender_sock,
time_t now);
@ -204,23 +204,25 @@ static int try_broadcast(n2n_sn_t * sss,
/** Initialise the supernode structure */
int sn_init(n2n_sn_t *sss)
{
int sn_init(n2n_sn_t *sss) {
#ifdef WIN32
initWin32();
initWin32();
#endif
pearson_hash_init();
pearson_hash_init();
memset(sss, 0, sizeof(n2n_sn_t));
memset(sss, 0, sizeof(n2n_sn_t));
sss->daemon = 1; /* By defult run as a daemon. */
sss->lport = N2N_SN_LPORT_DEFAULT;
sss->mport = N2N_SN_MGMT_PORT;
sss->sock = -1;
sss->mgmt_sock = -1;
sss->daemon = 1; /* By defult run as a daemon. */
sss->lport = N2N_SN_LPORT_DEFAULT;
sss->mport = N2N_SN_MGMT_PORT;
sss->sock = -1;
sss->mgmt_sock = -1;
sss->dhcp_addr.net_addr = inet_addr(N2N_SN_DHCP_NET_ADDR_DEFAULT);
sss->dhcp_addr.net_addr = ntohl(sss->dhcp_addr.net_addr);
sss->dhcp_addr.net_bitlen = N2N_SN_DHCP_NET_BIT_DEFAULT;
return 0; /* OK */
return 0; /* OK */
}
/** Deinitialise the supernode structure and deallocate any memory owned by
@ -265,61 +267,101 @@ static uint16_t reg_lifetime(n2n_sn_t *sss)
/** Update the edge table with the details of the edge which contacted the
* supernode. */
static int update_edge(n2n_sn_t *sss,
const n2n_mac_t edgeMac,
const n2n_REGISTER_SUPER_t* reg,
struct sn_community *comm,
const n2n_sock_t *sender_sock,
time_t now)
{
macstr_t mac_buf;
n2n_sock_str_t sockbuf;
struct peer_info *scan;
traceEvent(TRACE_DEBUG, "update_edge for %s [%s]",
macaddr_str(mac_buf, edgeMac),
sock_to_cstr(sockbuf, sender_sock));
HASH_FIND_PEER(comm->edges, edgeMac, scan);
if (NULL == scan)
{
/* Not known */
scan = (struct peer_info *)calloc(1,
sizeof(struct peer_info)); /* deallocated in purge_expired_registrations */
memcpy(&(scan->mac_addr), edgeMac, sizeof(n2n_mac_t));
memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t));
scan->last_valid_time_stamp = initial_time_stamp ();
time_t now) {
macstr_t mac_buf;
n2n_sock_str_t sockbuf;
struct peer_info *scan;
traceEvent(TRACE_DEBUG, "update_edge for %s [%s]",
macaddr_str(mac_buf, reg->edgeMac),
sock_to_cstr(sockbuf, sender_sock));
HASH_FIND_PEER(comm->edges, reg->edgeMac, scan);
if (NULL == scan) {
/* Not known */
scan = (struct peer_info *) calloc(1,
sizeof(struct peer_info)); /* deallocated in purge_expired_registrations */
memcpy(&(scan->mac_addr), reg->edgeMac, sizeof(n2n_mac_t));
scan->dev_addr.net_addr = reg->dev_addr.net_addr;
scan->dev_addr.net_bitlen = reg->dev_addr.net_bitlen;
memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t));
scan->last_valid_time_stamp = initial_time_stamp();
HASH_ADD_PEER(comm->edges, scan);
traceEvent(TRACE_INFO, "update_edge created %s ==> %s",
macaddr_str(mac_buf, reg->edgeMac),
sock_to_cstr(sockbuf, sender_sock));
} else {
/* Known */
if (!sock_equal(sender_sock, &(scan->sock))) {
memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t));
traceEvent(TRACE_INFO, "update_edge updated %s ==> %s",
macaddr_str(mac_buf, reg->edgeMac),
sock_to_cstr(sockbuf, sender_sock));
} else {
traceEvent(TRACE_DEBUG, "update_edge unchanged %s ==> %s",
macaddr_str(mac_buf, reg->edgeMac),
sock_to_cstr(sockbuf, sender_sock));
}
}
scan->last_seen = now;
return 0;
}
HASH_ADD_PEER(comm->edges, scan);
traceEvent(TRACE_INFO, "update_edge created %s ==> %s",
macaddr_str(mac_buf, edgeMac),
sock_to_cstr(sockbuf, sender_sock));
}
else
{
/* Known */
if (!sock_equal(sender_sock, &(scan->sock)))
{
memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t));
static signed int peer_tap_ip_sort(struct peer_info *a, struct peer_info *b) {
uint32_t a_host_id = a->dev_addr.net_addr & (~bitlen2mask(a->dev_addr.net_bitlen));
uint32_t b_host_id = b->dev_addr.net_addr & (~bitlen2mask(b->dev_addr.net_bitlen));
return ((signed int)a_host_id - (signed int)b_host_id);
}
traceEvent(TRACE_INFO, "update_edge updated %s ==> %s",
macaddr_str(mac_buf, edgeMac),
sock_to_cstr(sockbuf, sender_sock));
}
else
{
traceEvent(TRACE_DEBUG, "update_edge unchanged %s ==> %s",
macaddr_str(mac_buf, edgeMac),
sock_to_cstr(sockbuf, sender_sock));
}
}
scan->last_seen = now;
return 0;
/** The IP address assigned to the edge by the DHCP function of sn. */
static int assign_one_ip_addr(n2n_sn_t *sss,
struct sn_community *comm,
n2n_ip_subnet_t *ipaddr) {
struct peer_info *peer, *tmpPeer;
uint32_t net_id, mask, max_host, host_id = 1;
dec_ip_bit_str_t ip_bit_str = {'\0'};
mask = bitlen2mask(sss->dhcp_addr.net_bitlen);
net_id = sss->dhcp_addr.net_addr & mask;
max_host = ~mask;
HASH_SORT(comm->edges, peer_tap_ip_sort);
HASH_ITER(hh, comm->edges, peer, tmpPeer) {
if ((peer->dev_addr.net_addr & bitlen2mask(peer->dev_addr.net_bitlen)) == net_id) {
if (host_id >= max_host) {
traceEvent(TRACE_WARNING, "No assignable IP to edge tap adapter.");
return -1;
}
if (peer->dev_addr.net_addr == 0) {
continue;
}
if ((peer->dev_addr.net_addr & max_host) == host_id) {
++host_id;
} else {
break;
}
}
}
ipaddr->net_addr = net_id | host_id;
ipaddr->net_bitlen = sss->dhcp_addr.net_bitlen;
traceEvent(TRACE_INFO, "Assign IP %s to tap adapter of edge.", ip_subnet_to_str(ip_bit_str, ipaddr));
return 0;
}
/***
*
* For a given packet, find the apporopriate internal last valid time stamp for lookup
@ -409,89 +451,89 @@ static int process_mgmt(n2n_sn_t *sss,
const struct sockaddr_in *sender_sock,
const uint8_t *mgmt_buf,
size_t mgmt_size,
time_t now)
{
char resbuf[N2N_SN_PKTBUF_SIZE];
size_t ressize = 0;
uint32_t num_edges = 0;
uint32_t num = 0;
struct sn_community *community, *tmp;
struct peer_info * peer, *tmpPeer;
macstr_t mac_buf;
n2n_sock_str_t sockbuf;
traceEvent(TRACE_DEBUG, "process_mgmt");
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"----------------\n");
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"uptime %lu\n", (now - sss->start_time));
HASH_ITER(hh, sss->communities, community, tmp)
{
num_edges += HASH_COUNT(community->edges);
}
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"edges %u\n",
num_edges);
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"errors %u\n",
(unsigned int)sss->stats.errors);
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"reg_sup %u\n",
(unsigned int)sss->stats.reg_super);
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"reg_nak %u\n",
(unsigned int)sss->stats.reg_super_nak);
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"fwd %u\n",
(unsigned int)sss->stats.fwd);
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"broadcast %u\n",
(unsigned int)sss->stats.broadcast);
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"last fwd %lu sec ago\n",
(long unsigned int)(now - sss->stats.last_fwd));
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"last reg %lu sec ago\n",
(long unsigned int)(now - sss->stats.last_reg_super));
ressize += snprintf(resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize,
"cur_cmnts %u\n", HASH_COUNT(sss->communities));
HASH_ITER(hh, sss->communities, community, tmp) {
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"community: %s\n", community->community);
sendto_mgmt(sss, sender_sock, (const uint8_t *)resbuf, ressize);
ressize = 0;
num = 0;
HASH_ITER(hh, community->edges, peer, tmpPeer) {
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"\t[id: %u][MAC: %s][edge: %s][last seen: %lu sec ago]\n",
++num, macaddr_str(mac_buf, peer->mac_addr),
sock_to_cstr(sockbuf, &(peer->sock)), now-peer->last_seen);
sendto_mgmt(sss, sender_sock, (const uint8_t *)resbuf, ressize);
ressize = 0;
}
}
ressize += snprintf(resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize,
"\n");
sendto_mgmt(sss, sender_sock, (const uint8_t *)resbuf, ressize);
return 0;
time_t now) {
char resbuf[N2N_SN_PKTBUF_SIZE];
size_t ressize = 0;
uint32_t num_edges = 0;
uint32_t num = 0;
struct sn_community *community, *tmp;
struct peer_info *peer, *tmpPeer;
macstr_t mac_buf;
n2n_sock_str_t sockbuf;
dec_ip_bit_str_t ip_bit_str = {'\0'};
traceEvent(TRACE_DEBUG, "process_mgmt");
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"\tid tun_tap MAC edge last_seen\n");
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"-------------------------------------------------------------------------------------\n");
HASH_ITER(hh, sss->communities, community, tmp) {
num_edges += HASH_COUNT(community->edges);
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"community: %s\n", community->community);
sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize);
ressize = 0;
num = 0;
HASH_ITER(hh, community->edges, peer, tmpPeer) {
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"\t%-4u %-18s %-17s %-21s %lu\n",
++num, ip_subnet_to_str(ip_bit_str, &peer->dev_addr),
macaddr_str(mac_buf, peer->mac_addr),
sock_to_cstr(sockbuf, &(peer->sock)), now - peer->last_seen);
sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize);
ressize = 0;
}
}
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"-------------------------------------------------------------------------------------\n");
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"uptime %lu | ", (now - sss->start_time));
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"edges %u | ",
num_edges);
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"reg_sup %u | ",
(unsigned int) sss->stats.reg_super);
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"reg_nak %u | ",
(unsigned int) sss->stats.reg_super_nak);
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"errors %u \n",
(unsigned int) sss->stats.errors);
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"fwd %u | ",
(unsigned int) sss->stats.fwd);
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"broadcast %u | ",
(unsigned int) sss->stats.broadcast);
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"cur_cmnts %u\n", HASH_COUNT(sss->communities));
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"last fwd %lu sec ago\n",
(long unsigned int) (now - sss->stats.last_fwd));
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
"last reg %lu sec ago\n\n",
(long unsigned int) (now - sss->stats.last_reg_super));
sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize);
return 0;
}
static int sendto_mgmt(n2n_sn_t *sss,
const struct sockaddr_in *sender_sock,
const uint8_t *mgmt_buf,
@ -528,6 +570,7 @@ static int process_udp(n2n_sn_t * sss,
char buf[32];
struct sn_community *comm, *tmp;
uint64_t stamp;
const n2n_mac_t null_mac = {0, 0, 0, 0, 0, 0}; /* 00:00:00:00:00:00 */
traceEvent(TRACE_DEBUG, "Processing incoming UDP packet [len: %lu][sender: %s:%u]",
udp_size, intoa(ntohl(sender_sock->sin_addr.s_addr), buf, sizeof(buf)),
@ -791,6 +834,9 @@ static int process_udp(n2n_sn_t * sss,
n2n_common_t cmn2;
uint8_t ackbuf[N2N_SN_PKTBUF_SIZE];
size_t encx=0;
n2n_ip_subnet_t ipaddr;
memset(&ack, 0, sizeof(n2n_REGISTER_SUPER_ACK_t));
/* Edge requesting registration with us. */
sss->stats.last_reg_super=now;
@ -836,6 +882,12 @@ static int process_udp(n2n_sn_t * sss,
memcpy(&(ack.cookie), &(reg.cookie), sizeof(n2n_cookie_t));
memcpy(ack.edgeMac, reg.edgeMac, sizeof(n2n_mac_t));
if ((reg.dev_addr.net_addr == 0) || (reg.dev_addr.net_addr == 0xFFFFFFFF) || (reg.dev_addr.net_bitlen == 0) ||
((reg.dev_addr.net_addr & 0xFFFF0000) == 0xA9FE0000 /* 169.254.0.0 */)) {
assign_one_ip_addr(sss, comm, &ipaddr);
ack.dev_addr.net_addr = ipaddr.net_addr;
ack.dev_addr.net_bitlen = ipaddr.net_bitlen;
}
ack.lifetime = reg_lifetime(sss);
ack.sock.family = AF_INET;
@ -843,13 +895,14 @@ static int process_udp(n2n_sn_t * sss,
memcpy(ack.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE);
ack.num_sn=0; /* No backup */
memset(&(ack.sn_bak), 0, sizeof(n2n_sock_t));
traceEvent(TRACE_DEBUG, "Rx REGISTER_SUPER for %s [%s]",
macaddr_str(mac_buf, reg.edgeMac),
sock_to_cstr(sockbuf, &(ack.sock)));
update_edge(sss, reg.edgeMac, comm, &(ack.sock), now);
if(memcmp(reg.edgeMac, &null_mac, N2N_MAC_SIZE) != 0){
update_edge(sss, &reg, comm, &(ack.sock), now);
}
encode_REGISTER_SUPER_ACK(ackbuf, &encx, &cmn2, &ack);

260
src/wire.c

@ -289,130 +289,135 @@ int decode_REGISTER( n2n_REGISTER_t * reg,
return retval;
}
int encode_REGISTER_SUPER( uint8_t * base,
size_t * idx,
const n2n_common_t * common,
const n2n_REGISTER_SUPER_t * reg )
{
int retval=0;
retval += encode_common( base, idx, common );
retval += encode_buf( base, idx, reg->cookie, N2N_COOKIE_SIZE );
retval += encode_mac( base, idx, reg->edgeMac );
retval += encode_uint16( base, idx, 0 ); /* NULL auth scheme */
retval += encode_uint16( base, idx, 0 ); /* No auth data */
return retval;
int encode_REGISTER_SUPER(uint8_t *base,
size_t *idx,
const n2n_common_t *common,
const n2n_REGISTER_SUPER_t *reg) {
int retval = 0;
retval += encode_common(base, idx, common);
retval += encode_buf(base, idx, reg->cookie, N2N_COOKIE_SIZE);
retval += encode_mac(base, idx, reg->edgeMac);
retval += encode_uint32(base, idx, reg->dev_addr.net_addr);
retval += encode_uint8(base, idx, reg->dev_addr.net_bitlen);
retval += encode_uint16(base, idx, 0); /* NULL auth scheme */
retval += encode_uint16(base, idx, 0); /* No auth data */
return retval;
}
int decode_REGISTER_SUPER( n2n_REGISTER_SUPER_t * reg,
const n2n_common_t * cmn, /* info on how to interpret it */
const uint8_t * base,
size_t * rem,
size_t * idx )
{
size_t retval=0;
memset( reg, 0, sizeof(n2n_REGISTER_SUPER_t) );
retval += decode_buf( reg->cookie, N2N_COOKIE_SIZE, base, rem, idx );
retval += decode_mac( reg->edgeMac, base, rem, idx );
retval += decode_uint16( &(reg->auth.scheme), base, rem, idx );
retval += decode_uint16( &(reg->auth.toksize), base, rem, idx );
retval += decode_buf( reg->auth.token, reg->auth.toksize, base, rem, idx );
return retval;
}
int encode_REGISTER_ACK( uint8_t * base,
size_t * idx,
const n2n_common_t * common,
const n2n_REGISTER_ACK_t * reg )
{
int retval=0;
retval += encode_common( base, idx, common );
retval += encode_buf( base, idx, reg->cookie, N2N_COOKIE_SIZE );
retval += encode_mac( base, idx, reg->dstMac );
retval += encode_mac( base, idx, reg->srcMac );
int decode_REGISTER_SUPER(n2n_REGISTER_SUPER_t *reg,
const n2n_common_t *cmn, /* info on how to interpret it */
const uint8_t *base,
size_t *rem,
size_t *idx) {
size_t retval = 0;
memset(reg, 0, sizeof(n2n_REGISTER_SUPER_t));
retval += decode_buf(reg->cookie, N2N_COOKIE_SIZE, base, rem, idx);
retval += decode_mac(reg->edgeMac, base, rem, idx);
retval += decode_uint32(&(reg->dev_addr.net_addr), base, rem, idx);
retval += decode_uint8(&(reg->dev_addr.net_bitlen), base, rem, idx);
retval += decode_uint16(&(reg->auth.scheme), base, rem, idx);
retval += decode_uint16(&(reg->auth.toksize), base, rem, idx);
retval += decode_buf(reg->auth.token, reg->auth.toksize, base, rem, idx);
return retval;
}
/* The socket in REGISTER_ACK is the socket from which the REGISTER
* arrived. This is sent back to the sender so it knows what its public
* socket is. */
if ( 0 != reg->sock.family )
{
retval += encode_sock( base, idx, &(reg->sock) );
}
return retval;
int encode_REGISTER_ACK(uint8_t *base,
size_t *idx,
const n2n_common_t *common,
const n2n_REGISTER_ACK_t *reg) {
int retval = 0;
retval += encode_common(base, idx, common);
retval += encode_buf(base, idx, reg->cookie, N2N_COOKIE_SIZE);
retval += encode_mac(base, idx, reg->dstMac);
retval += encode_mac(base, idx, reg->srcMac);
/* The socket in REGISTER_ACK is the socket from which the REGISTER
* arrived. This is sent back to the sender so it knows what its public
* socket is. */
if (0 != reg->sock.family) {
retval += encode_sock(base, idx, &(reg->sock));
}
return retval;
}
int decode_REGISTER_ACK( n2n_REGISTER_ACK_t * reg,
const n2n_common_t * cmn, /* info on how to interpret it */
const uint8_t * base,
size_t * rem,
size_t * idx )
{
size_t retval=0;
memset( reg, 0, sizeof(n2n_REGISTER_ACK_t) );
retval += decode_buf( reg->cookie, N2N_COOKIE_SIZE, base, rem, idx );
retval += decode_mac( reg->dstMac, base, rem, idx );
retval += decode_mac( reg->srcMac, base, rem, idx );
/* The socket in REGISTER_ACK is the socket from which the REGISTER
* arrived. This is sent back to the sender so it knows what its public
* socket is. */
if ( cmn->flags & N2N_FLAGS_SOCKET )
{
retval += decode_sock( &(reg->sock), base, rem, idx );
}
return retval;
int decode_REGISTER_ACK(n2n_REGISTER_ACK_t *reg,
const n2n_common_t *cmn, /* info on how to interpret it */
const uint8_t *base,
size_t *rem,
size_t *idx) {
size_t retval = 0;
memset(reg, 0, sizeof(n2n_REGISTER_ACK_t));
retval += decode_buf(reg->cookie, N2N_COOKIE_SIZE, base, rem, idx);
retval += decode_mac(reg->dstMac, base, rem, idx);
retval += decode_mac(reg->srcMac, base, rem, idx);
/* The socket in REGISTER_ACK is the socket from which the REGISTER
* arrived. This is sent back to the sender so it knows what its public
* socket is. */
if (cmn->flags & N2N_FLAGS_SOCKET) {
retval += decode_sock(&(reg->sock), base, rem, idx);
}
return retval;
}
int encode_REGISTER_SUPER_ACK( uint8_t * base,
size_t * idx,
const n2n_common_t * common,
const n2n_REGISTER_SUPER_ACK_t * reg )
{
int retval=0;
retval += encode_common( base, idx, common );
retval += encode_buf( base, idx, reg->cookie, N2N_COOKIE_SIZE );
retval += encode_mac( base, idx, reg->edgeMac );
retval += encode_uint16( base, idx, reg->lifetime );
retval += encode_sock( base, idx, &(reg->sock) );
retval += encode_uint8( base, idx, reg->num_sn );
if ( reg->num_sn > 0 )
{
/* We only support 0 or 1 at this stage */
retval += encode_sock( base, idx, &(reg->sn_bak) );
}
return retval;
int encode_REGISTER_SUPER_ACK(uint8_t *base,
size_t *idx,
const n2n_common_t *common,
const n2n_REGISTER_SUPER_ACK_t *reg) {
int retval = 0;
retval += encode_common(base, idx, common);
retval += encode_buf(base, idx, reg->cookie, N2N_COOKIE_SIZE);
retval += encode_mac(base, idx, reg->edgeMac);
retval += encode_uint32(base, idx, reg->dev_addr.net_addr);
retval += encode_uint8(base, idx, reg->dev_addr.net_bitlen);
retval += encode_uint16(base, idx, reg->lifetime);
retval += encode_sock(base, idx, &(reg->sock));
retval += encode_uint8(base, idx, reg->num_sn);
if (reg->num_sn > 0) {
/* We only support 0 or 1 at this stage */
retval += encode_sock(base, idx, &(reg->sn_bak));
}
return retval;
}
int decode_REGISTER_SUPER_ACK( n2n_REGISTER_SUPER_ACK_t * reg,
const n2n_common_t * cmn, /* info on how to interpret it */
const uint8_t * base,
size_t * rem,
size_t * idx )
{
size_t retval=0;
memset( reg, 0, sizeof(n2n_REGISTER_SUPER_ACK_t) );
retval += decode_buf( reg->cookie, N2N_COOKIE_SIZE, base, rem, idx );
retval += decode_mac( reg->edgeMac, base, rem, idx );
retval += decode_uint16( &(reg->lifetime), base, rem, idx );
int decode_REGISTER_SUPER_ACK(n2n_REGISTER_SUPER_ACK_t *reg,
const n2n_common_t *cmn, /* info on how to interpret it */
const uint8_t *base,
size_t *rem,
size_t *idx) {
size_t retval = 0;
/* Socket is mandatory in this message type */
retval += decode_sock( &(reg->sock), base, rem, idx );
memset(reg, 0, sizeof(n2n_REGISTER_SUPER_ACK_t));
retval += decode_buf(reg->cookie, N2N_COOKIE_SIZE, base, rem, idx);
retval += decode_mac(reg->edgeMac, base, rem, idx);
retval += decode_uint32(&(reg->dev_addr.net_addr), base, rem, idx);
retval += decode_uint8(&(reg->dev_addr.net_bitlen), base, rem, idx);
retval += decode_uint16(&(reg->lifetime), base, rem, idx);
/* Following the edge socket are an array of backup supernodes. */
retval += decode_uint8( &(reg->num_sn), base, rem, idx );
if ( reg->num_sn > 0 )
{
/* We only support 0 or 1 at this stage */
retval += decode_sock( &(reg->sn_bak), base, rem, idx );
}
/* Socket is mandatory in this message type */
retval += decode_sock(&(reg->sock), base, rem, idx);
return retval;
/* Following the edge socket are an array of backup supernodes. */
retval += decode_uint8(&(reg->num_sn), base, rem, idx);
if (reg->num_sn > 0) {
/* We only support 0 or 1 at this stage */
retval += decode_sock(&(reg->sn_bak), base, rem, idx);
}
return retval;
}
int fill_sockaddr( struct sockaddr * addr,
size_t addrlen,
const n2n_sock_t * sock )
@ -475,35 +480,36 @@ int decode_PACKET( n2n_PACKET_t * pkt,
return retval;
}
int encode_PEER_INFO( uint8_t * base,
size_t * idx,
const n2n_common_t * common,
const n2n_PEER_INFO_t * pkt )
{
int retval=0;
retval += encode_common( base, idx, common );
retval += encode_uint16( base, idx, pkt->aflags );
retval += encode_mac( base, idx, pkt->mac );
retval += encode_sock( base, idx, &pkt->sock );
return retval;
int encode_PEER_INFO(uint8_t *base,
size_t *idx,
const n2n_common_t *common,
const n2n_PEER_INFO_t *pkt) {
int retval = 0;
retval += encode_common(base, idx, common);
retval += encode_uint16(base, idx, pkt->aflags);
retval += encode_mac(base, idx, pkt->mac);
retval += encode_sock(base, idx, &pkt->sock);
return retval;
}
int decode_PEER_INFO( n2n_PEER_INFO_t * pkt,
const n2n_common_t * cmn, /* info on how to interpret it */
const uint8_t * base,
size_t * rem,
size_t * idx )
{
size_t retval=0;
memset( pkt, 0, sizeof(n2n_PEER_INFO_t) );
retval += decode_uint16( &(pkt->aflags), base, rem, idx );
retval += decode_mac( pkt->mac, base, rem, idx );
retval += decode_sock( &pkt->sock, base, rem, idx );
return retval;
int decode_PEER_INFO(n2n_PEER_INFO_t *pkt,
const n2n_common_t *cmn, /* info on how to interpret it */
const uint8_t *base,
size_t *rem,
size_t *idx) {
size_t retval = 0;
memset(pkt, 0, sizeof(n2n_PEER_INFO_t));
retval += decode_uint16(&(pkt->aflags), base, rem, idx);
retval += decode_mac(pkt->mac, base, rem, idx);
retval += decode_sock(&pkt->sock, base, rem, idx);
return retval;
}
int encode_QUERY_PEER( uint8_t * base,
size_t * idx,
const n2n_common_t * common,

15
win32/n2n_win32.h

@ -98,13 +98,14 @@ struct ip {
/* ************************************* */
typedef struct tuntap_dev {
HANDLE device_handle;
char *device_name;
char *ifName;
OVERLAPPED overlap_read, overlap_write;
uint8_t mac_addr[6];
uint32_t ip_addr, device_mask;
unsigned int mtu;
HANDLE device_handle;
char *device_name;
char *ifName;
OVERLAPPED overlap_read, overlap_write;
n2n_mac_t mac_addr;
uint32_t ip_addr;
uint32_t device_mask;
unsigned int mtu;
} tuntap_dev;
#define index(a, b) strchr(a, b)

7
win32/winconfig.h

@ -1,8 +1,15 @@
/* winconfig.h. Win32 replacement for file generated from config.h.in by configure. */
/* OS name */
#ifndef PACKAGE_OSNAME
#define PACKAGE_OSNAME N2N_OSNAME
#endif
/* Define to the version of this package. */
#ifndef PACKAGE_VERSION
#define PACKAGE_VERSION N2N_VERSION
#endif
#ifndef GIT_RELEASE
#define GIT_RELEASE N2N_VERSION
#endif

Loading…
Cancel
Save