Browse Source

Implement query peer to try p2p during send

When a lot of monodirection traffic is sent, p2p can be hard to
enstablish because a reply is needed in order to start the registration.
Now a sending peer can query the peer information via the supernode.

This is based on the following commits:
- 1236f37a70
- ad2d416510
- 5348671299
- b2806dcde8
pull/128/head
emanuele-f 6 years ago
parent
commit
f36814b152
  1. 90
      edge_utils.c
  2. 4
      n2n.h
  3. 97
      n2n_wire.h
  4. 36
      sn.c
  5. 55
      wire.c

90
edge_utils.c

@ -405,7 +405,8 @@ static void register_with_new_peer(n2n_edge_t * eee,
} }
register_with_local_peers(eee); register_with_local_peers(eee);
} } else
scan->sock = *peer;
} }
/* ************************************** */ /* ************************************** */
@ -656,6 +657,32 @@ static void send_register_super(n2n_edge_t * eee,
/* ************************************** */ /* ************************************** */
/** Send a QUERY_PEER packet to the current supernode. */
static void send_query_peer( n2n_edge_t * eee,
const n2n_mac_t dstMac) {
uint8_t pktbuf[N2N_PKT_BUF_SIZE];
size_t idx;
n2n_common_t cmn = {0};
n2n_QUERY_PEER_t query = {{0}};
cmn.ttl=N2N_DEFAULT_TTL;
cmn.pc = n2n_query_peer;
cmn.flags = 0;
memcpy( cmn.community, eee->conf.community_name, N2N_COMMUNITY_SIZE );
idx=0;
encode_mac( query.srcMac, &idx, eee->device.mac_addr );
idx=0;
encode_mac( query.targetMac, &idx, dstMac );
idx=0;
encode_QUERY_PEER( pktbuf, &idx, &cmn, &query );
traceEvent( TRACE_DEBUG, "send QUERY_PEER to supernode" );
sendto_sock( eee->udp_sock, pktbuf, idx, &(eee->supernode) );
}
/** Send a REGISTER packet to another edge. */ /** Send a REGISTER packet to another edge. */
static void send_register(n2n_edge_t * eee, static void send_register(n2n_edge_t * eee,
const n2n_sock_t * remote_peer, const n2n_sock_t * remote_peer,
@ -1076,6 +1103,37 @@ static int is_ethMulticast(const void * buf, size_t bufsize) {
/* ************************************** */ /* ************************************** */
static int check_query_peer_info(n2n_edge_t *eee, time_t now, n2n_mac_t mac) {
struct peer_info *scan = eee->pending_peers;
while(scan != NULL) {
if(memcmp(scan->mac_addr, mac, N2N_MAC_SIZE) == 0)
break;
scan = scan->next;
}
if(!scan) {
scan = calloc(1, sizeof(struct peer_info));
memcpy(scan->mac_addr, mac, N2N_MAC_SIZE);
scan->timeout = REGISTER_SUPER_INTERVAL_DFL; /* TODO: should correspond to the peer supernode registration timeout */
update_peer_seen(scan, now); /* Don't change this it marks the pending peer for removal. */
peer_list_add(&(eee->pending_peers), scan);
}
if(now - scan->last_sent_query > REGISTER_SUPER_INTERVAL_DFL) {
send_query_peer(eee, scan->mac_addr);
scan->last_sent_query = now;
return(0);
}
return(1);
}
/* ************************************** */
/* @return 1 if destination is a peer, 0 if destination is supernode */ /* @return 1 if destination is a peer, 0 if destination is supernode */
static int find_peer_destination(n2n_edge_t * eee, static int find_peer_destination(n2n_edge_t * eee,
n2n_mac_t mac_address, n2n_mac_t mac_address,
@ -1129,6 +1187,8 @@ static int find_peer_destination(n2n_edge_t * eee,
traceEvent(TRACE_DEBUG, "P2P Peer [MAC=%02X:%02X:%02X:%02X:%02X:%02X] not found, using supernode", traceEvent(TRACE_DEBUG, "P2P Peer [MAC=%02X:%02X:%02X:%02X:%02X:%02X] not found, using supernode",
mac_address[0] & 0xFF, mac_address[1] & 0xFF, mac_address[2] & 0xFF, mac_address[0] & 0xFF, mac_address[1] & 0xFF, mac_address[2] & 0xFF,
mac_address[3] & 0xFF, mac_address[4] & 0xFF, mac_address[5] & 0xFF); mac_address[3] & 0xFF, mac_address[4] & 0xFF, mac_address[5] & 0xFF);
check_query_peer_info(eee, now, mac_address);
} }
traceEvent(TRACE_DEBUG, "find_peer_address (%s) -> [%s]", traceEvent(TRACE_DEBUG, "find_peer_address (%s) -> [%s]",
@ -1174,7 +1234,7 @@ static int send_packet(n2n_edge_t * eee,
/* ************************************** */ /* ************************************** */
/** A layer-2 packet was received at the tunnel and needs to be sent via UDP. */ /** A layer-2 packet was received at the tunnel and needs to be sent via UDP. */
void send_packet2net(n2n_edge_t * eee, static void send_packet2net(n2n_edge_t * eee,
uint8_t *tap_pkt, size_t len) { uint8_t *tap_pkt, size_t len) {
ipstr_t ip_buf; ipstr_t ip_buf;
n2n_mac_t destMac; n2n_mac_t destMac;
@ -1517,6 +1577,32 @@ static void readFromIPSocket(n2n_edge_t * eee, int in_sock) {
traceEvent(TRACE_WARNING, "Rx REGISTER_SUPER_ACK with no outstanding REGISTER_SUPER."); traceEvent(TRACE_WARNING, "Rx REGISTER_SUPER_ACK with no outstanding REGISTER_SUPER.");
} }
break; break;
} case MSG_TYPE_PEER_INFO: {
n2n_PEER_INFO_t pi;
struct peer_info * scan;
decode_PEER_INFO( &pi, &cmn, udp_buf, &rem, &idx );
if(!is_valid_peer_sock(&pi.sock)) {
char sockbuf[64];
traceEvent(TRACE_DEBUG, "Skip invalid PEER_INFO %s [%s]",
sock_to_cstr(sockbuf, &pi.sock),
macaddr_str(mac_buf1, pi.mac) );
break;
}
scan = find_peer_by_mac( eee->pending_peers, pi.mac );
if (scan) {
scan->sock = pi.sock;
traceEvent(TRACE_INFO, "Rx PEER_INFO on %s",
macaddr_str(mac_buf1, pi.mac) );
send_register(eee, &scan->sock, scan->mac_addr);
} else {
traceEvent(TRACE_INFO, "Rx PEER_INFO unknown peer %s",
macaddr_str(mac_buf1, pi.mac) );
}
break;
} }
default: default:
/* Not a known message type */ /* Not a known message type */

4
n2n.h

@ -150,6 +150,8 @@ typedef struct tuntap_dev {
#define MSG_TYPE_REGISTER_SUPER_ACK 6 #define MSG_TYPE_REGISTER_SUPER_ACK 6
#define MSG_TYPE_REGISTER_SUPER_NAK 7 #define MSG_TYPE_REGISTER_SUPER_NAK 7
#define MSG_TYPE_FEDERATION 8 #define MSG_TYPE_FEDERATION 8
#define MSG_TYPE_PEER_INFO 9
#define MSG_TYPE_QUERY_PEER 10
/* Set N2N_COMPRESSION_ENABLED to 0 to disable lzo1x compression of ethernet /* Set N2N_COMPRESSION_ENABLED to 0 to disable lzo1x compression of ethernet
* frames. Doing this will break compatibility with the standard n2n packet * frames. Doing this will break compatibility with the standard n2n packet
@ -174,6 +176,7 @@ struct peer_info {
int timeout; int timeout;
time_t last_seen; time_t last_seen;
time_t last_p2p; time_t last_p2p;
time_t last_sent_query;
}; };
#define N2N_EDGE_SN_HOST_SIZE 48 #define N2N_EDGE_SN_HOST_SIZE 48
@ -298,5 +301,4 @@ int quick_edge_init(char *device_name, char *community_name,
char *supernode_ip_address_port, char *supernode_ip_address_port,
int *keep_on_running); int *keep_on_running);
void send_packet2net(n2n_edge_t * eee, uint8_t *tap_pkt, size_t len);
#endif /* _N2N_H_ */ #endif /* _N2N_H_ */

97
n2n_wire.h

@ -61,7 +61,9 @@ typedef enum n2n_pc
n2n_register_super=5, /* Register edge to supernode */ n2n_register_super=5, /* Register edge to supernode */
n2n_register_super_ack=6, /* ACK from supernode to edge */ n2n_register_super_ack=6, /* ACK from supernode to edge */
n2n_register_super_nak=7, /* NAK from supernode to edge - registration refused */ n2n_register_super_nak=7, /* NAK from supernode to edge - registration refused */
n2n_federation=8 /* Not used by edge */ n2n_federation=8, /* Not used by edge */
n2n_peer_info=9, /* Send info on a peer from sn to edge */
n2n_query_peer=10 /* ask supernode for info on a peer */
} n2n_pc_t; } n2n_pc_t;
#define N2N_FLAGS_OPTIONS 0x0080 #define N2N_FLAGS_OPTIONS 0x0080
@ -84,7 +86,7 @@ typedef enum n2n_pc
#define N2N_EINVAL -3 #define N2N_EINVAL -3
#define N2N_ENOSPACE -4 #define N2N_ENOSPACE -4
struct n2n_sock typedef struct n2n_sock
{ {
uint8_t family; /* AF_INET or AF_INET6; or 0 if invalid */ uint8_t family; /* AF_INET or AF_INET6; or 0 if invalid */
uint16_t port; /* host order */ uint16_t port; /* host order */
@ -93,75 +95,58 @@ struct n2n_sock
uint8_t v6[IPV6_SIZE]; /* byte sequence */ uint8_t v6[IPV6_SIZE]; /* byte sequence */
uint8_t v4[IPV4_SIZE]; /* byte sequence */ uint8_t v4[IPV4_SIZE]; /* byte sequence */
} addr; } addr;
}; } n2n_sock_t;
typedef struct n2n_sock n2n_sock_t; typedef struct n2n_auth
struct n2n_auth
{ {
uint16_t scheme; /* What kind of auth */ uint16_t scheme; /* What kind of auth */
uint16_t toksize; /* Size of auth token */ uint16_t toksize; /* Size of auth token */
uint8_t token[N2N_AUTH_TOKEN_SIZE]; /* Auth data interpreted based on scheme */ uint8_t token[N2N_AUTH_TOKEN_SIZE]; /* Auth data interpreted based on scheme */
}; } n2n_auth_t;
typedef struct n2n_auth n2n_auth_t;
typedef struct n2n_common
struct n2n_common
{ {
/* int version; */ /* int version; */
uint8_t ttl; uint8_t ttl;
uint8_t pc; uint8_t pc;
uint16_t flags; uint16_t flags;
n2n_community_t community; n2n_community_t community;
}; } n2n_common_t;
typedef struct n2n_common n2n_common_t;
struct n2n_REGISTER typedef struct n2n_REGISTER
{ {
n2n_cookie_t cookie; /* Link REGISTER and REGISTER_ACK */ n2n_cookie_t cookie; /* Link REGISTER and REGISTER_ACK */
n2n_mac_t srcMac; /* MAC of registering party */ n2n_mac_t srcMac; /* MAC of registering party */
n2n_mac_t dstMac; /* MAC of target edge */ n2n_mac_t dstMac; /* MAC of target edge */
n2n_sock_t sock; /* REVISIT: unused? */ n2n_sock_t sock; /* REVISIT: unused? */
}; } n2n_REGISTER_t;
typedef struct n2n_REGISTER n2n_REGISTER_t; typedef struct n2n_REGISTER_ACK
struct n2n_REGISTER_ACK
{ {
n2n_cookie_t cookie; /* Return cookie from REGISTER */ n2n_cookie_t cookie; /* Return cookie from REGISTER */
n2n_mac_t srcMac; /* MAC of acknowledging party (supernode or edge) */ n2n_mac_t srcMac; /* MAC of acknowledging party (supernode or edge) */
n2n_mac_t dstMac; /* Reflected MAC of registering edge from REGISTER */ 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_sock_t sock; /* Supernode's view of edge socket (IP Addr, port) */
}; } n2n_REGISTER_ACK_t;
typedef struct n2n_REGISTER_ACK n2n_REGISTER_ACK_t;
struct n2n_PACKET typedef struct n2n_PACKET
{ {
n2n_mac_t srcMac; n2n_mac_t srcMac;
n2n_mac_t dstMac; n2n_mac_t dstMac;
n2n_sock_t sock; n2n_sock_t sock;
uint16_t transform; uint16_t transform;
}; } n2n_PACKET_t;
typedef struct n2n_PACKET n2n_PACKET_t;
/* Linked with n2n_register_super in n2n_pc_t. Only from edge to supernode. */ /* Linked with n2n_register_super in n2n_pc_t. Only from edge to supernode. */
struct n2n_REGISTER_SUPER typedef struct n2n_REGISTER_SUPER
{ {
n2n_cookie_t cookie; /* Link REGISTER_SUPER and REGISTER_SUPER_ACK */ n2n_cookie_t cookie; /* Link REGISTER_SUPER and REGISTER_SUPER_ACK */
n2n_mac_t edgeMac; /* MAC to register with edge sending socket */ n2n_mac_t edgeMac; /* MAC to register with edge sending socket */
n2n_auth_t auth; /* Authentication scheme and tokens */ n2n_auth_t auth; /* Authentication scheme and tokens */
}; } n2n_REGISTER_SUPER_t;
typedef struct n2n_REGISTER_SUPER n2n_REGISTER_SUPER_t;
/* Linked with n2n_register_super_ack in n2n_pc_t. Only from supernode to edge. */ /* Linked with n2n_register_super_ack in n2n_pc_t. Only from supernode to edge. */
struct n2n_REGISTER_SUPER_ACK typedef struct n2n_REGISTER_SUPER_ACK
{ {
n2n_cookie_t cookie; /* Return cookie from REGISTER_SUPER */ n2n_cookie_t cookie; /* Return cookie from REGISTER_SUPER */
n2n_mac_t edgeMac; /* MAC registered to edge sending socket */ n2n_mac_t edgeMac; /* MAC registered to edge sending socket */
@ -177,26 +162,27 @@ struct n2n_REGISTER_SUPER_ACK
* non-zero then sn_bak is valid. */ * 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;
typedef struct n2n_REGISTER_SUPER_ACK n2n_REGISTER_SUPER_ACK_t;
/* Linked with n2n_register_super_ack in n2n_pc_t. Only from supernode to edge. */ /* Linked with n2n_register_super_ack in n2n_pc_t. Only from supernode to edge. */
struct n2n_REGISTER_SUPER_NAK typedef struct n2n_REGISTER_SUPER_NAK
{ {
n2n_cookie_t cookie; /* Return cookie from REGISTER_SUPER */ n2n_cookie_t cookie; /* Return cookie from REGISTER_SUPER */
}; } n2n_REGISTER_SUPER_NAK_t;
typedef struct n2n_REGISTER_SUPER_NAK n2n_REGISTER_SUPER_NAK_t;
typedef struct n2n_PEER_INFO
{
uint16_t aflags;
n2n_mac_t mac;
n2n_sock_t sock;
} n2n_PEER_INFO_t;
struct n2n_buf typedef struct n2n_QUERY_PEER
{ {
uint8_t * data; n2n_mac_t srcMac;
size_t size; n2n_mac_t targetMac;
}; } n2n_QUERY_PEER_t;
typedef struct n2n_buf n2n_buf_t; typedef struct n2n_buf n2n_buf_t;
@ -324,5 +310,26 @@ int decode_PACKET( n2n_PACKET_t * pkt,
size_t * rem, size_t * rem,
size_t * idx ); size_t * idx );
int encode_PEER_INFO( uint8_t * base,
size_t * idx,
const n2n_common_t * common,
const n2n_PEER_INFO_t * pkt );
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 );
int encode_QUERY_PEER( uint8_t * base,
size_t * idx,
const n2n_common_t * common,
const n2n_QUERY_PEER_t * pkt );
int decode_QUERY_PEER( n2n_QUERY_PEER_t * pkt,
const n2n_common_t * cmn, /* info on how to interpret it */
const uint8_t * base,
size_t * rem,
size_t * idx );
#endif /* #if !defined( N2N_WIRE_H_ ) */ #endif /* #if !defined( N2N_WIRE_H_ ) */

36
sn.c

@ -670,6 +670,42 @@ static int process_udp(n2n_sn_t * sss,
traceEvent(TRACE_INFO, "Discarded registration: unallowed community '%s'", traceEvent(TRACE_INFO, "Discarded registration: unallowed community '%s'",
(char*)cmn.community); (char*)cmn.community);
break; break;
} case MSG_TYPE_QUERY_PEER: {
n2n_QUERY_PEER_t query;
uint8_t encbuf[N2N_SN_PKTBUF_SIZE];
size_t encx=0;
n2n_common_t cmn2;
n2n_PEER_INFO_t pi;
struct peer_info *scan;
decode_QUERY_PEER( &query, &cmn, udp_buf, &rem, &idx );
traceEvent( TRACE_DEBUG, "Rx QUERY_PEER from %s for %s",
macaddr_str( mac_buf, query.srcMac ),
macaddr_str( mac_buf2, query.targetMac ) );
scan = find_peer_by_mac( sss->edges, query.targetMac );
if (scan) {
cmn2.ttl = N2N_DEFAULT_TTL;
cmn2.pc = n2n_peer_info;
cmn2.flags = N2N_FLAGS_FROM_SUPERNODE;
memcpy( cmn2.community, cmn.community, sizeof(n2n_community_t) );
pi.aflags = 0;
memcpy( pi.mac, query.targetMac, sizeof(n2n_mac_t) );
pi.sock = scan->sock;
encode_PEER_INFO( encbuf, &encx, &cmn2, &pi );
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 ) );
} else {
traceEvent( TRACE_DEBUG, "Ignoring QUERY_PEER for unknown edge %s",
macaddr_str( mac_buf, query.targetMac ) );
}
} }
default: default:
/* Not a known message type */ /* Not a known message type */

55
wire.c

@ -475,3 +475,58 @@ int decode_PACKET( n2n_PACKET_t * pkt,
return retval; 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 encode_QUERY_PEER( uint8_t * base,
size_t * idx,
const n2n_common_t * common,
const n2n_QUERY_PEER_t * pkt )
{
int retval=0;
retval += encode_common( base, idx, common );
retval += encode_mac( base, idx, pkt->srcMac );
retval += encode_mac( base, idx, pkt->targetMac );
return retval;
}
int decode_QUERY_PEER( n2n_QUERY_PEER_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_QUERY_PEER_t) );
retval += decode_mac( pkt->srcMac, base, rem, idx );
retval += decode_mac( pkt->targetMac, base, rem, idx );
return retval;
}

Loading…
Cancel
Save