/* It's a probe request, send back a reply */
/* Type 2 probe replies were introduced in protocol 17.3 */
- if ((n->options >> 24) == 3) {
+ if ((n->options >> 24) >= 3) {
uint8_t* data = packet->data;
*data++ = 2;
uint16_t len16 = htons(len); memcpy(data, &len16, 2); data += 2;
vpn_packet_t pkt1, pkt2;
vpn_packet_t *pkt[] = { &pkt1, &pkt2, &pkt1, &pkt2 };
int nextpkt = 0;
- vpn_packet_t *outpkt = pkt[0];
size_t outlen;
if(n->status.sptps) {
/* Decrypt the packet */
if(cipher_active(n->incipher)) {
- outpkt = pkt[nextpkt++];
+ vpn_packet_t *outpkt = pkt[nextpkt++];
outlen = MAXSIZE;
if(!cipher_decrypt(n->incipher, &inpkt->seqno, inpkt->len, &outpkt->seqno, &outlen, true)) {
/* Check the sequence number */
inpkt->len -= sizeof inpkt->seqno;
- inpkt->seqno = ntohl(inpkt->seqno);
+ uint32_t seqno;
+ memcpy(&seqno, inpkt->seqno, sizeof seqno);
+ seqno = ntohl(seqno);
if(replaywin) {
- if(inpkt->seqno != n->received_seqno + 1) {
- if(inpkt->seqno >= n->received_seqno + replaywin * 8) {
+ if(seqno != n->received_seqno + 1) {
+ if(seqno >= n->received_seqno + replaywin * 8) {
if(n->farfuture++ < replaywin >> 2) {
logger(DEBUG_ALWAYS, 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);
+ n->name, n->hostname, seqno - n->received_seqno - 1, n->farfuture);
return;
}
logger(DEBUG_ALWAYS, LOG_WARNING, "Lost %d packets from %s (%s)",
- inpkt->seqno - n->received_seqno - 1, n->name, n->hostname);
+ 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))) {
+ } else if (seqno <= n->received_seqno) {
+ if((n->received_seqno >= replaywin * 8 && seqno <= n->received_seqno - replaywin * 8) || !(n->late[(seqno / 8) % replaywin] & (1 << seqno % 8))) {
logger(DEBUG_ALWAYS, LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d",
- n->name, n->hostname, inpkt->seqno, n->received_seqno);
+ n->name, n->hostname, seqno, n->received_seqno);
return;
}
} else {
- for(int i = n->received_seqno + 1; i < inpkt->seqno; i++)
+ for(int i = n->received_seqno + 1; i < seqno; i++)
n->late[(i / 8) % replaywin] |= 1 << i % 8;
}
}
n->farfuture = 0;
- n->late[(inpkt->seqno / 8) % replaywin] &= ~(1 << inpkt->seqno % 8);
+ n->late[(seqno / 8) % replaywin] &= ~(1 << seqno % 8);
}
- if(inpkt->seqno > n->received_seqno)
- n->received_seqno = inpkt->seqno;
+ if(seqno > n->received_seqno)
+ n->received_seqno = seqno;
n->received++;
length_t origlen = inpkt->len;
if(n->incompression) {
- outpkt = pkt[nextpkt++];
+ vpn_packet_t *outpkt = pkt[nextpkt++];
if((outpkt->len = uncompress_packet(outpkt->data, inpkt->data, inpkt->len, n->incompression)) < 0) {
logger(DEBUG_TRAFFIC, LOG_ERR, "Error while uncompressing packet from %s (%s)",
size_t outlen;
#if defined(SOL_IP) && defined(IP_TOS)
static int priority = 0;
-#endif
int origpriority = origpkt->priority;
+#endif
if(!n->status.reachable) {
logger(DEBUG_TRAFFIC, LOG_INFO, "Trying to send UDP packet to unreachable node %s (%s)", n->name, n->hostname);
/* Add sequence number */
- inpkt->seqno = htonl(++(n->sent_seqno));
+ uint32_t seqno = htonl(++(n->sent_seqno));
+ memcpy(inpkt->seqno, &seqno, sizeof inpkt->seqno);
inpkt->len += sizeof inpkt->seqno;
/* Encrypt the packet */
outpkt = pkt[nextpkt++];
outlen = MAXSIZE;
- if(!cipher_encrypt(n->outcipher, &inpkt->seqno, inpkt->len, &outpkt->seqno, &outlen, true)) {
+ if(!cipher_encrypt(n->outcipher, inpkt->seqno, inpkt->len, outpkt->seqno, &outlen, true)) {
logger(DEBUG_TRAFFIC, LOG_ERR, "Error while encrypting packet to %s (%s)", n->name, n->hostname);
goto end;
}
/* Add the message authentication code */
if(digest_active(n->outdigest)) {
- if(!digest_create(n->outdigest, &inpkt->seqno, inpkt->len, (char *)&inpkt->seqno + inpkt->len)) {
+ if(!digest_create(n->outdigest, inpkt->seqno, inpkt->len, inpkt->seqno + inpkt->len)) {
logger(DEBUG_TRAFFIC, LOG_ERR, "Error while encrypting packet to %s (%s)", n->name, n->hostname);
goto end;
}
}
#endif
- if(sendto(listen_socket[sock].udp.fd, (char *) &inpkt->seqno, inpkt->len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
+ if(sendto(listen_socket[sock].udp.fd, inpkt->seqno, inpkt->len, 0, &sa->sa, SALEN(sa->sa)) < 0 && !sockwouldblock(sockerrno)) {
if(sockmsgsize(sockerrno)) {
if(n->maxmtu >= origlen)
n->maxmtu = origlen - 1;
// usually distributes the sending of broadcast packets over all nodes.
case BMODE_MST:
for list_each(connection_t, c, connection_list)
- if(c->status.active && c->status.mst && c != from->nexthop->connection)
+ if(c->edge && c->status.mst && c != from->nexthop->connection)
send_packet(c->node, packet);
break;
node_t *n;
int len;
- len = recvfrom(ls->udp.fd, (char *) &pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen);
+ len = recvfrom(ls->udp.fd, pkt.seqno, MAXSIZE, 0, &from.sa, &fromlen);
if(len <= 0 || len > MAXSIZE) {
if(!sockwouldblock(sockerrno))