-int tcppacket_h(connection_t *c)
-{
- short int len;
-cp
- if(sscanf(c->buffer, "%*d %hd", &len) != 1)
- {
- syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "PACKET", c->name, c->hostname);
- return -1;
- }
-
- /* Set reqlen to len, this will tell receive_meta() that a tcppacket is coming. */
-
- c->tcplen = len;
-cp
- return 0;
+/* Transmitting MTU information */
+
+bool send_mtu_info(node_t *from, node_t *to, int mtu) {
+ /* Skip cases where sending MTU info messages doesn't make sense.
+ This is done here in order to avoid repeating the same logic in multiple callsites. */
+
+ if(to == myself) {
+ return true;
+ }
+
+ if(!to->status.reachable) {
+ 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;
+ }
+
+ /* We will send the passed-in MTU value, unless we believe ours is better. */
+
+ node_t *via = (from->via == myself) ? from->nexthop : from->via;
+
+ if(from->minmtu == from->maxmtu && from->via == myself) {
+ /* We have a direct measurement. Override the value entirely.
+ Note that we only do that if we are sitting as a static relay in the path;
+ otherwise, we can't guarantee packets will flow through us, and increasing
+ MTU could therefore end up being too optimistic. */
+ mtu = from->minmtu;
+ } else if(via->minmtu == via->maxmtu) {
+ /* Static relay. Ensure packets will make it through the entire relay path. */
+ mtu = MIN(mtu, via->minmtu);
+ } else if(via->nexthop->minmtu == via->nexthop->maxmtu) {
+ /* Dynamic relay. Ensure packets will make it through the entire relay path. */
+ 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. */
+
+ return send_request(to->nexthop->connection, "%d %s %s %d", MTU_INFO, from->name, to->name, mtu);