mirror of
https://github.com/ntop/n2n.git
synced 2024-09-19 16:41:11 +02:00
more sockaddr generalization (#1028)
This commit is contained in:
parent
439dfc6886
commit
95cfbca5a9
|
@ -751,7 +751,11 @@ typedef struct sn_stats {
|
||||||
typedef struct node_supernode_association {
|
typedef struct node_supernode_association {
|
||||||
|
|
||||||
n2n_mac_t mac; /* mac address of an edge */
|
n2n_mac_t mac; /* mac address of an edge */
|
||||||
const struct sockaddr_in sock; /* network order socket of that edge's supernode */
|
socklen_t sock_len; /* amount of actually used space (of the following) */
|
||||||
|
union {
|
||||||
|
struct sockaddr sock; /* network order socket of that edge's supernode */
|
||||||
|
struct sockaddr_storage sas; /* the actual memory for it, sockaddr can be too small */
|
||||||
|
};
|
||||||
time_t last_seen; /* time mark to keep track of purging requirements */
|
time_t last_seen; /* time mark to keep track of purging requirements */
|
||||||
|
|
||||||
UT_hash_handle hh; /* makes this structure hashable */
|
UT_hash_handle hh; /* makes this structure hashable */
|
||||||
|
@ -796,9 +800,12 @@ struct sn_community_regular_expression {
|
||||||
|
|
||||||
|
|
||||||
typedef struct n2n_tcp_connection {
|
typedef struct n2n_tcp_connection {
|
||||||
int socket_fd; /* file descriptor for tcp socket */
|
int socket_fd; /* file descriptor for tcp socket */
|
||||||
struct sockaddr sock; /* network order socket */
|
socklen_t sock_len; /* amount of actually used space (of the following) */
|
||||||
|
union {
|
||||||
|
struct sockaddr sock; /* network order socket */
|
||||||
|
struct sockaddr_storage sas; /* memory for it, can be longer than sockaddr */
|
||||||
|
};
|
||||||
uint16_t expected; /* number of bytes expected to be read */
|
uint16_t expected; /* number of bytes expected to be read */
|
||||||
uint16_t position; /* current position in the buffer */
|
uint16_t position; /* current position in the buffer */
|
||||||
uint8_t buffer[N2N_PKT_BUF_SIZE + sizeof(uint16_t)]; /* buffer for data collected from tcp socket incl. prepended length */
|
uint8_t buffer[N2N_PKT_BUF_SIZE + sizeof(uint16_t)]; /* buffer for data collected from tcp socket incl. prepended length */
|
||||||
|
|
|
@ -417,7 +417,6 @@ void readFromMgmtSocket (n2n_edge_t *eee) {
|
||||||
ssize_t recvlen;
|
ssize_t recvlen;
|
||||||
/* ssize_t sendlen; */
|
/* ssize_t sendlen; */
|
||||||
mgmt_req_t req;
|
mgmt_req_t req;
|
||||||
socklen_t i;
|
|
||||||
size_t msg_len;
|
size_t msg_len;
|
||||||
time_t now;
|
time_t now;
|
||||||
struct peer_info *peer, *tmpPeer;
|
struct peer_info *peer, *tmpPeer;
|
||||||
|
@ -438,11 +437,11 @@ void readFromMgmtSocket (n2n_edge_t *eee) {
|
||||||
req.mgmt_sock = eee->udp_mgmt_sock;
|
req.mgmt_sock = eee->udp_mgmt_sock;
|
||||||
req.keep_running = eee->keep_running;
|
req.keep_running = eee->keep_running;
|
||||||
req.mgmt_password_hash = eee->conf.mgmt_password_hash;
|
req.mgmt_password_hash = eee->conf.mgmt_password_hash;
|
||||||
|
req.sock_len = sizeof(req.sas);
|
||||||
|
|
||||||
now = time(NULL);
|
now = time(NULL);
|
||||||
i = sizeof(req.sender_sock);
|
|
||||||
recvlen = recvfrom(eee->udp_mgmt_sock, udp_buf, N2N_PKT_BUF_SIZE, 0 /*flags*/,
|
recvlen = recvfrom(eee->udp_mgmt_sock, udp_buf, N2N_PKT_BUF_SIZE, 0 /*flags*/,
|
||||||
(struct sockaddr *) &req.sender_sock, (socklen_t *) &i);
|
&req.sender_sock, &req.sock_len);
|
||||||
|
|
||||||
if(recvlen < 0) {
|
if(recvlen < 0) {
|
||||||
traceEvent(TRACE_WARNING, "mgmt recvfrom failed: %d - %s", errno, strerror(errno));
|
traceEvent(TRACE_WARNING, "mgmt recvfrom failed: %d - %s", errno, strerror(errno));
|
||||||
|
@ -546,7 +545,7 @@ void readFromMgmtSocket (n2n_edge_t *eee) {
|
||||||
(peer->last_seen) ? time_buf : "");
|
(peer->last_seen) ? time_buf : "");
|
||||||
|
|
||||||
sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0,
|
sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0,
|
||||||
(struct sockaddr *) &req.sender_sock, sizeof(struct sockaddr_in));
|
&req.sender_sock, req.sock_len);
|
||||||
msg_len = 0;
|
msg_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,7 +569,7 @@ void readFromMgmtSocket (n2n_edge_t *eee) {
|
||||||
(peer->last_seen) ? time_buf : "");
|
(peer->last_seen) ? time_buf : "");
|
||||||
|
|
||||||
sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0,
|
sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0,
|
||||||
(struct sockaddr *) &req.sender_sock, sizeof(struct sockaddr_in));
|
&req.sender_sock, req.sock_len);
|
||||||
msg_len = 0;
|
msg_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -596,7 +595,7 @@ void readFromMgmtSocket (n2n_edge_t *eee) {
|
||||||
(peer->uptime) ? uptime_buf : "");
|
(peer->uptime) ? uptime_buf : "");
|
||||||
|
|
||||||
sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0,
|
sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0,
|
||||||
(struct sockaddr *) &req.sender_sock, sizeof(struct sockaddr_in));
|
&req.sender_sock, req.sock_len);
|
||||||
msg_len = 0;
|
msg_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -643,5 +642,5 @@ void readFromMgmtSocket (n2n_edge_t *eee) {
|
||||||
"\nType \"help\" to see more commands.\n\n");
|
"\nType \"help\" to see more commands.\n\n");
|
||||||
|
|
||||||
sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0,
|
sendto(eee->udp_mgmt_sock, udp_buf, msg_len, 0,
|
||||||
(struct sockaddr *) &req.sender_sock, sizeof(struct sockaddr_in));
|
&req.sender_sock, req.sock_len);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ int getTraceLevel ();
|
||||||
ssize_t send_reply (mgmt_req_t *req, strbuf_t *buf, size_t msg_len) {
|
ssize_t send_reply (mgmt_req_t *req, strbuf_t *buf, size_t msg_len) {
|
||||||
// TODO: better error handling (counters?)
|
// TODO: better error handling (counters?)
|
||||||
return sendto(req->mgmt_sock, buf->str, msg_len, 0,
|
return sendto(req->mgmt_sock, buf->str, msg_len, 0,
|
||||||
(struct sockaddr *) &req->sender_sock, sizeof(struct sockaddr_in));
|
&req->sender_sock, req->sock_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t gen_json_1str (strbuf_t *buf, char *tag, char *_type, char *key, char *val) {
|
size_t gen_json_1str (strbuf_t *buf, char *tag, char *_type, char *key, char *val) {
|
||||||
|
|
|
@ -39,7 +39,11 @@ typedef struct mgmt_req {
|
||||||
char *argv0;
|
char *argv0;
|
||||||
char *argv;
|
char *argv;
|
||||||
char tag[10];
|
char tag[10];
|
||||||
struct sockaddr_in sender_sock;
|
socklen_t sock_len;
|
||||||
|
union {
|
||||||
|
struct sockaddr sender_sock;
|
||||||
|
struct sockaddr_storage sas; // memory for the socket, actual socket can be longer than sockaddr
|
||||||
|
};
|
||||||
} mgmt_req_t;
|
} mgmt_req_t;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -255,12 +255,12 @@ static void handleMgmtJson (mgmt_req_t *req, char *udp_buf, const int recvlen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static int sendto_mgmt (n2n_sn_t *sss,
|
static int sendto_mgmt (n2n_sn_t *sss,
|
||||||
const struct sockaddr_in *sender_sock,
|
const struct sockaddr *sender_sock, socklen_t sock_size,
|
||||||
const uint8_t *mgmt_buf,
|
const uint8_t *mgmt_buf,
|
||||||
size_t mgmt_size) {
|
size_t mgmt_size) {
|
||||||
|
|
||||||
ssize_t r = sendto(sss->mgmt_sock, (void *)mgmt_buf, mgmt_size, 0 /*flags*/,
|
ssize_t r = sendto(sss->mgmt_sock, (void *)mgmt_buf, mgmt_size, 0 /*flags*/,
|
||||||
(struct sockaddr *)sender_sock, sizeof (struct sockaddr_in));
|
sender_sock, sock_size);
|
||||||
|
|
||||||
if(r <= 0) {
|
if(r <= 0) {
|
||||||
++(sss->stats.errors);
|
++(sss->stats.errors);
|
||||||
|
@ -272,7 +272,7 @@ static int sendto_mgmt (n2n_sn_t *sss,
|
||||||
}
|
}
|
||||||
|
|
||||||
int process_mgmt (n2n_sn_t *sss,
|
int process_mgmt (n2n_sn_t *sss,
|
||||||
const struct sockaddr_in *sender_sock,
|
const struct sockaddr *sender_sock, socklen_t sock_size,
|
||||||
char *mgmt_buf,
|
char *mgmt_buf,
|
||||||
size_t mgmt_size,
|
size_t mgmt_size,
|
||||||
time_t now) {
|
time_t now) {
|
||||||
|
@ -297,7 +297,8 @@ int process_mgmt (n2n_sn_t *sss,
|
||||||
req.mgmt_sock = sss->mgmt_sock;
|
req.mgmt_sock = sss->mgmt_sock;
|
||||||
req.keep_running = sss->keep_running;
|
req.keep_running = sss->keep_running;
|
||||||
req.mgmt_password_hash = sss->mgmt_password_hash;
|
req.mgmt_password_hash = sss->mgmt_password_hash;
|
||||||
memcpy(&req.sender_sock, sender_sock, sizeof(req.sender_sock));
|
memcpy(&req.sender_sock, sender_sock, sock_size);
|
||||||
|
req.sock_len = sock_size;
|
||||||
|
|
||||||
/* avoid parsing any uninitialized junk from the stack */
|
/* avoid parsing any uninitialized junk from the stack */
|
||||||
mgmt_buf[mgmt_size] = 0;
|
mgmt_buf[mgmt_size] = 0;
|
||||||
|
@ -309,7 +310,7 @@ int process_mgmt (n2n_sn_t *sss,
|
||||||
"\thelp | This help message\n"
|
"\thelp | This help message\n"
|
||||||
"\treload_communities | Reloads communities and user's public keys\n"
|
"\treload_communities | Reloads communities and user's public keys\n"
|
||||||
"\t<enter> | Display status and statistics\n");
|
"\t<enter> | Display status and statistics\n");
|
||||||
sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize);
|
sendto_mgmt(sss, sender_sock, sock_size, (const uint8_t *) resbuf, ressize);
|
||||||
return 0; /* no status output afterwards */
|
return 0; /* no status output afterwards */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,7 +318,7 @@ int process_mgmt (n2n_sn_t *sss,
|
||||||
if(!sss->community_file) {
|
if(!sss->community_file) {
|
||||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
||||||
"No community file provided (-c command line option)\n");
|
"No community file provided (-c command line option)\n");
|
||||||
sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize);
|
sendto_mgmt(sss, sender_sock, sock_size, (const uint8_t *) resbuf, ressize);
|
||||||
return 0; /* no status output afterwards */
|
return 0; /* no status output afterwards */
|
||||||
}
|
}
|
||||||
traceEvent(TRACE_NORMAL, "'reload_communities' command");
|
traceEvent(TRACE_NORMAL, "'reload_communities' command");
|
||||||
|
@ -325,12 +326,12 @@ int process_mgmt (n2n_sn_t *sss,
|
||||||
if(load_allowed_sn_community(sss)) {
|
if(load_allowed_sn_community(sss)) {
|
||||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
||||||
"Error while re-loading community file (not found or no valid content)\n");
|
"Error while re-loading community file (not found or no valid content)\n");
|
||||||
sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize);
|
sendto_mgmt(sss, sender_sock, sock_size, (const uint8_t *) resbuf, ressize);
|
||||||
return 0; /* no status output afterwards */
|
return 0; /* no status output afterwards */
|
||||||
}
|
}
|
||||||
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
ressize += snprintf(resbuf + ressize, N2N_SN_PKTBUF_SIZE - ressize,
|
||||||
"OK.\n");
|
"OK.\n");
|
||||||
sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize);
|
sendto_mgmt(sss, sender_sock, sock_size, (const uint8_t *) resbuf, ressize);
|
||||||
return 0; /* no status output afterwards */
|
return 0; /* no status output afterwards */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,7 +358,7 @@ int process_mgmt (n2n_sn_t *sss,
|
||||||
"%s '%s'\n",
|
"%s '%s'\n",
|
||||||
(community->is_federation) ? "FEDERATION" : ((community->purgeable == UNPURGEABLE) ? "FIXED NAME COMMUNITY" : "COMMUNITY"),
|
(community->is_federation) ? "FEDERATION" : ((community->purgeable == UNPURGEABLE) ? "FIXED NAME COMMUNITY" : "COMMUNITY"),
|
||||||
(community->is_federation) ? "-/-" : community->community);
|
(community->is_federation) ? "-/-" : community->community);
|
||||||
sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize);
|
sendto_mgmt(sss, sender_sock, sock_size, (const uint8_t *) resbuf, ressize);
|
||||||
ressize = 0;
|
ressize = 0;
|
||||||
|
|
||||||
num = 0;
|
num = 0;
|
||||||
|
@ -373,7 +374,7 @@ int process_mgmt (n2n_sn_t *sss,
|
||||||
peer->dev_desc,
|
peer->dev_desc,
|
||||||
(peer->last_seen) ? time_buf : "");
|
(peer->last_seen) ? time_buf : "");
|
||||||
|
|
||||||
sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize);
|
sendto_mgmt(sss, sender_sock, sock_size, (const uint8_t *) resbuf, ressize);
|
||||||
ressize = 0;
|
ressize = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -418,7 +419,7 @@ int process_mgmt (n2n_sn_t *sss,
|
||||||
"last reg %lu sec ago\n\n",
|
"last reg %lu sec ago\n\n",
|
||||||
(long unsigned int) (now - sss->stats.last_reg_super));
|
(long unsigned int) (now - sss->stats.last_reg_super));
|
||||||
|
|
||||||
sendto_mgmt(sss, sender_sock, (const uint8_t *) resbuf, ressize);
|
sendto_mgmt(sss, sender_sock, sock_size, (const uint8_t *) resbuf, ressize);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
127
src/sn_utils.c
127
src/sn_utils.c
|
@ -57,13 +57,13 @@ static int sort_communities (n2n_sn_t *sss,
|
||||||
time_t now);
|
time_t now);
|
||||||
|
|
||||||
int process_mgmt (n2n_sn_t *sss,
|
int process_mgmt (n2n_sn_t *sss,
|
||||||
const struct sockaddr_in *sender_sock,
|
const struct sockaddr *sender_sock, socklen_t sock_size,
|
||||||
char *mgmt_buf,
|
char *mgmt_buf,
|
||||||
size_t mgmt_size,
|
size_t mgmt_size,
|
||||||
time_t now);
|
time_t now);
|
||||||
|
|
||||||
static int process_udp (n2n_sn_t *sss,
|
static int process_udp (n2n_sn_t *sss,
|
||||||
const struct sockaddr_in *sender_sock,
|
const struct sockaddr *sender_sock, socklen_t sock_size,
|
||||||
const SOCKET socket_fd,
|
const SOCKET socket_fd,
|
||||||
uint8_t *udp_buf,
|
uint8_t *udp_buf,
|
||||||
size_t udp_size,
|
size_t udp_size,
|
||||||
|
@ -700,7 +700,7 @@ static int try_forward (n2n_sn_t * sss,
|
||||||
if(assoc) {
|
if(assoc) {
|
||||||
traceEvent(TRACE_DEBUG, "found mac address associated with a known supernode, forwarding packet to that supernode");
|
traceEvent(TRACE_DEBUG, "found mac address associated with a known supernode, forwarding packet to that supernode");
|
||||||
sendto_sock(sss, sss->sock,
|
sendto_sock(sss, sss->sock,
|
||||||
(const struct sockaddr*)&(assoc->sock),
|
&(assoc->sock),
|
||||||
pktbuf, pktsize);
|
pktbuf, pktsize);
|
||||||
} else {
|
} else {
|
||||||
// forwarding packet to all federated supernodes
|
// forwarding packet to all federated supernodes
|
||||||
|
@ -876,7 +876,7 @@ void sn_term (n2n_sn_t *sss) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_node_supernode_association (struct sn_community *comm,
|
void update_node_supernode_association (struct sn_community *comm,
|
||||||
n2n_mac_t *edgeMac, const struct sockaddr_in *sender_sock,
|
n2n_mac_t *edgeMac, const struct sockaddr *sender_sock, socklen_t sock_size,
|
||||||
time_t now) {
|
time_t now) {
|
||||||
|
|
||||||
node_supernode_association_t *assoc;
|
node_supernode_association_t *assoc;
|
||||||
|
@ -884,15 +884,17 @@ void update_node_supernode_association (struct sn_community *comm,
|
||||||
HASH_FIND(hh, comm->assoc, edgeMac, sizeof(n2n_mac_t), assoc);
|
HASH_FIND(hh, comm->assoc, edgeMac, sizeof(n2n_mac_t), assoc);
|
||||||
if(!assoc) {
|
if(!assoc) {
|
||||||
// create a new association
|
// create a new association
|
||||||
assoc = (node_supernode_association_t*)malloc(sizeof(node_supernode_association_t));
|
assoc = (node_supernode_association_t*)calloc(1, sizeof(node_supernode_association_t));
|
||||||
if(assoc) {
|
if(assoc) {
|
||||||
memcpy(&(assoc->mac), edgeMac, sizeof(n2n_mac_t));
|
memcpy(&(assoc->mac), edgeMac, sizeof(n2n_mac_t));
|
||||||
memcpy((struct sockaddr_in*)&(assoc->sock), sender_sock, sizeof(struct sockaddr_in));
|
memcpy(&(assoc->sock), sender_sock, sock_size);
|
||||||
|
assoc->sock_len = sock_size;
|
||||||
assoc->last_seen = now;
|
assoc->last_seen = now;
|
||||||
HASH_ADD(hh, comm->assoc, mac, sizeof(n2n_mac_t), assoc);
|
HASH_ADD(hh, comm->assoc, mac, sizeof(n2n_mac_t), assoc);
|
||||||
} else {
|
} else {
|
||||||
// already there, update socket and time only
|
// already there, update socket and time only
|
||||||
memcpy((struct sockaddr_in*)&(assoc->sock), sender_sock, sizeof(struct sockaddr_in));
|
memcpy(&(assoc->sock), sender_sock, sock_size);
|
||||||
|
assoc->sock_len = sock_size;
|
||||||
assoc->last_seen = now;
|
assoc->last_seen = now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1509,7 +1511,7 @@ static int sort_communities (n2n_sn_t *sss,
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
static int process_udp (n2n_sn_t * sss,
|
static int process_udp (n2n_sn_t * sss,
|
||||||
const struct sockaddr_in *sender_sock,
|
const struct sockaddr *sender_sock, socklen_t sock_size,
|
||||||
const SOCKET socket_fd,
|
const SOCKET socket_fd,
|
||||||
uint8_t * udp_buf,
|
uint8_t * udp_buf,
|
||||||
size_t udp_size,
|
size_t udp_size,
|
||||||
|
@ -1522,10 +1524,10 @@ static int process_udp (n2n_sn_t * sss,
|
||||||
uint8_t from_supernode;
|
uint8_t from_supernode;
|
||||||
peer_info_t *sn = NULL;
|
peer_info_t *sn = NULL;
|
||||||
n2n_sock_t sender;
|
n2n_sock_t sender;
|
||||||
|
n2n_sock_t *orig_sender;
|
||||||
macstr_t mac_buf;
|
macstr_t mac_buf;
|
||||||
macstr_t mac_buf2;
|
macstr_t mac_buf2;
|
||||||
n2n_sock_str_t sockbuf;
|
n2n_sock_str_t sockbuf;
|
||||||
char buf[32];
|
|
||||||
uint8_t hash_buf[16] = {0}; /* always size of 16 (max) despite the actual value of N2N_REG_SUP_HASH_CHECK_LEN (<= 16) */
|
uint8_t hash_buf[16] = {0}; /* always size of 16 (max) despite the actual value of N2N_REG_SUP_HASH_CHECK_LEN (<= 16) */
|
||||||
|
|
||||||
struct sn_community *comm, *tmp;
|
struct sn_community *comm, *tmp;
|
||||||
|
@ -1534,9 +1536,12 @@ static int process_udp (n2n_sn_t * sss,
|
||||||
int skip_add;
|
int skip_add;
|
||||||
time_t any_time = 0;
|
time_t any_time = 0;
|
||||||
|
|
||||||
traceEvent(TRACE_DEBUG, "processing incoming UDP packet [len: %lu][sender: %s:%u]",
|
memset(&sender, 0, sizeof(n2n_sock_t));
|
||||||
udp_size, intoa(ntohl(sender_sock->sin_addr.s_addr), buf, sizeof(buf)),
|
fill_n2nsock(&sender, sender_sock);
|
||||||
ntohs(sender_sock->sin_port));
|
orig_sender = &sender;
|
||||||
|
|
||||||
|
traceEvent(TRACE_DEBUG, "processing incoming UDP packet [len: %lu][sender: %s]",
|
||||||
|
udp_size, sock_to_cstr(sockbuf, &sender));
|
||||||
|
|
||||||
/* check if header is unencrypted. the following check is around 99.99962 percent reliable.
|
/* check if header is unencrypted. the following check is around 99.99962 percent reliable.
|
||||||
* it heavily relies on the structure of packet's common part
|
* it heavily relies on the structure of packet's common part
|
||||||
|
@ -1652,11 +1657,6 @@ static int process_udp (n2n_sn_t * sss,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* REVISIT: when UDP/IPv6 is supported we will need a flag to indicate which
|
|
||||||
* IP transport version the packet arrived on. May need to UDP sockets. */
|
|
||||||
memset(&sender, 0, sizeof(n2n_sock_t));
|
|
||||||
fill_n2nsock(&sender, (struct sockaddr*)sender_sock);
|
|
||||||
|
|
||||||
from_supernode = cmn.flags & N2N_FLAGS_FROM_SUPERNODE;
|
from_supernode = cmn.flags & N2N_FLAGS_FROM_SUPERNODE;
|
||||||
if(from_supernode) {
|
if(from_supernode) {
|
||||||
skip_add = SN_ADD_SKIP;
|
skip_add = SN_ADD_SKIP;
|
||||||
|
@ -1718,7 +1718,7 @@ static int process_udp (n2n_sn_t * sss,
|
||||||
/* We are going to add socket even if it was not there before */
|
/* We are going to add socket even if it was not there before */
|
||||||
cmn2.flags |= N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE;
|
cmn2.flags |= N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE;
|
||||||
|
|
||||||
fill_n2nsock(&pkt.sock, (struct sockaddr*)sender_sock);
|
memcpy(&pkt.sock, &sender, sizeof(sender));
|
||||||
|
|
||||||
rec_buf = encbuf;
|
rec_buf = encbuf;
|
||||||
/* Re-encode the header. */
|
/* Re-encode the header. */
|
||||||
|
@ -1801,7 +1801,7 @@ static int process_udp (n2n_sn_t * sss,
|
||||||
/* We are going to add socket even if it was not there before */
|
/* We are going to add socket even if it was not there before */
|
||||||
cmn2.flags |= N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE;
|
cmn2.flags |= N2N_FLAGS_SOCKET | N2N_FLAGS_FROM_SUPERNODE;
|
||||||
|
|
||||||
fill_n2nsock(®.sock, (struct sockaddr*)sender_sock);
|
memcpy(®.sock, &sender, sizeof(sender));
|
||||||
|
|
||||||
/* Re-encode the header. */
|
/* Re-encode the header. */
|
||||||
encode_REGISTER(encbuf, &encx, &cmn2, ®);
|
encode_REGISTER(encbuf, &encx, &cmn2, ®);
|
||||||
|
@ -1960,7 +1960,7 @@ static int process_udp (n2n_sn_t * sss,
|
||||||
|
|
||||||
ack.lifetime = reg_lifetime(sss);
|
ack.lifetime = reg_lifetime(sss);
|
||||||
|
|
||||||
fill_n2nsock(&ack.sock, (struct sockaddr*)sender_sock);
|
memcpy(&ack.sock, &sender, sizeof(sender));
|
||||||
|
|
||||||
/* Add sender's data to federation (or update it) */
|
/* Add sender's data to federation (or update it) */
|
||||||
if(comm->is_federation == IS_FEDERATION) {
|
if(comm->is_federation == IS_FEDERATION) {
|
||||||
|
@ -2029,7 +2029,7 @@ static int process_udp (n2n_sn_t * sss,
|
||||||
encode_buf(ackbuf, &encx, hash_buf /* no matter what content */, N2N_REG_SUP_HASH_CHECK_LEN);
|
encode_buf(ackbuf, &encx, hash_buf /* no matter what content */, N2N_REG_SUP_HASH_CHECK_LEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sendto_sock(sss, socket_fd, (struct sockaddr *)sender_sock, ackbuf, encx);
|
sendto_sock(sss, socket_fd, sender_sock, ackbuf, encx);
|
||||||
|
|
||||||
traceEvent(TRACE_DEBUG, "Tx REGISTER_SUPER_NAK for %s",
|
traceEvent(TRACE_DEBUG, "Tx REGISTER_SUPER_NAK for %s",
|
||||||
macaddr_str(mac_buf, reg.edgeMac));
|
macaddr_str(mac_buf, reg.edgeMac));
|
||||||
|
@ -2041,7 +2041,7 @@ static int process_udp (n2n_sn_t * sss,
|
||||||
// NULL comm and from_supernode parameter)
|
// NULL comm and from_supernode parameter)
|
||||||
// exception: do not forward auto ip draw
|
// exception: do not forward auto ip draw
|
||||||
if(!is_null_mac(reg.edgeMac)) {
|
if(!is_null_mac(reg.edgeMac)) {
|
||||||
fill_n2nsock(®.sock, (struct sockaddr*)sender_sock);
|
memcpy(®.sock, &sender, sizeof(sender));
|
||||||
|
|
||||||
cmn2.pc = n2n_register_super;
|
cmn2.pc = n2n_register_super;
|
||||||
encode_REGISTER_SUPER(ackbuf, &encx, &cmn2, ®);
|
encode_REGISTER_SUPER(ackbuf, &encx, &cmn2, ®);
|
||||||
|
@ -2100,7 +2100,7 @@ static int process_udp (n2n_sn_t * sss,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sendto_sock(sss, socket_fd, (struct sockaddr *)sender_sock, ackbuf, encx);
|
sendto_sock(sss, socket_fd, sender_sock, ackbuf, encx);
|
||||||
|
|
||||||
traceEvent(TRACE_DEBUG, "Tx REGISTER_SUPER_ACK for %s [%s]",
|
traceEvent(TRACE_DEBUG, "Tx REGISTER_SUPER_ACK for %s [%s]",
|
||||||
macaddr_str(mac_buf, reg.edgeMac),
|
macaddr_str(mac_buf, reg.edgeMac),
|
||||||
|
@ -2108,7 +2108,7 @@ static int process_udp (n2n_sn_t * sss,
|
||||||
} else {
|
} else {
|
||||||
// this is an edge with valid authentication registering with another supernode, so ...
|
// this is an edge with valid authentication registering with another supernode, so ...
|
||||||
// 1- ... associate it with that other supernode
|
// 1- ... associate it with that other supernode
|
||||||
update_node_supernode_association(comm, &(reg.edgeMac), sender_sock, now);
|
update_node_supernode_association(comm, &(reg.edgeMac), sender_sock, sock_size, now);
|
||||||
// 2- ... we can delete it from regular list if present (can happen)
|
// 2- ... we can delete it from regular list if present (can happen)
|
||||||
HASH_FIND_PEER(comm->edges, reg.edgeMac, peer);
|
HASH_FIND_PEER(comm->edges, reg.edgeMac, peer);
|
||||||
if(peer != NULL) {
|
if(peer != NULL) {
|
||||||
|
@ -2179,17 +2179,10 @@ static int process_udp (n2n_sn_t * sss,
|
||||||
n2n_sock_str_t sockbuf1;
|
n2n_sock_str_t sockbuf1;
|
||||||
n2n_sock_str_t sockbuf2;
|
n2n_sock_str_t sockbuf2;
|
||||||
macstr_t mac_buf1;
|
macstr_t mac_buf1;
|
||||||
n2n_sock_t sender;
|
|
||||||
n2n_sock_t *orig_sender;
|
|
||||||
int i;
|
int i;
|
||||||
uint8_t dec_tmpbuf[REG_SUPER_ACK_PAYLOAD_SPACE];
|
uint8_t dec_tmpbuf[REG_SUPER_ACK_PAYLOAD_SPACE];
|
||||||
n2n_REGISTER_SUPER_ACK_payload_t *payload;
|
n2n_REGISTER_SUPER_ACK_payload_t *payload;
|
||||||
|
|
||||||
memset(&sender, 0, sizeof(n2n_sock_t));
|
|
||||||
fill_n2nsock(&sender, (struct sockaddr*)sender_sock);
|
|
||||||
|
|
||||||
orig_sender = &sender;
|
|
||||||
|
|
||||||
memset(&ack, 0, sizeof(n2n_REGISTER_SUPER_ACK_t));
|
memset(&ack, 0, sizeof(n2n_REGISTER_SUPER_ACK_t));
|
||||||
|
|
||||||
if(!comm) {
|
if(!comm) {
|
||||||
|
@ -2268,10 +2261,6 @@ static int process_udp (n2n_sn_t * sss,
|
||||||
struct peer_info *peer;
|
struct peer_info *peer;
|
||||||
n2n_sock_str_t sockbuf;
|
n2n_sock_str_t sockbuf;
|
||||||
macstr_t mac_buf;
|
macstr_t mac_buf;
|
||||||
n2n_sock_t sender;
|
|
||||||
|
|
||||||
memset(&sender, 0, sizeof(n2n_sock_t));
|
|
||||||
fill_n2nsock(&sender, (struct sockaddr*)sender_sock);
|
|
||||||
|
|
||||||
memset(&nak, 0, sizeof(n2n_REGISTER_SUPER_NAK_t));
|
memset(&nak, 0, sizeof(n2n_REGISTER_SUPER_NAK_t));
|
||||||
|
|
||||||
|
@ -2389,7 +2378,7 @@ static int process_udp (n2n_sn_t * sss,
|
||||||
memcpy(pi.mac, query.targetMac, sizeof(n2n_mac_t));
|
memcpy(pi.mac, query.targetMac, sizeof(n2n_mac_t));
|
||||||
memcpy(pi.srcMac, sss->mac_addr, sizeof(n2n_mac_t));
|
memcpy(pi.srcMac, sss->mac_addr, sizeof(n2n_mac_t));
|
||||||
|
|
||||||
fill_n2nsock(&pi.sock, (struct sockaddr*)sender_sock);
|
memcpy(&pi.sock, &sender, sizeof(sender));
|
||||||
|
|
||||||
pi.load = sn_selection_criterion_gather_data(sss);
|
pi.load = sn_selection_criterion_gather_data(sss);
|
||||||
|
|
||||||
|
@ -2406,7 +2395,7 @@ static int process_udp (n2n_sn_t * sss,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sendto_sock(sss, socket_fd, (struct sockaddr *)sender_sock, encbuf, encx);
|
sendto_sock(sss, socket_fd, sender_sock, encbuf, encx);
|
||||||
|
|
||||||
traceEvent(TRACE_DEBUG, "Tx PONG to %s",
|
traceEvent(TRACE_DEBUG, "Tx PONG to %s",
|
||||||
macaddr_str(mac_buf, query.srcMac));
|
macaddr_str(mac_buf, query.srcMac));
|
||||||
|
@ -2448,7 +2437,7 @@ static int process_udp (n2n_sn_t * sss,
|
||||||
time_stamp());
|
time_stamp());
|
||||||
}
|
}
|
||||||
// back to sender, be it edge or supernode (which will forward to edge)
|
// back to sender, be it edge or supernode (which will forward to edge)
|
||||||
sendto_sock(sss, socket_fd, (struct sockaddr *)sender_sock, encbuf, encx);
|
sendto_sock(sss, socket_fd, sender_sock, encbuf, encx);
|
||||||
|
|
||||||
traceEvent(TRACE_DEBUG, "Tx PEER_INFO to %s",
|
traceEvent(TRACE_DEBUG, "Tx PEER_INFO to %s",
|
||||||
macaddr_str(mac_buf, query.srcMac));
|
macaddr_str(mac_buf, query.srcMac));
|
||||||
|
@ -2508,7 +2497,7 @@ static int process_udp (n2n_sn_t * sss,
|
||||||
if(peer != NULL) {
|
if(peer != NULL) {
|
||||||
if((comm->is_federation == IS_NO_FEDERATION) && (!is_null_mac(pi.srcMac))) {
|
if((comm->is_federation == IS_NO_FEDERATION) && (!is_null_mac(pi.srcMac))) {
|
||||||
// snoop on the information to use for supernode forwarding (do not wait until first remote REGISTER_SUPER)
|
// snoop on the information to use for supernode forwarding (do not wait until first remote REGISTER_SUPER)
|
||||||
update_node_supernode_association(comm, &(pi.mac), sender_sock, now);
|
update_node_supernode_association(comm, &(pi.mac), sender_sock, sock_size, now);
|
||||||
|
|
||||||
// this is a PEER_INFO for one of the edges conencted to this supernode, forward,
|
// this is a PEER_INFO for one of the edges conencted to this supernode, forward,
|
||||||
// i.e. re-assemble (memcpy of udpbuf to encbuf could be sufficient as well)
|
// i.e. re-assemble (memcpy of udpbuf to encbuf could be sufficient as well)
|
||||||
|
@ -2597,12 +2586,12 @@ int run_sn_loop (n2n_sn_t *sss) {
|
||||||
|
|
||||||
// external udp
|
// external udp
|
||||||
if(FD_ISSET(sss->sock, &socket_mask)) {
|
if(FD_ISSET(sss->sock, &socket_mask)) {
|
||||||
struct sockaddr_in sender_sock;
|
struct sockaddr_storage sas;
|
||||||
socklen_t i;
|
struct sockaddr *sender_sock = (struct sockaddr*)&sas;
|
||||||
|
socklen_t ss_size = sizeof(sas);
|
||||||
|
|
||||||
i = sizeof(sender_sock);
|
|
||||||
bread = recvfrom(sss->sock, (void *)pktbuf, N2N_SN_PKTBUF_SIZE, 0 /*flags*/,
|
bread = recvfrom(sss->sock, (void *)pktbuf, N2N_SN_PKTBUF_SIZE, 0 /*flags*/,
|
||||||
(struct sockaddr *)&sender_sock, (socklen_t *)&i);
|
sender_sock, &ss_size);
|
||||||
|
|
||||||
if((bread < 0)
|
if((bread < 0)
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
@ -2622,7 +2611,7 @@ int run_sn_loop (n2n_sn_t *sss) {
|
||||||
// we have a datagram to process...
|
// we have a datagram to process...
|
||||||
if(bread > 0) {
|
if(bread > 0) {
|
||||||
// ...and the datagram has data (not just a header)
|
// ...and the datagram has data (not just a header)
|
||||||
process_udp(sss, &sender_sock, sss->sock, pktbuf, bread, now);
|
process_udp(sss, sender_sock, ss_size, sss->sock, pktbuf, bread, now);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2640,17 +2629,16 @@ int run_sn_loop (n2n_sn_t *sss) {
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(FD_ISSET(conn->socket_fd, &socket_mask)) {
|
if(FD_ISSET(conn->socket_fd, &socket_mask)) {
|
||||||
|
struct sockaddr_storage sas;
|
||||||
|
struct sockaddr *sender_sock = (struct sockaddr*)&sas;
|
||||||
|
socklen_t ss_size = sizeof(sas);
|
||||||
|
|
||||||
struct sockaddr_in sender_sock;
|
|
||||||
socklen_t i;
|
|
||||||
|
|
||||||
i = sizeof(sender_sock);
|
|
||||||
bread = recvfrom(conn->socket_fd,
|
bread = recvfrom(conn->socket_fd,
|
||||||
conn->buffer + conn->position, conn->expected - conn->position, 0 /*flags*/,
|
conn->buffer + conn->position, conn->expected - conn->position, 0 /*flags*/,
|
||||||
(struct sockaddr *)&sender_sock, (socklen_t *)&i);
|
sender_sock, &ss_size);
|
||||||
|
|
||||||
if(bread <= 0) {
|
if(bread <= 0) {
|
||||||
traceEvent(TRACE_INFO, "closing tcp connection to [%s]", sock_to_cstr(sockbuf, (n2n_sock_t*)&sender_sock));
|
traceEvent(TRACE_INFO, "closing tcp connection to [%s]", sock_to_cstr(sockbuf, (n2n_sock_t*)sender_sock));
|
||||||
traceEvent(TRACE_DEBUG, "recvfrom() returns %d and sees errno %d (%s)", bread, errno, strerror(errno));
|
traceEvent(TRACE_DEBUG, "recvfrom() returns %d and sees errno %d (%s)", bread, errno, strerror(errno));
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
traceEvent(TRACE_DEBUG, "WSAGetLastError(): %u", WSAGetLastError());
|
traceEvent(TRACE_DEBUG, "WSAGetLastError(): %u", WSAGetLastError());
|
||||||
|
@ -2665,14 +2653,14 @@ int run_sn_loop (n2n_sn_t *sss) {
|
||||||
// the prepended length has been read, preparing for the packet
|
// the prepended length has been read, preparing for the packet
|
||||||
conn->expected += be16toh(*(uint16_t*)(conn->buffer));
|
conn->expected += be16toh(*(uint16_t*)(conn->buffer));
|
||||||
if(conn->expected > N2N_SN_PKTBUF_SIZE) {
|
if(conn->expected > N2N_SN_PKTBUF_SIZE) {
|
||||||
traceEvent(TRACE_INFO, "closing tcp connection to [%s]", sock_to_cstr(sockbuf, (n2n_sock_t*)&sender_sock));
|
traceEvent(TRACE_INFO, "closing tcp connection to [%s]", sock_to_cstr(sockbuf, (n2n_sock_t*)sender_sock));
|
||||||
traceEvent(TRACE_DEBUG, "too many bytes in tcp packet expected");
|
traceEvent(TRACE_DEBUG, "too many bytes in tcp packet expected");
|
||||||
close_tcp_connection(sss, conn);
|
close_tcp_connection(sss, conn);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// full packet read, handle it
|
// full packet read, handle it
|
||||||
process_udp(sss, (struct sockaddr_in*)&(conn->sock), conn->socket_fd,
|
process_udp(sss, &(conn->sock), conn->sock_len, conn->socket_fd,
|
||||||
conn->buffer + sizeof(uint16_t), conn->position - sizeof(uint16_t), now);
|
conn->buffer + sizeof(uint16_t), conn->position - sizeof(uint16_t), now);
|
||||||
|
|
||||||
// reset, await new prepended length
|
// reset, await new prepended length
|
||||||
|
@ -2693,42 +2681,45 @@ int run_sn_loop (n2n_sn_t *sss) {
|
||||||
|
|
||||||
// accept new incoming tcp connection
|
// accept new incoming tcp connection
|
||||||
if(FD_ISSET(sss->tcp_sock, &socket_mask)) {
|
if(FD_ISSET(sss->tcp_sock, &socket_mask)) {
|
||||||
struct sockaddr_in sender_sock;
|
struct sockaddr_storage sas;
|
||||||
socklen_t i;
|
struct sockaddr *sender_sock = (struct sockaddr*)&sas;
|
||||||
|
socklen_t ss_size = sizeof(sas);
|
||||||
|
|
||||||
i = sizeof(sender_sock);
|
|
||||||
if((HASH_COUNT(sss->tcp_connections) + 4) < FD_SETSIZE) {
|
if((HASH_COUNT(sss->tcp_connections) + 4) < FD_SETSIZE) {
|
||||||
tmp_sock = accept(sss->tcp_sock, (struct sockaddr *)&sender_sock, (socklen_t *)&i);
|
tmp_sock = accept(sss->tcp_sock, sender_sock, &ss_size);
|
||||||
|
// REVISIT: should we error out if ss_size returns bigger than before? can this ever happen?
|
||||||
if(tmp_sock >= 0) {
|
if(tmp_sock >= 0) {
|
||||||
conn = (n2n_tcp_connection_t*)malloc(sizeof(n2n_tcp_connection_t));
|
conn = (n2n_tcp_connection_t*)calloc(1, sizeof(n2n_tcp_connection_t));
|
||||||
if(conn) {
|
if(conn) {
|
||||||
conn->socket_fd = tmp_sock;
|
conn->socket_fd = tmp_sock;
|
||||||
memcpy(&(conn->sock), &sender_sock, sizeof(struct sockaddr_in));
|
memcpy(&(conn->sock), sender_sock, ss_size);
|
||||||
|
conn->sock_len = ss_size;
|
||||||
conn->inactive = 0;
|
conn->inactive = 0;
|
||||||
conn->expected = sizeof(uint16_t);
|
conn->expected = sizeof(uint16_t);
|
||||||
conn->position = 0;
|
conn->position = 0;
|
||||||
HASH_ADD_INT(sss->tcp_connections, socket_fd, conn);
|
HASH_ADD_INT(sss->tcp_connections, socket_fd, conn);
|
||||||
traceEvent(TRACE_INFO, "accepted incoming TCP connection from [%s]",
|
traceEvent(TRACE_INFO, "accepted incoming TCP connection from [%s]",
|
||||||
sock_to_cstr(sockbuf, (n2n_sock_t*)&sender_sock));
|
sock_to_cstr(sockbuf, (n2n_sock_t*)sender_sock));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// no space to store the socket for a new connection, close immediately
|
// no space to store the socket for a new connection, close immediately
|
||||||
traceEvent(TRACE_DEBUG, "denied incoming TCP connection from [%s] due to max connections limit hit",
|
traceEvent(TRACE_DEBUG, "denied incoming TCP connection from [%s] due to max connections limit hit",
|
||||||
sock_to_cstr(sockbuf, (n2n_sock_t*)&sender_sock));
|
sock_to_cstr(sockbuf, (n2n_sock_t*)sender_sock));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* N2N_HAVE_TCP */
|
#endif /* N2N_HAVE_TCP */
|
||||||
|
|
||||||
// handle management port input
|
// handle management port input
|
||||||
if(FD_ISSET(sss->mgmt_sock, &socket_mask)) {
|
if(FD_ISSET(sss->mgmt_sock, &socket_mask)) {
|
||||||
struct sockaddr_in sender_sock;
|
struct sockaddr_storage sas;
|
||||||
size_t i;
|
struct sockaddr *sender_sock = (struct sockaddr*)&sas;
|
||||||
|
socklen_t ss_size = sizeof(sas);
|
||||||
|
|
||||||
i = sizeof(sender_sock);
|
|
||||||
bread = recvfrom(sss->mgmt_sock, (void *)pktbuf, N2N_SN_PKTBUF_SIZE, 0 /*flags*/,
|
bread = recvfrom(sss->mgmt_sock, (void *)pktbuf, N2N_SN_PKTBUF_SIZE, 0 /*flags*/,
|
||||||
(struct sockaddr *)&sender_sock, (socklen_t *)&i);
|
sender_sock, &ss_size);
|
||||||
|
|
||||||
|
// REVISIT: should we error out if ss_size returns bigger than before? can this ever happen?
|
||||||
if(bread <= 0) {
|
if(bread <= 0) {
|
||||||
traceEvent(TRACE_ERROR, "recvfrom() failed %d errno %d (%s)", bread, errno, strerror(errno));
|
traceEvent(TRACE_ERROR, "recvfrom() failed %d errno %d (%s)", bread, errno, strerror(errno));
|
||||||
*sss->keep_running = 0;
|
*sss->keep_running = 0;
|
||||||
|
@ -2736,7 +2727,7 @@ int run_sn_loop (n2n_sn_t *sss) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// we have a datagram to process
|
// we have a datagram to process
|
||||||
process_mgmt(sss, &sender_sock, (char *)pktbuf, bread, now);
|
process_mgmt(sss, sender_sock, ss_size, (char *)pktbuf, bread, now);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user