From 57f742fe42c5b3b65ce205f873ff20512b750b8f Mon Sep 17 00:00:00 2001 From: BetaBeauty Date: Tue, 27 Oct 2020 04:13:56 +0800 Subject: [PATCH] Extra Device Description in P2P Connection and Register to Super Node (#475) * add cmake export commands * add extra edge description (hint) field * add peer2peer description registry * fixed bug: peer2peer not pass the dev_desc filed * update -I option in the helper text Co-authored-by: Longtao Wang --- CMakeLists.txt | 2 ++ include/n2n.h | 2 ++ include/n2n_wire.h | 5 +++++ src/edge.c | 11 ++++++++++- src/edge_utils.c | 39 ++++++++++++++++++++++++++++----------- src/sn_utils.c | 13 ++++++++----- src/wire.c | 4 ++++ 7 files changed, 59 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8000941..eff71f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,8 @@ cmake_minimum_required(VERSION 2.6) include(CheckFunctionExists) SET(CMAKE_VERBOSE_MAKEFILE ON) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + # N2n release information set(N2N_VERSION "2.9.0") set(N2N_OSNAME ${CMAKE_SYSTEM}) diff --git a/include/n2n.h b/include/n2n.h index 3889588..8342543 100644 --- a/include/n2n.h +++ b/include/n2n.h @@ -197,6 +197,7 @@ typedef char n2n_sn_name_t[N2N_EDGE_SN_HOST_SIZE]; struct peer_info { n2n_mac_t mac_addr; n2n_ip_subnet_t dev_addr; + n2n_desc_t dev_desc; n2n_sock_t sock; int timeout; uint8_t purgeable; @@ -273,6 +274,7 @@ 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. */ + n2n_desc_t dev_desc; /**< The device description (hint) */ 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 */ diff --git a/include/n2n_wire.h b/include/n2n_wire.h index 83f85ef..a27a93d 100644 --- a/include/n2n_wire.h +++ b/include/n2n_wire.h @@ -30,6 +30,7 @@ #define N2N_COMMUNITY_SIZE 16 #define N2N_MAC_SIZE 6 #define N2N_COOKIE_SIZE 4 +#define N2N_DESC_SIZE 16 #define N2N_PKT_BUF_SIZE 2048 #define N2N_SOCKBUF_SIZE 64 /* string representation of INET or INET6 sockets */ @@ -40,6 +41,8 @@ typedef uint8_t n2n_community_t[N2N_COMMUNITY_SIZE]; typedef uint8_t n2n_mac_t[N2N_MAC_SIZE]; typedef uint8_t n2n_cookie_t[N2N_COOKIE_SIZE]; +typedef uint8_t n2n_desc_t[N2N_DESC_SIZE]; + typedef char n2n_sock_str_t[N2N_SOCKBUF_SIZE]; /* tracing string buffer */ #if defined(WIN32) @@ -126,6 +129,7 @@ typedef struct n2n_REGISTER n2n_mac_t dstMac; /**< MAC of target edge */ n2n_sock_t sock; /**< REVISIT: unused? */ n2n_ip_subnet_t dev_addr; /**< IP address of the tuntap adapter. */ + n2n_desc_t dev_desc; /**< Hint description correlated with the edge */ } n2n_REGISTER_t; typedef struct n2n_REGISTER_ACK @@ -150,6 +154,7 @@ 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_desc_t dev_desc; /**< Hint description correlated with the edge */ n2n_auth_t auth; /**< Authentication scheme and tokens */ } n2n_REGISTER_SUPER_t; diff --git a/src/edge.c b/src/edge.c index 7f238a7..ccea3a8 100644 --- a/src/edge.c +++ b/src/edge.c @@ -154,6 +154,7 @@ static void help() { printf("-k | Encryption key (ASCII) - also N2N_KEY=.\n"); printf("-l | Supernode IP:port\n"); printf("-i | Registration interval, for NAT hole punching (default 20 seconds)\n"); + printf("-I | Annotate the edge's description (hint), identified in the manage port\n"); printf("-L | TTL for registration packet when UDP NAT hole punching through supernode (default 0 for not set )\n"); printf("-p | Fixed local UDP port.\n"); #ifndef WIN32 @@ -422,6 +423,14 @@ static int setOption(int optkey, char *optargument, n2n_tuntap_priv_config_t *ec } #endif + case 'I': /* Device Description (hint) */ + { + memset(conf->dev_desc, 0, N2N_DESC_SIZE); + /* reserve possible last char as null terminator. */ + strncpy((char *)conf->dev_desc, optargument, N2N_DESC_SIZE-1); + break; + } + case 'p': { conf->local_port = atoi(optargument); @@ -530,7 +539,7 @@ static int loadFromCLI(int argc, char *argv[], n2n_edge_conf_t *conf, n2n_tuntap u_char c; while ((c = getopt_long(argc, argv, - "k:a:bc:Eu:g:m:M:s:d:l:p:fvhrt:i:SDL:z::A::Hn:" + "k:a:bc:Eu:g:m:M:s:d:l:p:fvhrt:i:I:SDL:z::A::Hn:" #ifdef __linux__ "T:" #endif diff --git a/src/edge_utils.c b/src/edge_utils.c index a388cd7..ab9d09c 100644 --- a/src/edge_utils.c +++ b/src/edge_utils.c @@ -32,6 +32,7 @@ static void check_peer_registration_needed(n2n_edge_t *eee, uint8_t from_supernode, const n2n_mac_t mac, const n2n_ip_subnet_t *dev_addr, + const n2n_desc_t *dev_desc, const n2n_sock_t *peer); static int edge_init_sockets(n2n_edge_t *eee, int udp_local_port, int mgmt_port, uint8_t tos); @@ -42,6 +43,7 @@ static void check_known_peer_sock_change(n2n_edge_t *eee, uint8_t from_supernode, const n2n_mac_t mac, const n2n_ip_subnet_t *dev_addr, + const n2n_desc_t *dev_desc, const n2n_sock_t *peer, time_t when); @@ -61,6 +63,9 @@ int edge_verify_conf(const n2n_edge_conf_t *conf) { ((conf->encrypt_key != NULL) && (conf->transop_id == N2N_TRANSFORM_ID_NULL))) return(-4); + if (conf->dev_desc[0] == 0) + return (-5); + return(0); } @@ -390,6 +395,7 @@ static void register_with_new_peer(n2n_edge_t *eee, uint8_t from_supernode, const n2n_mac_t mac, const n2n_ip_subnet_t *dev_addr, + const n2n_desc_t *dev_desc, const n2n_sock_t *peer) { /* REVISIT: purge of pending_peers not yet done. */ struct peer_info *scan; @@ -463,6 +469,7 @@ static void register_with_new_peer(n2n_edge_t *eee, if(dev_addr != NULL){ memcpy(&(scan->dev_addr), dev_addr, sizeof(n2n_ip_subnet_t)); } + if (dev_desc) memcpy(scan->dev_desc, dev_desc, N2N_DESC_SIZE); } @@ -473,6 +480,7 @@ static void check_peer_registration_needed(n2n_edge_t *eee, uint8_t from_supernode, const n2n_mac_t mac, const n2n_ip_subnet_t *dev_addr, + const n2n_desc_t *dev_desc, const n2n_sock_t *peer) { struct peer_info *scan; @@ -480,7 +488,7 @@ static void check_peer_registration_needed(n2n_edge_t *eee, if (scan == NULL) { /* Not in known_peers - start the REGISTER process. */ - register_with_new_peer(eee, from_supernode, mac, dev_addr, peer); + register_with_new_peer(eee, from_supernode, mac, dev_addr, dev_desc, peer); } else { /* Already in known_peers. */ time_t now = time(NULL); @@ -490,7 +498,7 @@ static void check_peer_registration_needed(n2n_edge_t *eee, if ((now - scan->last_seen) > 0 /* >= 1 sec */) { /* Don't register too often */ - check_known_peer_sock_change(eee, from_supernode, mac, dev_addr, peer, now); + check_known_peer_sock_change(eee, from_supernode, mac, dev_addr, dev_desc, peer, now); } } } @@ -580,6 +588,7 @@ static void check_known_peer_sock_change(n2n_edge_t *eee, uint8_t from_supernode, const n2n_mac_t mac, const n2n_ip_subnet_t *dev_addr, + const n2n_desc_t *dev_desc, const n2n_sock_t *peer, time_t when) { struct peer_info *scan; @@ -611,7 +620,7 @@ static void check_known_peer_sock_change(n2n_edge_t *eee, HASH_DEL(eee->known_peers, scan); free(scan); - register_with_new_peer(eee, from_supernode, mac, dev_addr, peer); + register_with_new_peer(eee, from_supernode, mac, dev_addr, dev_desc, peer); } else { /* Don't worry about what the supernode reports, it could be seeing a different socket. */ } @@ -701,6 +710,7 @@ static void send_register_super(n2n_edge_t *eee, const n2n_sock_t *supernode, in 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)); + memcpy(reg.dev_desc, eee->conf.dev_desc, N2N_DESC_SIZE); reg.auth.scheme = 0; /* No auth yet */ idx = 0; @@ -788,6 +798,7 @@ static void send_register(n2n_edge_t * eee, } reg.dev_addr.net_addr = ntohl(eee->device.ip_addr); reg.dev_addr.net_bitlen = mask2bitlen(ntohl(eee->device.device_mask)); + memcpy(reg.dev_desc, eee->conf.dev_desc, N2N_DESC_SIZE); idx=0; @@ -1220,9 +1231,9 @@ static void readFromMgmtSocket(n2n_edge_t *eee, int *keep_running) { "community: %s\n", eee->conf.community_name); msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), - " id tun_tap MAC edge last_seen\n"); + " id tun_tap MAC edge hint last_seen\n"); msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), - "------------------------------------------------------------------------------\n"); + "-----------------------------------------------------------------------------------------------\n"); msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), "supernode_forward:\n"); @@ -1232,10 +1243,12 @@ static void readFromMgmtSocket(n2n_edge_t *eee, int *keep_running) { if(peer->dev_addr.net_addr == 0) continue; net = htonl(peer->dev_addr.net_addr); msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), - " %-4u %-15s %-17s %-21s %lu\n", + " %-4u %-15s %-17s %-21s %-15s %lu\n", ++num, inet_ntoa(*(struct in_addr *) &net), macaddr_str(mac_buf, peer->mac_addr), - sock_to_cstr(sockbuf, &(peer->sock)), now - peer->last_seen); + sock_to_cstr(sockbuf, &(peer->sock)), + peer->dev_desc, + now - peer->last_seen); sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); @@ -1250,10 +1263,12 @@ static void readFromMgmtSocket(n2n_edge_t *eee, int *keep_running) { if(peer->dev_addr.net_addr == 0) continue; net = htonl(peer->dev_addr.net_addr); msg_len += snprintf((char *) (udp_buf + msg_len), (N2N_PKT_BUF_SIZE - msg_len), - " %-4u %-15s %-17s %-21s %lu\n", + " %-4u %-15s %-17s %-21s %-15s %lu\n", ++num, inet_ntoa(*(struct in_addr *) &net), macaddr_str(mac_buf, peer->mac_addr), - sock_to_cstr(sockbuf, &(peer->sock)), now - peer->last_seen); + sock_to_cstr(sockbuf, &(peer->sock)), + peer->dev_desc, + now - peer->last_seen); sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0/*flags*/, (struct sockaddr *) &sender_sock, sizeof(struct sockaddr_in)); @@ -1746,7 +1761,7 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) { } /* Update the sender in peer table entry */ - check_peer_registration_needed(eee, from_supernode, pkt.srcMac, NULL, orig_sender); + check_peer_registration_needed(eee, from_supernode, pkt.srcMac, NULL, NULL, orig_sender); handle_PACKET(eee, from_supernode, &pkt, orig_sender, udp_buf+idx, recvlen-idx); break; @@ -1800,7 +1815,7 @@ void readFromIPSocket(n2n_edge_t * eee, int in_sock) { sock_to_cstr(sockbuf1, &sender), sock_to_cstr(sockbuf2, orig_sender)); } - check_peer_registration_needed(eee, from_supernode, reg.srcMac, ®.dev_addr, orig_sender); + check_peer_registration_needed(eee, from_supernode, reg.srcMac, ®.dev_addr, ®.dev_desc, orig_sender); break; } case MSG_TYPE_REGISTER_ACK: @@ -2615,6 +2630,8 @@ void edge_init_conf_defaults(n2n_edge_conf_t *conf) { conf->disable_pmtu_discovery = 1; conf->register_interval = REGISTER_SUPER_INTERVAL_DFL; conf->tuntap_ip_mode = TUNTAP_IP_MODE_SN_ASSIGN; + /* reserve possible last char as null terminator. */ + gethostname((char*)conf->dev_desc, N2N_DESC_SIZE-1); if (getenv("N2N_KEY")) { conf->encrypt_key = strdup(getenv("N2N_KEY")); diff --git a/src/sn_utils.c b/src/sn_utils.c index eed0501..4560308 100644 --- a/src/sn_utils.c +++ b/src/sn_utils.c @@ -339,6 +339,7 @@ static int update_edge(n2n_sn_t *sss, 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((char*)scan->dev_desc, reg->dev_desc, N2N_DESC_SIZE); memcpy(&(scan->sock), sender_sock, sizeof(n2n_sock_t)); scan->last_valid_time_stamp = initial_time_stamp(); @@ -647,9 +648,9 @@ static int process_mgmt(n2n_sn_t *sss, traceEvent(TRACE_DEBUG, "process_mgmt"); ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - " id tun_tap MAC edge last_seen\n"); + " id tun_tap MAC edge hint last_seen\n"); ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - "---------------------------------------------------------------------------------\n"); + "-------------------------------------------------------------------------------------------------\n"); HASH_ITER(hh, sss->communities, community, tmp) { num_edges += HASH_COUNT(community->edges); ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, @@ -660,17 +661,19 @@ static int process_mgmt(n2n_sn_t *sss, num = 0; HASH_ITER(hh, community->edges, peer, tmpPeer) { ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, - " %-4u %-18s %-17s %-21s %lu\n", + " %-4u %-18s %-17s %-21s %-15s %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); + sock_to_cstr(sockbuf, &(peer->sock)), + peer->dev_desc, + 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"); + "-------------------------------------------------------------------------------------------------\n"); ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize, "uptime %lu | ", (now - sss->start_time)); diff --git a/src/wire.c b/src/wire.c index 4c18bc4..1dc1003 100644 --- a/src/wire.c +++ b/src/wire.c @@ -288,6 +288,7 @@ int encode_REGISTER(uint8_t *base, } retval += encode_uint32(base, idx, reg->dev_addr.net_addr); retval += encode_uint8(base, idx, reg->dev_addr.net_bitlen); + retval += encode_buf(base, idx, reg->dev_desc, N2N_DESC_SIZE); return retval; } @@ -309,6 +310,7 @@ int decode_REGISTER(n2n_REGISTER_t *reg, } retval += decode_uint32(&(reg->dev_addr.net_addr), base, rem, idx); retval += decode_uint8(&(reg->dev_addr.net_bitlen), base, rem, idx); + retval += decode_buf(reg->dev_desc, N2N_DESC_SIZE, base, rem, idx); return retval; } @@ -324,6 +326,7 @@ int encode_REGISTER_SUPER(uint8_t *base, 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_buf(base, idx, reg->dev_desc, N2N_DESC_SIZE); retval += encode_uint16(base, idx, 0); /* NULL auth scheme */ retval += encode_uint16(base, idx, 0); /* No auth data */ @@ -342,6 +345,7 @@ int decode_REGISTER_SUPER(n2n_REGISTER_SUPER_t *reg, 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_buf(reg->dev_desc, N2N_DESC_SIZE, 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);