mirror of
https://github.com/ntop/n2n.git
synced 2024-09-19 16:41:11 +02:00
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
This commit is contained in:
parent
b36754eae0
commit
f36814b152
90
edge_utils.c
90
edge_utils.c
|
@ -405,7 +405,8 @@ static void register_with_new_peer(n2n_edge_t * 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. */
|
||||
static void send_register(n2n_edge_t * eee,
|
||||
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 */
|
||||
static int find_peer_destination(n2n_edge_t * eee,
|
||||
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",
|
||||
mac_address[0] & 0xFF, mac_address[1] & 0xFF, mac_address[2] & 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]",
|
||||
|
@ -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. */
|
||||
void send_packet2net(n2n_edge_t * eee,
|
||||
static void send_packet2net(n2n_edge_t * eee,
|
||||
uint8_t *tap_pkt, size_t len) {
|
||||
ipstr_t ip_buf;
|
||||
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.");
|
||||
}
|
||||
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:
|
||||
/* Not a known message type */
|
||||
|
|
4
n2n.h
4
n2n.h
|
@ -150,6 +150,8 @@ typedef struct tuntap_dev {
|
|||
#define MSG_TYPE_REGISTER_SUPER_ACK 6
|
||||
#define MSG_TYPE_REGISTER_SUPER_NAK 7
|
||||
#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
|
||||
* frames. Doing this will break compatibility with the standard n2n packet
|
||||
|
@ -174,6 +176,7 @@ struct peer_info {
|
|||
int timeout;
|
||||
time_t last_seen;
|
||||
time_t last_p2p;
|
||||
time_t last_sent_query;
|
||||
};
|
||||
|
||||
#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,
|
||||
int *keep_on_running);
|
||||
|
||||
void send_packet2net(n2n_edge_t * eee, uint8_t *tap_pkt, size_t len);
|
||||
#endif /* _N2N_H_ */
|
||||
|
|
139
n2n_wire.h
139
n2n_wire.h
|
@ -61,7 +61,9 @@ typedef enum n2n_pc
|
|||
n2n_register_super=5, /* Register edge to supernode */
|
||||
n2n_register_super_ack=6, /* ACK from supernode to edge */
|
||||
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;
|
||||
|
||||
#define N2N_FLAGS_OPTIONS 0x0080
|
||||
|
@ -84,91 +86,74 @@ typedef enum n2n_pc
|
|||
#define N2N_EINVAL -3
|
||||
#define N2N_ENOSPACE -4
|
||||
|
||||
struct n2n_sock
|
||||
typedef struct n2n_sock
|
||||
{
|
||||
uint8_t family; /* AF_INET or AF_INET6; or 0 if invalid */
|
||||
uint16_t port; /* host order */
|
||||
union
|
||||
union
|
||||
{
|
||||
uint8_t v6[IPV6_SIZE]; /* byte sequence */
|
||||
uint8_t v4[IPV4_SIZE]; /* byte sequence */
|
||||
} addr;
|
||||
};
|
||||
} n2n_sock_t;
|
||||
|
||||
typedef struct n2n_sock n2n_sock_t;
|
||||
|
||||
struct n2n_auth
|
||||
typedef struct n2n_auth
|
||||
{
|
||||
uint16_t scheme; /* What kind of auth */
|
||||
uint16_t toksize; /* Size of auth token */
|
||||
uint8_t token[N2N_AUTH_TOKEN_SIZE]; /* Auth data interpreted based on scheme */
|
||||
};
|
||||
} n2n_auth_t;
|
||||
|
||||
typedef struct n2n_auth n2n_auth_t;
|
||||
|
||||
|
||||
struct n2n_common
|
||||
typedef struct n2n_common
|
||||
{
|
||||
/* int version; */
|
||||
uint8_t ttl;
|
||||
uint8_t pc;
|
||||
uint16_t flags;
|
||||
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_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 n2n_REGISTER_t;
|
||||
|
||||
struct n2n_REGISTER_ACK
|
||||
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_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 dstMac;
|
||||
n2n_sock_t sock;
|
||||
uint16_t transform;
|
||||
};
|
||||
|
||||
typedef struct n2n_PACKET n2n_PACKET_t;
|
||||
|
||||
} n2n_PACKET_t;
|
||||
|
||||
/* 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_mac_t edgeMac; /* MAC to register with edge sending socket */
|
||||
n2n_auth_t auth; /* Authentication scheme and tokens */
|
||||
};
|
||||
|
||||
typedef struct n2n_REGISTER_SUPER n2n_REGISTER_SUPER_t;
|
||||
|
||||
} n2n_REGISTER_SUPER_t;
|
||||
|
||||
/* 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_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.
|
||||
/* The packet format provides additional supernode definitions here.
|
||||
* uint8_t count, then for each count there is one
|
||||
* n2n_sock_t.
|
||||
*/
|
||||
|
@ -177,30 +162,31 @@ struct n2n_REGISTER_SUPER_ACK
|
|||
* non-zero then sn_bak is valid. */
|
||||
n2n_sock_t sn_bak; /* Socket of the first backup supernode */
|
||||
|
||||
};
|
||||
|
||||
typedef struct n2n_REGISTER_SUPER_ACK n2n_REGISTER_SUPER_ACK_t;
|
||||
} n2n_REGISTER_SUPER_ACK_t;
|
||||
|
||||
|
||||
/* 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_REGISTER_SUPER_NAK_t;
|
||||
|
||||
typedef struct n2n_REGISTER_SUPER_NAK n2n_REGISTER_SUPER_NAK_t;
|
||||
|
||||
|
||||
|
||||
struct n2n_buf
|
||||
typedef struct n2n_PEER_INFO
|
||||
{
|
||||
uint8_t * data;
|
||||
size_t size;
|
||||
};
|
||||
uint16_t aflags;
|
||||
n2n_mac_t mac;
|
||||
n2n_sock_t sock;
|
||||
} n2n_PEER_INFO_t;
|
||||
|
||||
typedef struct n2n_QUERY_PEER
|
||||
{
|
||||
n2n_mac_t srcMac;
|
||||
n2n_mac_t targetMac;
|
||||
} n2n_QUERY_PEER_t;
|
||||
|
||||
typedef struct n2n_buf n2n_buf_t;
|
||||
|
||||
int encode_uint8( uint8_t * base,
|
||||
int encode_uint8( uint8_t * base,
|
||||
size_t * idx,
|
||||
const uint8_t v );
|
||||
|
||||
|
@ -209,7 +195,7 @@ int decode_uint8( uint8_t * out,
|
|||
size_t * rem,
|
||||
size_t * idx );
|
||||
|
||||
int encode_uint16( uint8_t * base,
|
||||
int encode_uint16( uint8_t * base,
|
||||
size_t * idx,
|
||||
const uint16_t v );
|
||||
|
||||
|
@ -218,7 +204,7 @@ int decode_uint16( uint16_t * out,
|
|||
size_t * rem,
|
||||
size_t * idx );
|
||||
|
||||
int encode_uint32( uint8_t * base,
|
||||
int encode_uint32( uint8_t * base,
|
||||
size_t * idx,
|
||||
const uint32_t v );
|
||||
|
||||
|
@ -227,9 +213,9 @@ int decode_uint32( uint32_t * out,
|
|||
size_t * rem,
|
||||
size_t * idx );
|
||||
|
||||
int encode_buf( uint8_t * base,
|
||||
int encode_buf( uint8_t * base,
|
||||
size_t * idx,
|
||||
const void * p,
|
||||
const void * p,
|
||||
size_t s);
|
||||
|
||||
int decode_buf( uint8_t * out,
|
||||
|
@ -238,7 +224,7 @@ int decode_buf( uint8_t * out,
|
|||
size_t * rem,
|
||||
size_t * idx );
|
||||
|
||||
int encode_mac( uint8_t * base,
|
||||
int encode_mac( uint8_t * base,
|
||||
size_t * idx,
|
||||
const n2n_mac_t m );
|
||||
|
||||
|
@ -247,7 +233,7 @@ int decode_mac( uint8_t * out, /* of size N2N_MAC_SIZE. This clearer than passin
|
|||
size_t * rem,
|
||||
size_t * idx );
|
||||
|
||||
int encode_common( uint8_t * base,
|
||||
int encode_common( uint8_t * base,
|
||||
size_t * idx,
|
||||
const n2n_common_t * common );
|
||||
|
||||
|
@ -256,7 +242,7 @@ int decode_common( n2n_common_t * out,
|
|||
size_t * rem,
|
||||
size_t * idx );
|
||||
|
||||
int encode_sock( uint8_t * base,
|
||||
int encode_sock( uint8_t * base,
|
||||
size_t * idx,
|
||||
const n2n_sock_t * sock );
|
||||
|
||||
|
@ -265,9 +251,9 @@ int decode_sock( n2n_sock_t * sock,
|
|||
size_t * rem,
|
||||
size_t * idx );
|
||||
|
||||
int encode_REGISTER( uint8_t * base,
|
||||
int encode_REGISTER( uint8_t * base,
|
||||
size_t * idx,
|
||||
const n2n_common_t * common,
|
||||
const n2n_common_t * common,
|
||||
const n2n_REGISTER_t * reg );
|
||||
|
||||
int decode_REGISTER( n2n_REGISTER_t * pkt,
|
||||
|
@ -276,9 +262,9 @@ int decode_REGISTER( n2n_REGISTER_t * pkt,
|
|||
size_t * rem,
|
||||
size_t * idx );
|
||||
|
||||
int encode_REGISTER_SUPER( uint8_t * base,
|
||||
int encode_REGISTER_SUPER( uint8_t * base,
|
||||
size_t * idx,
|
||||
const n2n_common_t * common,
|
||||
const n2n_common_t * common,
|
||||
const n2n_REGISTER_SUPER_t * reg );
|
||||
|
||||
int decode_REGISTER_SUPER( n2n_REGISTER_SUPER_t * pkt,
|
||||
|
@ -287,9 +273,9 @@ int decode_REGISTER_SUPER( n2n_REGISTER_SUPER_t * pkt,
|
|||
size_t * rem,
|
||||
size_t * idx );
|
||||
|
||||
int encode_REGISTER_ACK( uint8_t * base,
|
||||
int encode_REGISTER_ACK( uint8_t * base,
|
||||
size_t * idx,
|
||||
const n2n_common_t * common,
|
||||
const n2n_common_t * common,
|
||||
const n2n_REGISTER_ACK_t * reg );
|
||||
|
||||
int decode_REGISTER_ACK( n2n_REGISTER_ACK_t * pkt,
|
||||
|
@ -309,13 +295,13 @@ int decode_REGISTER_SUPER_ACK( n2n_REGISTER_SUPER_ACK_t * reg,
|
|||
size_t * rem,
|
||||
size_t * idx );
|
||||
|
||||
int fill_sockaddr( struct sockaddr * addr,
|
||||
size_t addrlen,
|
||||
int fill_sockaddr( struct sockaddr * addr,
|
||||
size_t addrlen,
|
||||
const n2n_sock_t * sock );
|
||||
|
||||
int encode_PACKET( uint8_t * base,
|
||||
int encode_PACKET( uint8_t * base,
|
||||
size_t * idx,
|
||||
const n2n_common_t * common,
|
||||
const n2n_common_t * common,
|
||||
const n2n_PACKET_t * pkt );
|
||||
|
||||
int decode_PACKET( n2n_PACKET_t * pkt,
|
||||
|
@ -324,5 +310,26 @@ int decode_PACKET( n2n_PACKET_t * pkt,
|
|||
size_t * rem,
|
||||
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_ ) */
|
||||
|
|
142
sn.c
142
sn.c
|
@ -60,13 +60,13 @@ struct n2n_allowed_communities {
|
|||
|
||||
static struct n2n_allowed_communities *allowed_communities = NULL;
|
||||
|
||||
static int try_forward(n2n_sn_t * sss,
|
||||
static int try_forward(n2n_sn_t * sss,
|
||||
const n2n_common_t * cmn,
|
||||
const n2n_mac_t dstMac,
|
||||
const uint8_t * pktbuf,
|
||||
size_t pktsize);
|
||||
|
||||
static int try_broadcast(n2n_sn_t * sss,
|
||||
static int try_broadcast(n2n_sn_t * sss,
|
||||
const n2n_common_t * cmn,
|
||||
const n2n_mac_t srcMac,
|
||||
const uint8_t * pktbuf,
|
||||
|
@ -123,7 +123,7 @@ 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,
|
||||
static int update_edge(n2n_sn_t * sss,
|
||||
const n2n_mac_t edgeMac,
|
||||
const n2n_community_t community,
|
||||
const n2n_sock_t * sender_sock,
|
||||
|
@ -184,9 +184,9 @@ static int update_edge(n2n_sn_t * sss,
|
|||
*
|
||||
* @return -1 on error otherwise number of bytes sent
|
||||
*/
|
||||
static ssize_t sendto_sock(n2n_sn_t * sss,
|
||||
const n2n_sock_t * sock,
|
||||
const uint8_t * pktbuf,
|
||||
static ssize_t sendto_sock(n2n_sn_t * sss,
|
||||
const n2n_sock_t * sock,
|
||||
const uint8_t * pktbuf,
|
||||
size_t pktsize)
|
||||
{
|
||||
n2n_sock_str_t sockbuf;
|
||||
|
@ -203,7 +203,7 @@ static ssize_t sendto_sock(n2n_sn_t * sss,
|
|||
pktsize,
|
||||
sock_to_cstr(sockbuf, sock));
|
||||
|
||||
return sendto(sss->sock, pktbuf, pktsize, 0,
|
||||
return sendto(sss->sock, pktbuf, pktsize, 0,
|
||||
(const struct sockaddr *)&udpsock, sizeof(struct sockaddr_in));
|
||||
}
|
||||
else
|
||||
|
@ -219,7 +219,7 @@ static ssize_t sendto_sock(n2n_sn_t * sss,
|
|||
/** Try to forward a message to a unicast MAC. If the MAC is unknown then
|
||||
* broadcast to all edges in the destination community.
|
||||
*/
|
||||
static int try_forward(n2n_sn_t * sss,
|
||||
static int try_forward(n2n_sn_t * sss,
|
||||
const n2n_common_t * cmn,
|
||||
const n2n_mac_t dstMac,
|
||||
const uint8_t * pktbuf,
|
||||
|
@ -260,7 +260,7 @@ static int try_forward(n2n_sn_t * sss,
|
|||
|
||||
/* Not a known MAC so drop. */
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -270,7 +270,7 @@ static int try_forward(n2n_sn_t * sss,
|
|||
* This will send the exact same datagram to zero or more edges registered to
|
||||
* the supernode.
|
||||
*/
|
||||
static int try_broadcast(n2n_sn_t * sss,
|
||||
static int try_broadcast(n2n_sn_t * sss,
|
||||
const n2n_common_t * cmn,
|
||||
const n2n_mac_t srcMac,
|
||||
const uint8_t * pktbuf,
|
||||
|
@ -283,14 +283,14 @@ static int try_broadcast(n2n_sn_t * sss,
|
|||
traceEvent(TRACE_DEBUG, "try_broadcast");
|
||||
|
||||
scan = sss->edges;
|
||||
while(scan != NULL)
|
||||
while(scan != NULL)
|
||||
{
|
||||
if(0 == (memcmp(scan->community_name, cmn->community, sizeof(n2n_community_t)))
|
||||
&& (0 != memcmp(srcMac, scan->mac_addr, sizeof(n2n_mac_t))))
|
||||
/* REVISIT: exclude if the destination socket is where the packet came from. */
|
||||
{
|
||||
int data_sent_len;
|
||||
|
||||
|
||||
data_sent_len = sendto_sock(sss, &(scan->sock), pktbuf, pktsize);
|
||||
|
||||
if(data_sent_len != pktsize)
|
||||
|
@ -302,7 +302,7 @@ static int try_broadcast(n2n_sn_t * sss,
|
|||
macaddr_str(mac_buf, scan->mac_addr),
|
||||
strerror(errno));
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
++(sss->stats.broadcast);
|
||||
traceEvent(TRACE_DEBUG, "multicast %lu to [%s] %s",
|
||||
|
@ -314,14 +314,14 @@ static int try_broadcast(n2n_sn_t * sss,
|
|||
|
||||
scan = scan->next;
|
||||
} /* while */
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int process_mgmt(n2n_sn_t * sss,
|
||||
static int process_mgmt(n2n_sn_t * sss,
|
||||
const struct sockaddr_in * sender_sock,
|
||||
const uint8_t * mgmt_buf,
|
||||
const uint8_t * mgmt_buf,
|
||||
size_t mgmt_size,
|
||||
time_t now)
|
||||
{
|
||||
|
@ -331,46 +331,46 @@ static int process_mgmt(n2n_sn_t * sss,
|
|||
|
||||
traceEvent(TRACE_DEBUG, "process_mgmt");
|
||||
|
||||
ressize += snprintf(resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize,
|
||||
ressize += snprintf(resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize,
|
||||
"----------------\n");
|
||||
|
||||
ressize += snprintf(resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize,
|
||||
ressize += snprintf(resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize,
|
||||
"uptime %lu\n", (now - sss->start_time));
|
||||
|
||||
ressize += snprintf(resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize,
|
||||
"edges %u\n",
|
||||
ressize += snprintf(resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize,
|
||||
"edges %u\n",
|
||||
(unsigned int)peer_list_size(sss->edges));
|
||||
|
||||
ressize += snprintf(resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize,
|
||||
"errors %u\n",
|
||||
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",
|
||||
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",
|
||||
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,
|
||||
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,
|
||||
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",
|
||||
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,
|
||||
ressize += snprintf(resbuf+ressize, N2N_SN_PKTBUF_SIZE-ressize,
|
||||
"last reg %lu sec ago\n",
|
||||
(long unsigned int) (now - sss->stats.last_reg_super));
|
||||
|
||||
|
||||
r = sendto(sss->mgmt_sock, resbuf, ressize, 0/*flags*/,
|
||||
r = sendto(sss->mgmt_sock, resbuf, ressize, 0/*flags*/,
|
||||
(struct sockaddr *)sender_sock, sizeof(struct sockaddr_in));
|
||||
|
||||
if(r <= 0)
|
||||
|
@ -390,13 +390,13 @@ static int process_mgmt(n2n_sn_t * sss,
|
|||
static int allowed_n2n_community(n2n_common_t *cmn) {
|
||||
if(allowed_communities != NULL) {
|
||||
struct n2n_allowed_communities *c;
|
||||
|
||||
|
||||
HASH_FIND_STR(allowed_communities, (const char*)cmn->community, c);
|
||||
return((c == NULL) ? 0 : 1);
|
||||
} else {
|
||||
/* If no allowed community is defined, all communities are allowed */
|
||||
}
|
||||
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
@ -408,18 +408,18 @@ static int load_allowed_n2n_communities(char *path) {
|
|||
FILE *fd = fopen(path, "r");
|
||||
struct n2n_allowed_communities *s, *tmp;
|
||||
uint32_t num_communities = 0;
|
||||
|
||||
|
||||
if(fd == NULL) {
|
||||
traceEvent(TRACE_WARNING, "File %s not found", path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
HASH_ITER(hh, allowed_communities, s, tmp)
|
||||
free(s);
|
||||
|
||||
|
||||
while((line = fgets(buffer, sizeof(buffer), fd)) != NULL) {
|
||||
int len = strlen(line);
|
||||
|
||||
|
||||
if((len < 2) || line[0] == '#')
|
||||
continue;
|
||||
|
||||
|
@ -431,7 +431,7 @@ static int load_allowed_n2n_communities(char *path) {
|
|||
} else
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
s = (struct n2n_allowed_communities*)malloc(sizeof(struct n2n_allowed_communities));
|
||||
|
||||
if(s != NULL) {
|
||||
|
@ -448,16 +448,16 @@ static int load_allowed_n2n_communities(char *path) {
|
|||
|
||||
traceEvent(TRACE_NORMAL, "Loaded %u communities from %s",
|
||||
num_communities, path);
|
||||
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/** Examine a datagram and determine what to do with it.
|
||||
*
|
||||
*/
|
||||
static int process_udp(n2n_sn_t * sss,
|
||||
static int process_udp(n2n_sn_t * sss,
|
||||
const struct sockaddr_in * sender_sock,
|
||||
const uint8_t * udp_buf,
|
||||
const uint8_t * udp_buf,
|
||||
size_t udp_size,
|
||||
time_t now)
|
||||
{
|
||||
|
@ -508,7 +508,7 @@ static int process_udp(n2n_sn_t * sss,
|
|||
|
||||
/* 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_PACKET_t pkt;
|
||||
n2n_common_t cmn2;
|
||||
uint8_t encbuf[N2N_SN_PKTBUF_SIZE];
|
||||
size_t encx=0;
|
||||
|
@ -576,7 +576,7 @@ static int process_udp(n2n_sn_t * sss,
|
|||
decode_REGISTER(®, &cmn, udp_buf, &rem, &idx);
|
||||
|
||||
unicast = (0 == is_multi_broadcast(reg.dstMac));
|
||||
|
||||
|
||||
if(unicast) {
|
||||
traceEvent(TRACE_DEBUG, "Rx REGISTER %s -> %s %s",
|
||||
macaddr_str(mac_buf, reg.srcMac),
|
||||
|
@ -624,7 +624,7 @@ static int process_udp(n2n_sn_t * sss,
|
|||
uint8_t ackbuf[N2N_SN_PKTBUF_SIZE];
|
||||
size_t encx=0;
|
||||
|
||||
/* Edge requesting registration with us. */
|
||||
/* Edge requesting registration with us. */
|
||||
sss->stats.last_reg_super=now;
|
||||
++(sss->stats.reg_super);
|
||||
decode_REGISTER_SUPER(®, &cmn, udp_buf, &rem, &idx);
|
||||
|
@ -660,7 +660,7 @@ static int process_udp(n2n_sn_t * sss,
|
|||
|
||||
encode_REGISTER_SUPER_ACK(ackbuf, &encx, &cmn2, &ack);
|
||||
|
||||
sendto(sss->sock, ackbuf, encx, 0,
|
||||
sendto(sss->sock, ackbuf, encx, 0,
|
||||
(struct sockaddr *)sender_sock, sizeof(struct sockaddr_in));
|
||||
|
||||
traceEvent(TRACE_DEBUG, "Tx REGISTER_SUPER_ACK for %s [%s]",
|
||||
|
@ -670,6 +670,42 @@ static int process_udp(n2n_sn_t * sss,
|
|||
traceEvent(TRACE_INFO, "Discarded registration: unallowed community '%s'",
|
||||
(char*)cmn.community);
|
||||
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:
|
||||
/* Not a known message type */
|
||||
|
@ -720,11 +756,11 @@ static int setOption(int optkey, char *_optarg, n2n_sn_t *sss) {
|
|||
case 'l': /* local-port */
|
||||
sss->lport = atoi(_optarg);
|
||||
break;
|
||||
|
||||
|
||||
case 'c': /* community file */
|
||||
load_allowed_n2n_communities(optarg);
|
||||
break;
|
||||
|
||||
|
||||
case 'f': /* foreground */
|
||||
sss->daemon = 0;
|
||||
break;
|
||||
|
@ -778,7 +814,7 @@ static char *trim(char *s) {
|
|||
|
||||
while(isspace(s[0]) || (s[0] == '"') || (s[0] == '\''))
|
||||
s++;
|
||||
|
||||
|
||||
if(s[0] == 0) return s;
|
||||
|
||||
end = &s[strlen(s) - 1];
|
||||
|
@ -861,9 +897,9 @@ static void dump_registrations(int signo) {
|
|||
char buf[32];
|
||||
time_t now = time(NULL);
|
||||
u_int num = 0;
|
||||
|
||||
|
||||
traceEvent(TRACE_NORMAL, "====================================");
|
||||
|
||||
|
||||
while(list != NULL) {
|
||||
if(list->sock.family == AF_INET)
|
||||
traceEvent(TRACE_NORMAL, "[id: %u][MAC: %s][edge: %u.%u.%u.%u:%u][community: %s][last seen: %u sec ago]",
|
||||
|
@ -910,7 +946,7 @@ int main(int argc, char * const argv[]) {
|
|||
#if defined(N2N_HAVE_DAEMON)
|
||||
if(sss_node.daemon) {
|
||||
useSyslog=1; /* traceEvent output now goes to syslog. */
|
||||
|
||||
|
||||
if(-1 == daemon(0, 0)) {
|
||||
traceEvent(TRACE_ERROR, "Failed to become daemon.");
|
||||
exit(-5);
|
||||
|
@ -940,7 +976,7 @@ int main(int argc, char * const argv[]) {
|
|||
#ifndef WIN32
|
||||
signal(SIGHUP, dump_registrations);
|
||||
#endif
|
||||
|
||||
|
||||
return run_loop(&sss_node);
|
||||
}
|
||||
|
||||
|
|
99
wire.c
99
wire.c
|
@ -29,7 +29,7 @@
|
|||
#include "n2n_wire.h"
|
||||
#include <string.h>
|
||||
|
||||
int encode_uint8( uint8_t * base,
|
||||
int encode_uint8( uint8_t * base,
|
||||
size_t * idx,
|
||||
const uint8_t v )
|
||||
{
|
||||
|
@ -51,7 +51,7 @@ int decode_uint8( uint8_t * out,
|
|||
return 1;
|
||||
}
|
||||
|
||||
int encode_uint16( uint8_t * base,
|
||||
int encode_uint16( uint8_t * base,
|
||||
size_t * idx,
|
||||
const uint16_t v )
|
||||
{
|
||||
|
@ -75,7 +75,7 @@ int decode_uint16( uint16_t * out,
|
|||
return 2;
|
||||
}
|
||||
|
||||
int encode_uint32( uint8_t * base,
|
||||
int encode_uint32( uint8_t * base,
|
||||
size_t * idx,
|
||||
const uint32_t v )
|
||||
{
|
||||
|
@ -103,9 +103,9 @@ int decode_uint32( uint32_t * out,
|
|||
return 4;
|
||||
}
|
||||
|
||||
int encode_buf( uint8_t * base,
|
||||
int encode_buf( uint8_t * base,
|
||||
size_t * idx,
|
||||
const void * p,
|
||||
const void * p,
|
||||
size_t s)
|
||||
{
|
||||
memcpy( (base + (*idx)), p, s );
|
||||
|
@ -130,7 +130,7 @@ int decode_buf( uint8_t * out,
|
|||
|
||||
|
||||
|
||||
int encode_mac( uint8_t * base,
|
||||
int encode_mac( uint8_t * base,
|
||||
size_t * idx,
|
||||
const n2n_mac_t m )
|
||||
{
|
||||
|
@ -147,7 +147,7 @@ int decode_mac( uint8_t * out, /* of size N2N_MAC_SIZE. This clearer than passin
|
|||
|
||||
|
||||
|
||||
int encode_common( uint8_t * base,
|
||||
int encode_common( uint8_t * base,
|
||||
size_t * idx,
|
||||
const n2n_common_t * common )
|
||||
{
|
||||
|
@ -160,7 +160,7 @@ int encode_common( uint8_t * base,
|
|||
|
||||
encode_uint16( base, idx, flags );
|
||||
encode_buf( base, idx, common->community, N2N_COMMUNITY_SIZE );
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -177,7 +177,7 @@ int decode_common( n2n_common_t * out,
|
|||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
decode_uint8( &(out->ttl), base, rem, idx );
|
||||
decode_uint16( &(out->flags), base, rem, idx );
|
||||
out->pc = ( out->flags & N2N_FLAGS_TYPE_MASK );
|
||||
|
@ -189,14 +189,14 @@ int decode_common( n2n_common_t * out,
|
|||
}
|
||||
|
||||
|
||||
int encode_sock( uint8_t * base,
|
||||
int encode_sock( uint8_t * base,
|
||||
size_t * idx,
|
||||
const n2n_sock_t * sock )
|
||||
{
|
||||
int retval=0;
|
||||
uint16_t f;
|
||||
|
||||
switch (sock->family)
|
||||
switch (sock->family)
|
||||
{
|
||||
case AF_INET:
|
||||
{
|
||||
|
@ -229,7 +229,7 @@ int decode_sock( n2n_sock_t * sock,
|
|||
{
|
||||
size_t * idx0=idx;
|
||||
uint16_t f=0;
|
||||
|
||||
|
||||
decode_uint16( &f, base, rem, idx );
|
||||
|
||||
if( f & 0x8000 )
|
||||
|
@ -251,9 +251,9 @@ int decode_sock( n2n_sock_t * sock,
|
|||
return (idx-idx0);
|
||||
}
|
||||
|
||||
int encode_REGISTER( uint8_t * base,
|
||||
int encode_REGISTER( uint8_t * base,
|
||||
size_t * idx,
|
||||
const n2n_common_t * common,
|
||||
const n2n_common_t * common,
|
||||
const n2n_REGISTER_t * reg )
|
||||
{
|
||||
int retval=0;
|
||||
|
@ -289,9 +289,9 @@ int decode_REGISTER( n2n_REGISTER_t * reg,
|
|||
return retval;
|
||||
}
|
||||
|
||||
int encode_REGISTER_SUPER( uint8_t * base,
|
||||
int encode_REGISTER_SUPER( uint8_t * base,
|
||||
size_t * idx,
|
||||
const n2n_common_t * common,
|
||||
const n2n_common_t * common,
|
||||
const n2n_REGISTER_SUPER_t * reg )
|
||||
{
|
||||
int retval=0;
|
||||
|
@ -320,9 +320,9 @@ int decode_REGISTER_SUPER( n2n_REGISTER_SUPER_t * reg,
|
|||
return retval;
|
||||
}
|
||||
|
||||
int encode_REGISTER_ACK( uint8_t * base,
|
||||
int encode_REGISTER_ACK( uint8_t * base,
|
||||
size_t * idx,
|
||||
const n2n_common_t * common,
|
||||
const n2n_common_t * common,
|
||||
const n2n_REGISTER_ACK_t * reg )
|
||||
{
|
||||
int retval=0;
|
||||
|
@ -413,8 +413,8 @@ int decode_REGISTER_SUPER_ACK( n2n_REGISTER_SUPER_ACK_t * reg,
|
|||
return retval;
|
||||
}
|
||||
|
||||
int fill_sockaddr( struct sockaddr * addr,
|
||||
size_t addrlen,
|
||||
int fill_sockaddr( struct sockaddr * addr,
|
||||
size_t addrlen,
|
||||
const n2n_sock_t * sock )
|
||||
{
|
||||
int retval=-1;
|
||||
|
@ -435,9 +435,9 @@ int fill_sockaddr( struct sockaddr * addr,
|
|||
}
|
||||
|
||||
|
||||
int encode_PACKET( uint8_t * base,
|
||||
int encode_PACKET( uint8_t * base,
|
||||
size_t * idx,
|
||||
const n2n_common_t * common,
|
||||
const n2n_common_t * common,
|
||||
const n2n_PACKET_t * pkt )
|
||||
{
|
||||
int retval=0;
|
||||
|
@ -475,3 +475,58 @@ 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 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…
Reference in New Issue
Block a user