/*
net_packet.c -- Handles in- and outgoing VPN packets
Copyright (C) 1998-2005 Ivo Timmermans,
- 2000-2016 Guus Sliepen <guus@tinc-vpn.org>
+ 2000-2017 Guus Sliepen <guus@tinc-vpn.org>
2010 Timothy Redaelli <timothy@redaelli.eu>
2010 Brandon Black <blblack@gmail.com>
/* Check the sequence number */
seqno_t seqno;
- memcpy(&seqno, SEQNO(inpkt), sizeof seqno);
+ memcpy(&seqno, SEQNO(inpkt), sizeof(seqno));
seqno = ntohl(seqno);
- inpkt->len -= sizeof seqno;
+ inpkt->len -= sizeof(seqno);
if(replaywin) {
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)",
+ logger(DEBUG_TRAFFIC, LOG_WARNING, "Packet from %s (%s) is %d seqs in the future, dropped (%u)",
n->name, n->hostname, seqno - n->received_seqno - 1, n->farfuture);
return false;
}
- logger(DEBUG_ALWAYS, LOG_WARNING, "Lost %d packets from %s (%s)",
+ logger(DEBUG_TRAFFIC, LOG_WARNING, "Lost %d packets from %s (%s)",
seqno - n->received_seqno - 1, n->name, n->hostname);
memset(n->late, 0, replaywin);
} 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",
+ logger(DEBUG_TRAFFIC, LOG_WARNING, "Got late or replayed packet from %s (%s), seqno %d, last received %d",
n->name, n->hostname, seqno, n->received_seqno);
return false;
}
vpn_packet_t outpkt;
outpkt.offset = DEFAULT_PACKET_OFFSET;
- if(len > sizeof outpkt.data - outpkt.offset)
+ if(len > sizeof(outpkt.data) - outpkt.offset)
return;
outpkt.len = len;
bool receive_tcppacket_sptps(connection_t *c, const char *data, int len) {
if (len < sizeof(node_id_t) + sizeof(node_id_t)) {
- logger(DEBUG_ALWAYS, LOG_ERR, "Got too short TCP SPTPS packet from %s (%s)", c->name, c->hostname);
+ logger(DEBUG_PROTOCOL, LOG_ERR, "Got too short TCP SPTPS packet from %s (%s)", c->name, c->hostname);
return false;
}
uint8_t type = 0;
int offset = 0;
- if(!(DATA(origpkt)[12] | DATA(origpkt)[13])) {
+ if((!(DATA(origpkt)[12] | DATA(origpkt)[13])) && (n->sptps.outstate)) {
sptps_send_record(&n->sptps, PKT_PROBE, (char *)DATA(origpkt), origpkt->len);
return;
}
/* Add sequence number */
seqno_t seqno = htonl(++(n->sent_seqno));
- memcpy(SEQNO(inpkt), &seqno, sizeof seqno);
- inpkt->len += sizeof seqno;
+ memcpy(SEQNO(inpkt), &seqno, sizeof(seqno));
+ inpkt->len += sizeof(seqno);
/* Encrypt the packet */
if(priorityinheritance && origpriority != listen_socket[sock].priority) {
listen_socket[sock].priority = origpriority;
switch(sa->sa.sa_family) {
-#if defined(SOL_IP) && defined(IP_TOS)
+#if defined(IPPROTO_IP) && defined(IP_TOS)
case AF_INET:
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Setting IPv4 outgoing packet priority to %d", origpriority);
- if(setsockopt(listen_socket[sock].udp.fd, SOL_IP, IP_TOS, &origpriority, sizeof origpriority)) /* SO_PRIORITY doesn't seem to work */
+ if(setsockopt(listen_socket[sock].udp.fd, IPPROTO_IP, IP_TOS, (void *)&origpriority, sizeof(origpriority))) /* SO_PRIORITY doesn't seem to work */
logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setsockopt", sockstrerror(sockerrno));
break;
#endif
#if defined(IPPROTO_IPV6) & defined(IPV6_TCLASS)
case AF_INET6:
logger(DEBUG_TRAFFIC, LOG_DEBUG, "Setting IPv6 outgoing packet priority to %d", origpriority);
- if(setsockopt(listen_socket[sock].udp.fd, IPPROTO_IPV6, IPV6_TCLASS, (void *)&origpriority, sizeof origpriority)) /* SO_PRIORITY doesn't seem to work */
+ if(setsockopt(listen_socket[sock].udp.fd, IPPROTO_IPV6, IPV6_TCLASS, (void *)&origpriority, sizeof(origpriority))) /* SO_PRIORITY doesn't seem to work */
logger(DEBUG_ALWAYS, LOG_ERR, "System call `%s' failed: %s", "setsockopt", sockstrerror(sockerrno));
break;
#endif
if(type == SPTPS_HANDSHAKE || tcponly || (!direct && !relay_supported) || (type != PKT_PROBE && (len - SPTPS_DATAGRAM_OVERHEAD) > relay->minmtu)) {
if(type != SPTPS_HANDSHAKE && (to->nexthop->connection->options >> 24) >= 7) {
- char buf[len + sizeof to->id + sizeof from->id]; char* buf_ptr = buf;
- memcpy(buf_ptr, &to->id, sizeof to->id); buf_ptr += sizeof to->id;
- memcpy(buf_ptr, &from->id, sizeof from->id); buf_ptr += sizeof from->id;
- memcpy(buf_ptr, data, len); buf_ptr += len;
+ char buf[len + sizeof(to->id) + sizeof from->id]; char* buf_ptr = buf;
+ memcpy(buf_ptr, &to->id, sizeof(to->id)); buf_ptr += sizeof to->id;
+ memcpy(buf_ptr, &from->id, sizeof(from->id)); buf_ptr += sizeof from->id;
+ memcpy(buf_ptr, data, len);
logger(DEBUG_TRAFFIC, LOG_INFO, "Sending packet from %s (%s) to %s (%s) via %s (%s) (TCP)", from->name, from->hostname, to->name, to->hostname, to->nexthop->name, to->nexthop->hostname);
- return send_sptps_tcppacket(to->nexthop->connection, buf, sizeof buf);
+ return send_sptps_tcppacket(to->nexthop->connection, buf, sizeof(buf));
}
char buf[len * 4 / 3 + 5];
}
size_t overhead = 0;
- if(relay_supported) overhead += sizeof to->id + sizeof from->id;
+ if(relay_supported) overhead += sizeof(to->id) + sizeof from->id;
char buf[len + overhead]; char* buf_ptr = buf;
if(relay_supported) {
if(direct) {
/* Inform the recipient that this packet was sent directly. */
node_id_t nullid = {};
- memcpy(buf_ptr, &nullid, sizeof nullid); buf_ptr += sizeof nullid;
+ memcpy(buf_ptr, &nullid, sizeof(nullid)); buf_ptr += sizeof nullid;
} else {
- memcpy(buf_ptr, &to->id, sizeof to->id); buf_ptr += sizeof to->id;
+ memcpy(buf_ptr, &to->id, sizeof(to->id)); buf_ptr += sizeof to->id;
}
- memcpy(buf_ptr, &from->id, sizeof from->id); buf_ptr += sizeof from->id;
+ memcpy(buf_ptr, &from->id, sizeof(from->id)); buf_ptr += sizeof from->id;
}
/* TODO: if this copy turns out to be a performance concern, change sptps_send_record() to add some "pre-padding" to the buffer and use that instead */
vpn_packet_t inpkt;
inpkt.offset = DEFAULT_PACKET_OFFSET;
+ inpkt.priority = 0;
if(type == PKT_PROBE) {
if(!from->status.udppacket) {
}
int ip_mtu;
- socklen_t ip_mtu_len = sizeof ip_mtu;
+ socklen_t ip_mtu_len = sizeof(ip_mtu);
if(getsockopt(sock, IPPROTO_IP, IP_MTU, &ip_mtu, &ip_mtu_len)) {
logger(DEBUG_TRAFFIC, LOG_ERR, "getsockopt(IP_MTU) on %s (%s) failed: %s", n->name, n->hostname, sockstrerror(sockerrno));
close(sock);
// It might be from a 1.1 node, which might have a source ID in the packet.
pkt->offset = 2 * sizeof(node_id_t);
from = lookup_node_id(SRCID(pkt));
- if(from && !memcmp(DSTID(pkt), &nullid, sizeof nullid) && from->status.sptps) {
+ if(from && !memcmp(DSTID(pkt), &nullid, sizeof(nullid)) && from->status.sptps) {
if(sptps_verify_datagram(&from->sptps, DATA(pkt), pkt->len - 2 * sizeof(node_id_t)))
n = from;
else
pkt->len -= pkt->offset;
}
- if(!memcmp(DSTID(pkt), &nullid, sizeof nullid) || !relay_enabled) {
+ if(!memcmp(DSTID(pkt), &nullid, sizeof(nullid)) || !relay_enabled) {
direct = true;
from = n;
to = myself;
msg[i].msg_hdr = (struct msghdr){
.msg_name = &addr[i].sa,
- .msg_namelen = sizeof addr[i],
+ .msg_namelen = sizeof(addr)[i],
.msg_iov = &iov[i],
.msg_iovlen = 1,
};
#else
vpn_packet_t pkt;
sockaddr_t addr = {};
- socklen_t addrlen = sizeof addr;
+ socklen_t addrlen = sizeof(addr);
pkt.offset = 0;
int len = recvfrom(ls->udp.fd, (void *)DATA(&pkt), MAXSIZE, 0, &addr.sa, &addrlen);
vpn_packet_t packet;
packet.offset = DEFAULT_PACKET_OFFSET;
packet.priority = 0;
+ static int errors = 0;
if(devops.read(&packet)) {
+ errors = 0;
myself->in_packets++;
myself->in_bytes += packet.len;
route(myself, &packet);
+ } else {
+ usleep(errors * 50000);
+ errors++;
+ if(errors > 10) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "Too many errors from %s, exiting!", device);
+ event_exit();
+ }
}
}