Fix parsing of -b flag
[tinc] / src / protocol_misc.c
index 5fde833..05a4ada 100644 (file)
 #include "utils.h"
 #include "xalloc.h"
 
+#ifndef MIN
+#define MIN(x, y) (((x)<(y))?(x):(y))
+#endif
+
 int maxoutbufsize = 0;
+int mtu_info_interval = 5;
+int udp_info_interval = 5;
 
 /* Status and error notification routines */
 
@@ -129,7 +135,7 @@ bool send_tcppacket(connection_t *c, const vpn_packet_t *packet) {
        if(2.0 * c->outbuf.len / (float)maxoutbufsize - 1 > (float)rand()/(float)RAND_MAX)
                return true;
 
-       if(!send_request(c, "%d %hd", PACKET, packet->len))
+       if(!send_request(c, "%d %d", PACKET, packet->len))
                return false;
 
        return send_meta(c, (char *)DATA(packet), packet->len);
@@ -151,6 +157,36 @@ bool tcppacket_h(connection_t *c, const char *request) {
        return true;
 }
 
+bool send_sptps_tcppacket(connection_t *c, const char* packet, int len) {
+       /* If there already is a lot of data in the outbuf buffer, discard this packet.
+          We use a very simple Random Early Drop algorithm. */
+
+       if(2.0 * c->outbuf.len / (float)maxoutbufsize - 1 > (float)rand()/(float)RAND_MAX)
+               return true;
+
+       if(!send_request(c, "%d %d", SPTPS_PACKET, len))
+               return false;
+
+       send_meta_raw(c, packet, len);
+       return true;
+}
+
+bool sptps_tcppacket_h(connection_t *c, const char* request) {
+       short int len;
+
+       if(sscanf(request, "%*d %hd", &len) != 1) {
+               logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "SPTPS_PACKET", c->name,
+                          c->hostname);
+               return false;
+       }
+
+       /* Set sptpslen to len, this will tell receive_meta() that a SPTPS packet is coming. */
+
+       c->sptpslen = len;
+
+       return true;
+}
+
 /* Transmitting UDP information */
 
 bool send_udp_info(node_t *from, node_t *to) {
@@ -158,6 +194,11 @@ bool send_udp_info(node_t *from, node_t *to) {
           farther than the static relay. */
        to = (to->via == myself) ? to->nexthop : to->via;
 
+       if (to == NULL) {
+               logger(DEBUG_ALWAYS, LOG_ERR, "Something went wrong when selecting relay - possible fake UDP_INFO");
+               return false;
+       }
+
        /* Skip cases where sending UDP info messages doesn't make sense.
           This is done here in order to avoid repeating the same logic in multiple callsites. */
 
@@ -167,8 +208,15 @@ bool send_udp_info(node_t *from, node_t *to) {
        if(!to->status.reachable)
                return true;
 
-       if(from == myself && to->connection)
-               return true;
+       if(from == myself) {
+               if(to->connection)
+                       return true;
+
+               struct timeval elapsed;
+               timersub(&now, &to->udp_info_sent, &elapsed);
+               if(elapsed.tv_sec < udp_info_interval)
+                       return true;
+       }
 
        if((myself->options | from->options | to->options) & OPTION_TCPONLY)
                return true;
@@ -188,6 +236,9 @@ bool send_udp_info(node_t *from, node_t *to) {
        free(from_address);
        free(from_port);
 
+       if(from == myself)
+               to->udp_info_sent = now;
+
        return x;
 }
 
@@ -250,8 +301,15 @@ bool send_mtu_info(node_t *from, node_t *to, int mtu) {
        if(!to->status.reachable)
                return true;
 
-       if(from == myself && to->connection)
-               return true;
+       if(from == myself) {
+               if(to->connection)
+                       return true;
+
+               struct timeval elapsed;
+               timersub(&now, &to->mtu_info_sent, &elapsed);
+               if(elapsed.tv_sec < mtu_info_interval)
+                       return true;
+       }
 
        if((to->nexthop->options >> 24) < 6)
                return true;
@@ -273,6 +331,9 @@ bool send_mtu_info(node_t *from, node_t *to, int mtu) {
                mtu = MIN(mtu, via->nexthop->minmtu);
        }
 
+       if(from == myself)
+               to->mtu_info_sent = now;
+
        /* If none of the conditions above match in the steady state, it means we're using TCP,
           so the MTU is irrelevant. That said, it is still important to honor the MTU that was passed in,
           because other parts of the relay path might be able to use UDP, which means they care about the MTU. */