#!/bin/bash # # Network MTU resolution. # --------------------------------------------------------------------------- # CFG_NETWORK_MTU drives BOTH the rootless daemon's uplink MTU # (DOCKERD_ROOTLESS_ROOTLESSKIT_MTU — how image PULLS egress) and every app's # container-network MTU (the NETWORK_MTU_TAG baked into each compose). A blind # 1500 breaks on links whose real path MTU is lower (Qubes/NAT/VPN with PMTU # discovery blocked): small transfers (image manifests, tiny images) succeed but # large image-layer downloads stall and reset with "EOF" mid-blob. # # CFG_NETWORK_MTU accepts: # — use exactly (explicit override). # auto — probe the path MTU once, cache a safe value (default). # # The probe is a don't-fragment ICMP ladder. If ICMP is fully filtered (no probe # gets through at all) we can't tell a clean link from a constrained one, so we # assume the standard 1500 rather than needlessly shrinking every network — set # an explicit number for that case. networkMtuCacheFile() { echo "${docker_dir%/}/.network_mtu"; } # Largest standard MTU whose don't-fragment probe reaches the internet. # Echoes a number; 1500 when no signal (ping missing / all probes filtered). networkDetectMtu() { local host="${1:-1.1.1.1}" m best="" command -v ping >/dev/null 2>&1 || { echo 1500; return 0; } for m in 1500 1492 1400 1300 1280; do # payload = mtu - 28 (IPv4 + ICMP headers) if ping -M do -s $((m - 28)) -c1 -W2 "$host" >/dev/null 2>&1; then best="$m"; break fi done echo "${best:-1500}" } # The concrete MTU to bake into the daemon + composes. Resolves CFG_NETWORK_MTU: # a number is used verbatim; "auto"/empty is probed once and cached so we don't # re-ping on every app install. networkEffectiveMtu() { local want="${CFG_NETWORK_MTU:-auto}" if [[ "$want" =~ ^[0-9]+$ ]]; then echo "$want"; return 0; fi local cache cached cache="$(networkMtuCacheFile)" cached="$(cat "$cache" 2>/dev/null | tr -dc '0-9')" if [[ -n "$cached" ]]; then echo "$cached"; return 0; fi local detected; detected="$(networkDetectMtu)" if declare -F runInstallWrite >/dev/null 2>&1; then printf '%s\n' "$detected" | runInstallWrite "$cache" 2>/dev/null || true else printf '%s\n' "$detected" > "$cache" 2>/dev/null || true fi echo "$detected" } # Force a fresh probe (clears the cache), echoing the new value. The rootless # setup calls this so each (re)install re-detects the current link. networkRedetectMtu() { local cache; cache="$(networkMtuCacheFile)" if declare -F runInstallOp >/dev/null 2>&1; then runInstallOp rm -f "$cache" 2>/dev/null || true else rm -f "$cache" 2>/dev/null || true fi networkEffectiveMtu }