extern listen_socket_t listen_socket[MAXSOCKETS];
extern int listen_sockets;
-extern int keyexpires;
extern int keylifetime;
+ extern int udp_rcvbuf;
+ extern int udp_sndbuf;
extern bool do_prune;
-extern bool do_purge;
extern char *myport;
-extern time_t now;
extern int contradicting_add_edge;
extern int contradicting_del_edge;
/* Check the sequence number */
- inpkt->len -= sizeof(inpkt->seqno);
+ inpkt->len -= sizeof inpkt->seqno;
inpkt->seqno = ntohl(inpkt->seqno);
- if(inpkt->seqno != n->received_seqno + 1) {
- if(inpkt->seqno >= n->received_seqno + sizeof n->late * 8) {
- logger(LOG_WARNING, "Lost %d packets from %s (%s)",
- inpkt->seqno - n->received_seqno - 1, n->name, n->hostname);
-
- memset(n->late, 0, sizeof n->late);
- } else if (inpkt->seqno <= n->received_seqno) {
- if((n->received_seqno >= sizeof n->late * 8 && inpkt->seqno <= n->received_seqno - sizeof n->late * 8) || !(n->late[(inpkt->seqno / 8) % sizeof n->late] & (1 << inpkt->seqno % 8))) {
- logger(LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d",
- n->name, n->hostname, inpkt->seqno, n->received_seqno);
- return;
+ if(replaywin) {
+ if(inpkt->seqno != n->received_seqno + 1) {
+ if(inpkt->seqno >= n->received_seqno + replaywin * 8) {
+ if(n->farfuture++ < replaywin >> 2) {
+ logger(LOG_WARNING, "Packet from %s (%s) is %d seqs in the future, dropped (%u)",
+ n->name, n->hostname, inpkt->seqno - n->received_seqno - 1, n->farfuture);
+ return;
+ }
+ logger(LOG_WARNING, "Lost %d packets from %s (%s)",
+ inpkt->seqno - n->received_seqno - 1, n->name, n->hostname);
+ memset(n->late, 0, replaywin);
+ } else if (inpkt->seqno <= n->received_seqno) {
+ if((n->received_seqno >= replaywin * 8 && inpkt->seqno <= n->received_seqno - replaywin * 8) || !(n->late[(inpkt->seqno / 8) % replaywin] & (1 << inpkt->seqno % 8))) {
+ logger(LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d",
+ n->name, n->hostname, inpkt->seqno, n->received_seqno);
+ return;
+ }
+ } else {
+ for(i = n->received_seqno + 1; i < inpkt->seqno; i++)
+ n->late[(i / 8) % replaywin] |= 1 << i % 8;
}
- } else {
- for(i = n->received_seqno + 1; i < inpkt->seqno; i++)
- n->late[(i / 8) % sizeof n->late] |= 1 << i % 8;
}
+
+ n->farfuture = 0;
+ n->late[(inpkt->seqno / 8) % replaywin] &= ~(1 << inpkt->seqno % 8);
}
-
- n->late[(inpkt->seqno / 8) % sizeof n->late] &= ~(1 << inpkt->seqno % 8);
if(inpkt->seqno > n->received_seqno)
n->received_seqno = inpkt->seqno;
#endif
option = 1;
- setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof(option));
+ setsockopt(nfd, SOL_SOCKET, SO_REUSEADDR, (void *)&option, sizeof option);
+ if(udp_rcvbuf && setsockopt(nfd, SOL_SOCKET, SO_RCVBUF, (void *)&udp_rcvbuf, sizeof(udp_rcvbuf)))
+ logger(LOG_WARNING, "Can't set UDP SO_RCVBUF to %i: %s", udp_rcvbuf, strerror(errno));
+
+ if(udp_sndbuf && setsockopt(nfd, SOL_SOCKET, SO_SNDBUF, (void *)&udp_sndbuf, sizeof(udp_sndbuf)))
+ logger(LOG_WARNING, "Can't set UDP SO_SNDBUF to %i: %s", udp_sndbuf, strerror(errno));
+
#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
if(sa->sa.sa_family == AF_INET6)
setsockopt(nfd, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&option, sizeof option);
}
node_t *new_node(void) {
- node_t *n = xmalloc_and_zero(sizeof(*n));
+ node_t *n = xmalloc_and_zero(sizeof *n);
+ if(replaywin) n->late = xmalloc_and_zero(replaywin);
n->subnet_tree = new_subnet_tree();
n->edge_tree = new_edge_tree();
- EVP_CIPHER_CTX_init(&n->inctx);
- EVP_CIPHER_CTX_init(&n->outctx);
n->mtu = MTU;
n->maxmtu = MTU;
// Reset sequence number and late packet window
mykeyused = true;
to->received_seqno = 0;
- memset(to->late, 0, sizeof(to->late));
+ if(replaywin) memset(to->late, 0, replaywin);
- // Convert to hexadecimal and send
- char key[2 * to->inkeylength + 1];
- bin2hex(to->inkey, key, to->inkeylength);
- key[to->inkeylength * 2] = '\0';
-
- return send_request(to->nexthop->connection, "%d %s %s %s %d %d %d %d", ANS_KEY,
- myself->name, to->name, key,
- to->incipher ? to->incipher->nid : 0,
- to->indigest ? to->indigest->type : 0, to->inmaclength,
- to->incompression);
+ return send_request(to->nexthop->connection, "%d %s %s %s %d %d %zu %d", ANS_KEY,
+ myself->name, to->name, key,
+ cipher_get_nid(&to->incipher),
+ digest_get_nid(&to->indigest),
+ digest_length(&to->indigest),
+ to->incompression);
}
-bool ans_key_h(connection_t *c) {
+bool ans_key_h(connection_t *c, char *request) {
char from_name[MAX_STRING_SIZE];
char to_name[MAX_STRING_SIZE];
char key[MAX_STRING_SIZE];