diff --git a/include/n2n.h b/include/n2n.h index a01c87c..337616c 100644 --- a/include/n2n.h +++ b/include/n2n.h @@ -170,13 +170,13 @@ typedef struct ether_hdr ether_hdr_t; #ifndef WIN32 typedef struct tuntap_dev { - 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]; + 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 @@ -197,16 +197,16 @@ typedef char dec_ip_bit_str_t[N2N_NETMASK_STR_SIZE + 4]; 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 */ + 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 */ }; @@ -214,9 +214,9 @@ 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; - uint8_t 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; @@ -256,17 +256,17 @@ typedef struct n2n_edge_callbacks { /* ***************************************************** */ typedef struct n2n_tuntap_priv_config { - char tuntap_dev_name[N2N_IFNAMSIZ]; - char ip_mode[N2N_IF_MODE_SIZE]; - dec_ip_str_t ip_addr; - dec_ip_str_t netmask; - char device_mac[N2N_MACNAMSIZ]; - int mtu; - uint8_t got_s; - uint8_t daemon; + char tuntap_dev_name[N2N_IFNAMSIZ]; + char ip_mode[N2N_IF_MODE_SIZE]; + dec_ip_str_t ip_addr; + dec_ip_str_t netmask; + char device_mac[N2N_MACNAMSIZ]; + int mtu; + uint8_t got_s; + uint8_t daemon; #ifndef WIN32 - uid_t userid; - gid_t groupid; + uid_t userid; + gid_t groupid; #endif } n2n_tuntap_priv_config_t; @@ -274,91 +274,91 @@ 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 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_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; - uint32_t tx_sup; - uint32_t rx_sup; - uint32_t tx_sup_broadcast; - uint32_t rx_sup_broadcast; + uint32_t tx_p2p; + uint32_t rx_p2p; + uint32_t tx_sup; + uint32_t rx_sup; + uint32_t tx_sup_broadcast; + uint32_t rx_sup_broadcast; }; 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 */ - - /* Sockets */ - n2n_sock_t supernode; - int udp_sock; - int udp_mgmt_sock; /**< socket for status info. */ + 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 */ + + /* Sockets */ + n2n_sock_t supernode; + int udp_sock; + 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. */ + /* Peers */ + 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 */ + /* 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 */ - struct n2n_edge_stats stats; /**< Statistics */ + struct n2n_edge_stats stats; /**< Statistics */ - n2n_tuntap_priv_config_t tuntap_priv_conf; /**< Tuntap config */ + n2n_tuntap_priv_config_t tuntap_priv_conf; /**< Tuntap config */ }; typedef struct sn_stats { - size_t errors; /* Number of errors encountered. */ - size_t reg_super; /* Number of REGISTER_SUPER requests received. */ - size_t reg_super_nak; /* Number of REGISTER_SUPER requests declined. */ - size_t fwd; /* Number of messages forwarded. */ - size_t broadcast; /* Number of messages broadcast to a community. */ - time_t last_fwd; /* Time when last message was forwarded. */ - time_t last_reg_super; /* Time when last REGISTER_SUPER was received. */ + size_t errors; /* Number of errors encountered. */ + size_t reg_super; /* Number of REGISTER_SUPER requests received. */ + size_t reg_super_nak; /* Number of REGISTER_SUPER requests declined. */ + size_t fwd; /* Number of messages forwarded. */ + size_t broadcast; /* Number of messages broadcast to a community. */ + time_t last_fwd; /* Time when last message was forwarded. */ + time_t last_reg_super; /* Time when last REGISTER_SUPER was received. */ } sn_stats_t; struct sn_community @@ -383,20 +383,21 @@ struct sn_community_regular_expression 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. */ + 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; + uid_t userid; + gid_t groupid; #endif - int lock_communities; /* If true, only loaded and matching communities can be used. */ - struct sn_community *communities; - struct sn_community_regular_expression *rules; + int lock_communities; /* If true, only loaded and matching communities can be used. */ + struct sn_community *communities; + struct sn_community_regular_expression *rules; } n2n_sn_t; /* ************************************** */ @@ -435,7 +436,7 @@ void traceEvent(int eventTraceLevel, char* file, int line, char * format, ...); /* Tuntap API */ int tuntap_open(tuntap_dev *device, char *dev, const char *address_mode, char *device_ip, - char *device_mask, const char * device_mac, int mtu); + char *device_mask, const char * device_mac, int mtu); int tuntap_read(struct tuntap_dev *tuntap, unsigned char *buf, int len); int tuntap_write(struct tuntap_dev *tuntap, unsigned char *buf, int len); void tuntap_close(struct tuntap_dev *tuntap); @@ -456,11 +457,11 @@ void print_edge_stats(const n2n_edge_t *eee); /* Sockets */ char* sock_to_cstr( n2n_sock_str_t out, - const n2n_sock_t * sock ); + 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 ); + const n2n_sock_t * b ); /* Header encryption */ uint64_t time_stamp(void); diff --git a/src/sn_utils.c b/src/sn_utils.c index 861880b..13fb705 100644 --- a/src/sn_utils.c +++ b/src/sn_utils.c @@ -130,28 +130,28 @@ static ssize_t sendto_sock(n2n_sn_t *sss, const uint8_t *pktbuf, size_t pktsize) { - n2n_sock_str_t sockbuf; + n2n_sock_str_t sockbuf; - if (AF_INET == sock->family) + if (AF_INET == sock->family) { - struct sockaddr_in udpsock; + struct sockaddr_in udpsock; - udpsock.sin_family = AF_INET; - udpsock.sin_port = htons(sock->port); - memcpy(&(udpsock.sin_addr.s_addr), &(sock->addr.v4), IPV4_SIZE); + udpsock.sin_family = AF_INET; + udpsock.sin_port = htons(sock->port); + memcpy(&(udpsock.sin_addr.s_addr), &(sock->addr.v4), IPV4_SIZE); - traceEvent(TRACE_DEBUG, "sendto_sock %lu to [%s]", - pktsize, - sock_to_cstr(sockbuf, sock)); + traceEvent(TRACE_DEBUG, "sendto_sock %lu to [%s]", + pktsize, + sock_to_cstr(sockbuf, sock)); - return sendto(sss->sock, pktbuf, pktsize, 0, - (const struct sockaddr *)&udpsock, sizeof(struct sockaddr_in)); + return sendto(sss->sock, pktbuf, pktsize, 0, + (const struct sockaddr *)&udpsock, sizeof(struct sockaddr_in)); } - else + else { - /* AF_INET6 not implemented */ - errno = EAFNOSUPPORT; - return -1; + /* AF_INET6 not implemented */ + errno = EAFNOSUPPORT; + return -1; } } @@ -181,22 +181,22 @@ static int try_broadcast(n2n_sn_t * sss, data_sent_len = sendto_sock(sss, &(scan->sock), pktbuf, pktsize); if(data_sent_len != pktsize) - { - ++(sss->stats.errors); - traceEvent(TRACE_WARNING, "multicast %lu to [%s] %s failed %s", - pktsize, - sock_to_cstr(sockbuf, &(scan->sock)), - macaddr_str(mac_buf, scan->mac_addr), - strerror(errno)); - } + { + ++(sss->stats.errors); + traceEvent(TRACE_WARNING, "multicast %lu to [%s] %s failed %s", + pktsize, + sock_to_cstr(sockbuf, &(scan->sock)), + macaddr_str(mac_buf, scan->mac_addr), + strerror(errno)); + } else - { - ++(sss->stats.broadcast); - traceEvent(TRACE_DEBUG, "multicast %lu to [%s] %s", - pktsize, - sock_to_cstr(sockbuf, &(scan->sock)), - macaddr_str(mac_buf, scan->mac_addr)); - } + { + ++(sss->stats.broadcast); + traceEvent(TRACE_DEBUG, "multicast %lu to [%s] %s", + pktsize, + sock_to_cstr(sockbuf, &(scan->sock)), + macaddr_str(mac_buf, scan->mac_addr)); + } } } return 0; @@ -206,60 +206,60 @@ static int try_broadcast(n2n_sn_t * sss, /** Initialise the supernode structure */ 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->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; + 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 * it. */ void sn_term(n2n_sn_t *sss) { - struct sn_community *community, *tmp; - struct sn_community_regular_expression *re, *tmp_re; + struct sn_community *community, *tmp; + struct sn_community_regular_expression *re, *tmp_re; - if (sss->sock >= 0) + if (sss->sock >= 0) { - closesocket(sss->sock); + closesocket(sss->sock); } - sss->sock = -1; + sss->sock = -1; - if (sss->mgmt_sock >= 0) + if (sss->mgmt_sock >= 0) { - closesocket(sss->mgmt_sock); + closesocket(sss->mgmt_sock); } - sss->mgmt_sock = -1; + sss->mgmt_sock = -1; - HASH_ITER(hh, sss->communities, community, tmp) + HASH_ITER(hh, sss->communities, community, tmp) { - clear_peer_list(&community->edges); - if (NULL != community->header_encryption_ctx) - free (community->header_encryption_ctx); - HASH_DEL(sss->communities, community); - free(community); + clear_peer_list(&community->edges); + if (NULL != community->header_encryption_ctx) + free (community->header_encryption_ctx); + HASH_DEL(sss->communities, community); + free(community); } - HASH_ITER(hh, sss->rules, re, tmp_re) { - HASH_DEL(sss->rules, re); - if (NULL!=re->rule) { - free(re->rule); - } - free(re); + HASH_ITER(hh, sss->rules, re, tmp_re) { + HASH_DEL(sss->rules, re); + if (NULL!=re->rule) { + free(re->rule); } + free(re); + } } /** Determine the appropriate lifetime for new registrations. @@ -269,8 +269,8 @@ void sn_term(n2n_sn_t *sss) */ static uint16_t reg_lifetime(n2n_sn_t *sss) { - /* NOTE: UDP firewalls usually have a 30 seconds timeout */ - return 15; + /* NOTE: UDP firewalls usually have a 30 seconds timeout */ + return 15; } /** Update the edge table with the details of the edge which contacted the @@ -280,57 +280,57 @@ static int update_edge(n2n_sn_t *sss, 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; + 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)); + 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); + HASH_FIND_PEER(comm->edges, reg->edgeMac, scan); - if (NULL == scan) { - /* Not known */ + if (NULL == scan) { + /* Not known */ - scan = (struct peer_info *) calloc(1, - sizeof(struct peer_info)); /* deallocated in purge_expired_registrations */ + 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(); + 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); + 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)); - } - } + 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; + scan->last_seen = now; + return 0; } 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); + 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); } @@ -338,36 +338,36 @@ static signed int peer_tap_ip_sort(struct peer_info *a, struct peer_info *b) { 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; + 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; + traceEvent(TRACE_INFO, "Assign IP %s to tap adapter of edge.", ip_subnet_to_str(ip_bit_str, ipaddr)); + return 0; } @@ -377,8 +377,8 @@ static int assign_one_ip_addr(n2n_sn_t *sss, * and verify it (and also update, if applicable). */ static int find_edge_time_stamp_and_verify (struct peer_info * edges, - int from_supernode, n2n_mac_t mac, - uint64_t stamp) { + int from_supernode, n2n_mac_t mac, + uint64_t stamp) { uint64_t * previous_stamp = NULL; @@ -461,85 +461,85 @@ static int process_mgmt(n2n_sn_t *sss, 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; - 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"); + 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, + "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, + "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_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, + "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, + "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, + "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, + "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, + "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 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)); + 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); + sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize); - return 0; + return 0; } @@ -604,13 +604,13 @@ static int process_udp(n2n_sn_t * sss, if (comm) { if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { traceEvent(TRACE_DEBUG, "process_udp dropped a packet with unencrypted header " - "addressed to community '%s' which uses encrypted headers.", - comm->community); + "addressed to community '%s' which uses encrypted headers.", + comm->community); return -1; } if (comm->header_encryption == HEADER_ENCRYPTION_UNKNOWN) { traceEvent (TRACE_INFO, "process_udp locked community '%s' to using " - "unencrypted headers.", comm->community); + "unencrypted headers.", comm->community); /* set 'no encryption' in case it is not set yet */ comm->header_encryption = HEADER_ENCRYPTION_NONE; comm->header_encryption_ctx = NULL; @@ -631,13 +631,13 @@ static int process_udp(n2n_sn_t * sss, // time stamp verification follows in the packet specific section as it requires to determine the // sender from the hash list by its MAC, this all depends on packet type and packet structure // (MAC is not always in the same place) - if (checksum != pearson_hash_16 (udp_buf, udp_size)) { - traceEvent(TRACE_DEBUG, "process_udp dropped packet due to checksum error."); - return -1; + if (checksum != pearson_hash_16 (udp_buf, udp_size)) { + traceEvent(TRACE_DEBUG, "process_udp dropped packet due to checksum error."); + return -1; } if (comm->header_encryption == HEADER_ENCRYPTION_UNKNOWN) { traceEvent (TRACE_INFO, "process_udp locked community '%s' to using " - "encrypted headers.", comm->community); + "encrypted headers.", comm->community); /* set 'encrypted' in case it is not set yet */ comm->header_encryption = HEADER_ENCRYPTION_ENABLED; } @@ -651,7 +651,7 @@ static int process_udp(n2n_sn_t * sss, if (!ret) { // no matching key/community traceEvent(TRACE_DEBUG, "process_udp dropped a packet with seemingly encrypted header " - "for which no matching community which uses encrypted headers was found."); + "for which no matching community which uses encrypted headers was found."); return -1; } } @@ -684,280 +684,280 @@ static int process_udp(n2n_sn_t * sss, switch(msg_type) { case MSG_TYPE_PACKET: - { - /* PACKET from one edge to another edge via supernode. */ - - /* pkt will be modified in place and recoded to an output of potentially - * different size due to addition of the socket.*/ - n2n_PACKET_t pkt; - n2n_common_t cmn2; - uint8_t encbuf[N2N_SN_PKTBUF_SIZE]; - size_t encx=0; - int unicast; /* non-zero if unicast */ - uint8_t * rec_buf; /* either udp_buf or encbuf */ - - if(!comm) { - traceEvent(TRACE_DEBUG, "process_udp PACKET with unknown community %s", cmn.community); - return -1; - } - - sss->stats.last_fwd=now; - decode_PACKET(&pkt, &cmn, udp_buf, &rem, &idx); - - // already checked for valid comm - if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { - if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, pkt.srcMac, stamp)) { - traceEvent(TRACE_DEBUG, "process_udp dropped PACKET due to time stamp error."); - return -1; + { + /* PACKET from one edge to another edge via supernode. */ + + /* pkt will be modified in place and recoded to an output of potentially + * different size due to addition of the socket.*/ + n2n_PACKET_t pkt; + n2n_common_t cmn2; + uint8_t encbuf[N2N_SN_PKTBUF_SIZE]; + size_t encx=0; + int unicast; /* non-zero if unicast */ + uint8_t * rec_buf; /* either udp_buf or encbuf */ + + if(!comm) { + traceEvent(TRACE_DEBUG, "process_udp PACKET with unknown community %s", cmn.community); + return -1; } - } - unicast = (0 == is_multi_broadcast(pkt.dstMac)); + sss->stats.last_fwd=now; + decode_PACKET(&pkt, &cmn, udp_buf, &rem, &idx); - traceEvent(TRACE_DEBUG, "RX PACKET (%s) %s -> %s %s", - (unicast?"unicast":"multicast"), - macaddr_str(mac_buf, pkt.srcMac), - macaddr_str(mac_buf2, pkt.dstMac), - (from_supernode?"from sn":"local")); + // already checked for valid comm + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, pkt.srcMac, stamp)) { + traceEvent(TRACE_DEBUG, "process_udp dropped PACKET due to time stamp error."); + return -1; + } + } - if(!from_supernode) { - memcpy(&cmn2, &cmn, sizeof(n2n_common_t)); + unicast = (0 == is_multi_broadcast(pkt.dstMac)); - /* We are going to add socket even if it was not there before */ - cmn2.flags |= N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE; + traceEvent(TRACE_DEBUG, "RX PACKET (%s) %s -> %s %s", + (unicast?"unicast":"multicast"), + macaddr_str(mac_buf, pkt.srcMac), + macaddr_str(mac_buf2, pkt.dstMac), + (from_supernode?"from sn":"local")); - pkt.sock.family = AF_INET; - pkt.sock.port = ntohs(sender_sock->sin_port); - memcpy(pkt.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE); + if(!from_supernode) { + memcpy(&cmn2, &cmn, sizeof(n2n_common_t)); - rec_buf = encbuf; + /* We are going to add socket even if it was not there before */ + cmn2.flags |= N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE; - /* Re-encode the header. */ - encode_PACKET(encbuf, &encx, &cmn2, &pkt); - uint16_t oldEncx = encx; + pkt.sock.family = AF_INET; + pkt.sock.port = ntohs(sender_sock->sin_port); + memcpy(pkt.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE); - /* Copy the original payload unchanged */ - encode_buf(encbuf, &encx, (udp_buf + idx), (udp_size - idx)); + rec_buf = encbuf; - if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED) - packet_header_encrypt (rec_buf, oldEncx, comm->header_encryption_ctx, - comm->header_iv_ctx, - time_stamp (), pearson_hash_16 (rec_buf, encx)); + /* Re-encode the header. */ + encode_PACKET(encbuf, &encx, &cmn2, &pkt); + uint16_t oldEncx = encx; - } else { - /* Already from a supernode. Nothing to modify, just pass to - * destination. */ + /* Copy the original payload unchanged */ + encode_buf(encbuf, &encx, (udp_buf + idx), (udp_size - idx)); - traceEvent(TRACE_DEBUG, "Rx PACKET fwd unmodified"); + if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED) + packet_header_encrypt (rec_buf, oldEncx, comm->header_encryption_ctx, + comm->header_iv_ctx, + time_stamp (), pearson_hash_16 (rec_buf, encx)); - rec_buf = udp_buf; - encx = udp_size; + } else { + /* Already from a supernode. Nothing to modify, just pass to + * destination. */ - if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED) - packet_header_encrypt (rec_buf, idx, comm->header_encryption_ctx, - comm->header_iv_ctx, - time_stamp (), pearson_hash_16 (rec_buf, udp_size)); - } + traceEvent(TRACE_DEBUG, "Rx PACKET fwd unmodified"); - /* Common section to forward the final product. */ - if(unicast) - try_forward(sss, comm, &cmn, pkt.dstMac, rec_buf, encx); - else - try_broadcast(sss, comm, &cmn, pkt.srcMac, rec_buf, encx); - break; - } - case MSG_TYPE_REGISTER: - { - /* Forwarding a REGISTER from one edge to the next */ + rec_buf = udp_buf; + encx = udp_size; - n2n_REGISTER_t reg; - n2n_common_t cmn2; - uint8_t encbuf[N2N_SN_PKTBUF_SIZE]; - size_t encx=0; - int unicast; /* non-zero if unicast */ - uint8_t * rec_buf; /* either udp_buf or encbuf */ + if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED) + packet_header_encrypt (rec_buf, idx, comm->header_encryption_ctx, + comm->header_iv_ctx, + time_stamp (), pearson_hash_16 (rec_buf, udp_size)); + } - if(!comm) { - traceEvent(TRACE_DEBUG, "process_udp REGISTER from unknown community %s", cmn.community); - return -1; + /* Common section to forward the final product. */ + if(unicast) + try_forward(sss, comm, &cmn, pkt.dstMac, rec_buf, encx); + else + try_broadcast(sss, comm, &cmn, pkt.srcMac, rec_buf, encx); + break; } + case MSG_TYPE_REGISTER: + { + /* Forwarding a REGISTER from one edge to the next */ + + n2n_REGISTER_t reg; + n2n_common_t cmn2; + uint8_t encbuf[N2N_SN_PKTBUF_SIZE]; + size_t encx=0; + int unicast; /* non-zero if unicast */ + uint8_t * rec_buf; /* either udp_buf or encbuf */ + + if(!comm) { + traceEvent(TRACE_DEBUG, "process_udp REGISTER from unknown community %s", cmn.community); + return -1; + } - sss->stats.last_fwd=now; - decode_REGISTER(®, &cmn, udp_buf, &rem, &idx); + sss->stats.last_fwd=now; + decode_REGISTER(®, &cmn, udp_buf, &rem, &idx); - // already checked for valid comm - if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { - if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, reg.srcMac, stamp)) { - traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER due to time stamp error."); - return -1; + // already checked for valid comm + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, reg.srcMac, stamp)) { + traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER due to time stamp error."); + return -1; + } } - } - unicast = (0 == is_multi_broadcast(reg.dstMac)); + unicast = (0 == is_multi_broadcast(reg.dstMac)); - if(unicast) { - traceEvent(TRACE_DEBUG, "Rx REGISTER %s -> %s %s", - macaddr_str(mac_buf, reg.srcMac), - macaddr_str(mac_buf2, reg.dstMac), - ((cmn.flags & N2N_FLAGS_FROM_SUPERNODE)?"from sn":"local")); + if(unicast) { + traceEvent(TRACE_DEBUG, "Rx REGISTER %s -> %s %s", + macaddr_str(mac_buf, reg.srcMac), + macaddr_str(mac_buf2, reg.dstMac), + ((cmn.flags & N2N_FLAGS_FROM_SUPERNODE)?"from sn":"local")); - if(0 == (cmn.flags & N2N_FLAGS_FROM_SUPERNODE)) { - memcpy(&cmn2, &cmn, sizeof(n2n_common_t)); + if(0 == (cmn.flags & N2N_FLAGS_FROM_SUPERNODE)) { + memcpy(&cmn2, &cmn, sizeof(n2n_common_t)); - /* We are going to add socket even if it was not there before */ - cmn2.flags |= N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE; + /* We are going to add socket even if it was not there before */ + cmn2.flags |= N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE; - reg.sock.family = AF_INET; - reg.sock.port = ntohs(sender_sock->sin_port); - memcpy(reg.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE); + reg.sock.family = AF_INET; + reg.sock.port = ntohs(sender_sock->sin_port); + memcpy(reg.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE); - rec_buf = encbuf; + rec_buf = encbuf; - /* Re-encode the header. */ - encode_REGISTER(encbuf, &encx, &cmn2, ®); - } else { - /* Already from a supernode. Nothing to modify, just pass to - * destination. */ + /* Re-encode the header. */ + encode_REGISTER(encbuf, &encx, &cmn2, ®); + } else { + /* Already from a supernode. Nothing to modify, just pass to + * destination. */ - rec_buf = udp_buf; - encx = udp_size; - } + rec_buf = udp_buf; + encx = udp_size; + } - if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED) - packet_header_encrypt (rec_buf, encx, comm->header_encryption_ctx, - comm->header_iv_ctx, - time_stamp (), pearson_hash_16 (rec_buf, encx)); + if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED) + packet_header_encrypt (rec_buf, encx, comm->header_encryption_ctx, + comm->header_iv_ctx, + time_stamp (), pearson_hash_16 (rec_buf, encx)); - try_forward(sss, comm, &cmn, reg.dstMac, rec_buf, encx); /* unicast only */ - } else - traceEvent(TRACE_ERROR, "Rx REGISTER with multicast destination"); - break; - } + try_forward(sss, comm, &cmn, reg.dstMac, rec_buf, encx); /* unicast only */ + } else + traceEvent(TRACE_ERROR, "Rx REGISTER with multicast destination"); + break; + } case MSG_TYPE_REGISTER_ACK: traceEvent(TRACE_DEBUG, "Rx REGISTER_ACK (NOT IMPLEMENTED) Should not be via supernode"); break; case MSG_TYPE_REGISTER_SUPER: - { - n2n_REGISTER_SUPER_t reg; - n2n_REGISTER_SUPER_ACK_t ack; - n2n_common_t cmn2; - uint8_t ackbuf[N2N_SN_PKTBUF_SIZE]; - size_t encx=0; - struct sn_community_regular_expression *re, *tmp_re; - int8_t allowed_match = -1; - uint8_t match = 0; - int match_length = 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; - ++(sss->stats.reg_super); - decode_REGISTER_SUPER(®, &cmn, udp_buf, &rem, &idx); - - if (comm) { - if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { - if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, reg.edgeMac, stamp)) { - traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER due to time stamp error."); - return -1; - } + { + n2n_REGISTER_SUPER_t reg; + n2n_REGISTER_SUPER_ACK_t ack; + n2n_common_t cmn2; + uint8_t ackbuf[N2N_SN_PKTBUF_SIZE]; + size_t encx=0; + struct sn_community_regular_expression *re, *tmp_re; + int8_t allowed_match = -1; + uint8_t match = 0; + int match_length = 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; + ++(sss->stats.reg_super); + decode_REGISTER_SUPER(®, &cmn, udp_buf, &rem, &idx); + + if (comm) { + if(comm->header_encryption == HEADER_ENCRYPTION_ENABLED) { + if(!find_edge_time_stamp_and_verify (comm->edges, from_supernode, reg.edgeMac, stamp)) { + traceEvent(TRACE_DEBUG, "process_udp dropped REGISTER_SUPER due to time stamp error."); + return -1; + } + } } - } - /* - Before we move any further, we need to check if the requested - community is allowed by the supernode. In case it is not we do - not report any message back to the edge to hide the supernode - existance (better from the security standpoint) - */ - - if(!comm && sss->lock_communities) { - HASH_ITER(hh, sss->rules, re, tmp_re) { - allowed_match = re_matchp(re->rule, cmn.community, &match_length); - - if( (allowed_match != -1) - && (match_length == strlen(cmn.community)) // --- only full matches allowed (remove, if also partial matches wanted) - && (allowed_match == 0)) { // --- only full matches allowed (remove, if also partial matches wanted) - match = 1; - break; - } - } - if(match != 1) { - traceEvent(TRACE_INFO, "Discarded registration: unallowed community '%s'", - (char*)cmn.community); - return -1; + /* + Before we move any further, we need to check if the requested + community is allowed by the supernode. In case it is not we do + not report any message back to the edge to hide the supernode + existance (better from the security standpoint) + */ + + if(!comm && sss->lock_communities) { + HASH_ITER(hh, sss->rules, re, tmp_re) { + allowed_match = re_matchp(re->rule, cmn.community, &match_length); + + if( (allowed_match != -1) + && (match_length == strlen(cmn.community)) // --- only full matches allowed (remove, if also partial matches wanted) + && (allowed_match == 0)) { // --- only full matches allowed (remove, if also partial matches wanted) + match = 1; + break; + } + } + if(match != 1) { + traceEvent(TRACE_INFO, "Discarded registration: unallowed community '%s'", + (char*)cmn.community); + return -1; + } } - } - if(!comm && (!sss->lock_communities || (match == 1))) { - comm = calloc(1, sizeof(struct sn_community)); + if(!comm && (!sss->lock_communities || (match == 1))) { + comm = calloc(1, sizeof(struct sn_community)); + + if(comm) { + strncpy(comm->community, (char*)cmn.community, N2N_COMMUNITY_SIZE-1); + comm->community[N2N_COMMUNITY_SIZE-1] = '\0'; + /* new communities introduced by REGISTERs could not have had encrypted header... */ + comm->header_encryption = HEADER_ENCRYPTION_NONE; + comm->header_encryption_ctx = NULL; + /* ... and also are purgeable during periodic purge */ + comm->purgeable = COMMUNITY_PURGEABLE; + comm->number_enc_packets = 0; + HASH_ADD_STR(sss->communities, community, comm); + + traceEvent(TRACE_INFO, "New community: %s", comm->community); + } + } if(comm) { - strncpy(comm->community, (char*)cmn.community, N2N_COMMUNITY_SIZE-1); - comm->community[N2N_COMMUNITY_SIZE-1] = '\0'; - /* new communities introduced by REGISTERs could not have had encrypted header... */ - comm->header_encryption = HEADER_ENCRYPTION_NONE; - comm->header_encryption_ctx = NULL; - /* ... and also are purgeable during periodic purge */ - comm->purgeable = COMMUNITY_PURGEABLE; - comm->number_enc_packets = 0; - HASH_ADD_STR(sss->communities, community, comm); + cmn2.ttl = N2N_DEFAULT_TTL; + cmn2.pc = n2n_register_super_ack; + cmn2.flags = N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE; + memcpy(cmn2.community, cmn.community, sizeof(n2n_community_t)); + + 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); - traceEvent(TRACE_INFO, "New community: %s", comm->community); - } - } + ack.sock.family = AF_INET; + ack.sock.port = ntohs(sender_sock->sin_port); + memcpy(ack.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE); - if(comm) { - cmn2.ttl = N2N_DEFAULT_TTL; - cmn2.pc = n2n_register_super_ack; - cmn2.flags = N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE; - memcpy(cmn2.community, cmn.community, sizeof(n2n_community_t)); - - 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; - ack.sock.port = ntohs(sender_sock->sin_port); - memcpy(ack.sock.addr.v4, &(sender_sock->sin_addr.s_addr), IPV4_SIZE); - - ack.num_sn=0; /* No backup */ - - traceEvent(TRACE_DEBUG, "Rx REGISTER_SUPER for %s [%s]", - macaddr_str(mac_buf, reg.edgeMac), - sock_to_cstr(sockbuf, &(ack.sock))); - - if(memcmp(reg.edgeMac, &null_mac, N2N_MAC_SIZE) != 0){ - update_edge(sss, ®, comm, &(ack.sock), now); - } + ack.num_sn=0; /* No backup */ - encode_REGISTER_SUPER_ACK(ackbuf, &encx, &cmn2, &ack); + traceEvent(TRACE_DEBUG, "Rx REGISTER_SUPER for %s [%s]", + macaddr_str(mac_buf, reg.edgeMac), + sock_to_cstr(sockbuf, &(ack.sock))); - if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED) - packet_header_encrypt (ackbuf, encx, comm->header_encryption_ctx, - comm->header_iv_ctx, - time_stamp (), pearson_hash_16 (ackbuf, encx)); + if(memcmp(reg.edgeMac, &null_mac, N2N_MAC_SIZE) != 0){ + update_edge(sss, ®, comm, &(ack.sock), now); + } - sendto(sss->sock, ackbuf, encx, 0, - (struct sockaddr *)sender_sock, sizeof(struct sockaddr_in)); + encode_REGISTER_SUPER_ACK(ackbuf, &encx, &cmn2, &ack); - traceEvent(TRACE_DEBUG, "Tx REGISTER_SUPER_ACK for %s [%s]", - macaddr_str(mac_buf, reg.edgeMac), - sock_to_cstr(sockbuf, &(ack.sock))); - } else { - traceEvent(TRACE_INFO, "Discarded registration: unallowed community '%s'", - (char*)cmn.community); - return -1; + if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED) + packet_header_encrypt (ackbuf, encx, comm->header_encryption_ctx, + comm->header_iv_ctx, + time_stamp (), pearson_hash_16 (ackbuf, encx)); + + sendto(sss->sock, ackbuf, encx, 0, + (struct sockaddr *)sender_sock, sizeof(struct sockaddr_in)); + + traceEvent(TRACE_DEBUG, "Tx REGISTER_SUPER_ACK for %s [%s]", + macaddr_str(mac_buf, reg.edgeMac), + sock_to_cstr(sockbuf, &(ack.sock))); + } else { + traceEvent(TRACE_INFO, "Discarded registration: unallowed community '%s'", + (char*)cmn.community); + return -1; + } + break; } - break; - } case MSG_TYPE_QUERY_PEER: { n2n_QUERY_PEER_t query; uint8_t encbuf[N2N_SN_PKTBUF_SIZE]; @@ -1001,20 +1001,20 @@ static int process_udp(n2n_sn_t * sss, if (comm->header_encryption == HEADER_ENCRYPTION_ENABLED) packet_header_encrypt (encbuf, encx, comm->header_encryption_ctx, - comm->header_iv_ctx, - time_stamp (), pearson_hash_16 (encbuf, encx)); + comm->header_iv_ctx, + time_stamp (), pearson_hash_16 (encbuf, encx)); sendto( sss->sock, encbuf, encx, 0, (struct sockaddr *)sender_sock, sizeof(struct sockaddr_in) ); traceEvent( TRACE_DEBUG, "Tx PEER_INFO to %s", - macaddr_str( mac_buf, query.srcMac ) ); + macaddr_str( mac_buf, query.srcMac ) ); } else { traceEvent( TRACE_DEBUG, "Ignoring QUERY_PEER for unknown edge %s", - macaddr_str( mac_buf, query.targetMac ) ); + macaddr_str( mac_buf, query.targetMac ) ); } - break; + break; } default: /* Not a known message type */ @@ -1028,98 +1028,98 @@ static int process_udp(n2n_sn_t * sss, * daemonisation on some platforms. */ int run_sn_loop(n2n_sn_t *sss, int *keep_running) { - uint8_t pktbuf[N2N_SN_PKTBUF_SIZE]; - time_t last_purge_edges = 0; - time_t last_sort_communities = 0; + uint8_t pktbuf[N2N_SN_PKTBUF_SIZE]; + time_t last_purge_edges = 0; + time_t last_sort_communities = 0; - sss->start_time = time(NULL); + sss->start_time = time(NULL); - while (*keep_running) + while (*keep_running) { - int rc; - ssize_t bread; - int max_sock; - fd_set socket_mask; - struct timeval wait_time; - time_t now = 0; + int rc; + ssize_t bread; + int max_sock; + fd_set socket_mask; + struct timeval wait_time; + time_t now = 0; - FD_ZERO(&socket_mask); - max_sock = MAX(sss->sock, sss->mgmt_sock); + FD_ZERO(&socket_mask); + max_sock = MAX(sss->sock, sss->mgmt_sock); - FD_SET(sss->sock, &socket_mask); - FD_SET(sss->mgmt_sock, &socket_mask); + FD_SET(sss->sock, &socket_mask); + FD_SET(sss->mgmt_sock, &socket_mask); - wait_time.tv_sec = 10; - wait_time.tv_usec = 0; - rc = select(max_sock + 1, &socket_mask, NULL, NULL, &wait_time); + wait_time.tv_sec = 10; + wait_time.tv_usec = 0; + rc = select(max_sock + 1, &socket_mask, NULL, NULL, &wait_time); - now = time(NULL); + now = time(NULL); - if (rc > 0) + if (rc > 0) { - if (FD_ISSET(sss->sock, &socket_mask)) + if (FD_ISSET(sss->sock, &socket_mask)) { - struct sockaddr_in sender_sock; - socklen_t i; + struct sockaddr_in sender_sock; + socklen_t i; - i = sizeof(sender_sock); - bread = recvfrom(sss->sock, pktbuf, N2N_SN_PKTBUF_SIZE, 0 /*flags*/, - (struct sockaddr *)&sender_sock, (socklen_t *)&i); + i = sizeof(sender_sock); + bread = recvfrom(sss->sock, pktbuf, N2N_SN_PKTBUF_SIZE, 0 /*flags*/, + (struct sockaddr *)&sender_sock, (socklen_t *)&i); - if ((bread < 0) + if ((bread < 0) #ifdef WIN32 - && (WSAGetLastError() != WSAECONNRESET) + && (WSAGetLastError() != WSAECONNRESET) #endif - ) + ) { - /* For UDP bread of zero just means no data (unlike TCP). */ - /* The fd is no good now. Maybe we lost our interface. */ - traceEvent(TRACE_ERROR, "recvfrom() failed %d errno %d (%s)", bread, errno, strerror(errno)); + /* For UDP bread of zero just means no data (unlike TCP). */ + /* The fd is no good now. Maybe we lost our interface. */ + traceEvent(TRACE_ERROR, "recvfrom() failed %d errno %d (%s)", bread, errno, strerror(errno)); #ifdef WIN32 - traceEvent(TRACE_ERROR, "WSAGetLastError(): %u", WSAGetLastError()); + traceEvent(TRACE_ERROR, "WSAGetLastError(): %u", WSAGetLastError()); #endif - *keep_running = 0; - break; + *keep_running = 0; + break; } - /* We have a datagram to process */ - if (bread > 0) + /* We have a datagram to process */ + if (bread > 0) { - /* And the datagram has data (not just a header) */ - process_udp(sss, &sender_sock, pktbuf, bread, now); + /* And the datagram has data (not just a header) */ + process_udp(sss, &sender_sock, pktbuf, bread, now); } } - if (FD_ISSET(sss->mgmt_sock, &socket_mask)) + if (FD_ISSET(sss->mgmt_sock, &socket_mask)) { - struct sockaddr_in sender_sock; - size_t i; + struct sockaddr_in sender_sock; + size_t i; - i = sizeof(sender_sock); - bread = recvfrom(sss->mgmt_sock, pktbuf, N2N_SN_PKTBUF_SIZE, 0 /*flags*/, - (struct sockaddr *)&sender_sock, (socklen_t *)&i); + i = sizeof(sender_sock); + bread = recvfrom(sss->mgmt_sock, pktbuf, N2N_SN_PKTBUF_SIZE, 0 /*flags*/, + (struct sockaddr *)&sender_sock, (socklen_t *)&i); - if (bread <= 0) + if (bread <= 0) { - traceEvent(TRACE_ERROR, "recvfrom() failed %d errno %d (%s)", bread, errno, strerror(errno)); - *keep_running = 0; - break; + traceEvent(TRACE_ERROR, "recvfrom() failed %d errno %d (%s)", bread, errno, strerror(errno)); + *keep_running = 0; + break; } - /* We have a datagram to process */ - process_mgmt(sss, &sender_sock, pktbuf, bread, now); + /* We have a datagram to process */ + process_mgmt(sss, &sender_sock, pktbuf, bread, now); } } - else + else { - traceEvent(TRACE_DEBUG, "timeout"); + traceEvent(TRACE_DEBUG, "timeout"); } - purge_expired_communities(sss, &last_purge_edges, now); - sort_communities (sss, &last_sort_communities, now); + purge_expired_communities(sss, &last_purge_edges, now); + sort_communities (sss, &last_sort_communities, now); } /* while */ - sn_term(sss); + sn_term(sss); - return 0; + return 0; }