SagerNet / SagerNet/sing-box

TUIC/BBR: upload throughput drops after a download on a reused connection (local CLI reproducer)

Open
#4,538 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
38.2k
Forks
4.6k
Avg merge
19d 15h
Merged PRs (30d)
1

Description

Operating system

Linux

System version

Debian GNU/Linux forky/sid, x86_64; Linux 6.18.35-x64v1-xanmod1.

Installation type

Original sing-box Command Line

If you are using a graphical client, please provide the version of the client.

Not applicable to the reproduction; no graphical client is used.

Version
sing-box version 1.14.1

Environment: go1.26.8 linux/amd64
Tags: with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_ocm,with_cloudflared,with_naive_outbound,with_usbip,with_openvpn,with_openconnect,badlinkname,tfogo_checklinkname0,with_musl
Revision: 1ac1a339cb1223e9c70eae14c44411c75033c02d
CGO: enabled
Description

On a local, isolated, rate-limited link, a TUIC client using BBR has substantially lower upload throughput after a sequence containing downloads than a fresh client performing the same final upload. The client process and its TUIC connection stay alive throughout each sequence. Restarting the client for the fresh comparison restores the higher throughput in this test.

Expected: with unchanged link capacity, no configured loss, no competing application traffic and identical final upload size/concurrency, previous downloads should not cause this degree of subsequent upload degradation.

Observed with the original 1.14.1 command-line binary, two rounds with reversed case order:

Round Fresh connection: upload Mbps After download sequence: upload Mbps Reduction
1 87.109 54.112 37.9%
2 88.290 51.299 41.9%

The final upload is 16 MiB total across four concurrent TCP streams, not 16 MiB per stream. Throughput is total verified payload bytes × 8 / wall-clock completion time, in decimal Mbps. Timing includes SOCKS connection setup and the receiver's final byte-count acknowledgement. Both variants use exactly the same final upload workload and a 1 MiB warm-up upload. All payload bytes are verified; there are no failed or omitted phases in the reported final run.

The link is shaped to 100 Mbps per direction, with 5 ms added delay per direction (approximately 10 ms propagation RTT). No packet loss is configured. Both namespaces' HTB/netem end counters report zero drops and zero remaining backlog. HTB overlimits reflect rate shaping, not dropped packets. GSO is disabled for these isolated sing-box processes only, to make the artificial link test more controlled. These numbers are specific to this short workload and environment, not a universal throughput limit.

This investigation began with much more severe Windows/Android upload symptoms. In one Windows comparison, sing-box 1.14.1 reported 290.36 Mbps download / 4.64 Mbps upload, whereas FlClash reported 426.22 / 362.37 Mbps through the same public exit. However, those GUI measurements are background only: a CUBIC trial did not resolve the device symptom, and this Linux BBR reproduction does not establish that both problems have the same root cause. This report is deliberately scoped to the independently reproducible local throughput regression.

Possible investigation area, not a confirmed diagnosis from these logs: application-limited accounting when receive-heavy traffic generates outbound control frames. The relevant dependency is SagerNet/quic-go v0.61.0-sing-box-mod.7, via sing-quic v0.7.0. Earlier diagnostic experiments suggested inspecting packerEmptyTime and the injected congestion controller's OnAppLimited call. The reported measurements below use the unmodified binary; no candidate patch is required to reproduce them.

Source references:

Reproduction

Everything runs on one Linux machine using the original sing-box CLI. No external proxy, Internet test endpoint, DNS resolver, TUN, GUI or closed-source program is needed during the test.

Requirements: root/CAP_NET_ADMIN access with Linux network namespaces, ip and tc from iproute2, Python 3, OpenSSL, and the original sing-box 1.14.1 binary. The recorded host uses the kernel listed above; portability to other kernels has not yet been established.

  1. Save the complete script below as repro.py (or extract it from the attached tuic-upload-evidence.zip).

  2. Run it with the absolute path to the original sing-box binary. Choose a new output directory for each invocation:

    sudo python3 repro.py --binary /usr/bin/sing-box --output ./repro-output
    
  3. Compare the final phase of each fresh and after-download case in repro-output/results.json. The script prints the same measurements and records complete client/server logs.

Topology:

Python workload -> SOCKS 127.0.0.1:18890 -> sing-box TUIC client
        isolated client namespace, 192.0.2.1
               <veth; HTB 100 Mbps + netem 5 ms each way>
        isolated server namespace, 192.0.2.2
sing-box TUIC server :14443 -> Python receiver 127.0.0.1:18080

The script creates random temporary namespace names and lab-only credentials, generates and verifies a self-signed test certificate, checks both configs with sing-box check, then starts original CLI server/client processes. It does not read production configs or alter host-interface routes/qdiscs. Both namespaces have an isolated default route only to satisfy interface monitoring. Temporary processes, namespaces and the private test key are removed on exit.

Case sequences (sizes are total payload per phase):

  • fresh: restart client → UP 1 MiB / 1 stream (warm-up) → UP 16 MiB / 4 streams (measurement).
  • after-download: restart client → UP 1 MiB / 1 → UP 4 MiB / 1 → DOWN 4 MiB / 1 → UP 16 MiB / 1 → DOWN 16 MiB / 1 → UP 16 MiB / 4 (measurement).
  • Round 1 runs fresh then after-download; round 2 reverses that order. The server remains running. TCP streams are recreated between phases; TUIC client state is retained within each case. This compares the complete specified histories; it does not isolate a single preceding packet or prove permanence of the degradation.

BBR is explicitly selected on both ends. initial_packet_size: 1200 plus disabled PMTU discovery hold QUIC packet sizing constant. udp_relay_mode: native records the existing baseline but no application UDP relay is exercised: all workload streams are TCP. h3 is the pinned ALPN. Other features such as TUN, sniffing, DNS filtering, selector/URLTest groups, multiplexing extensions and Tailscale are absent.

Complete reproduction script

repro.py
#!/usr/bin/env python3
"""Local TUIC connection-history benchmark. Requires root, Linux ip/tc, openssl.
Only creates disposable network namespaces; no production config or host qdisc changes.
Usage: sudo python3 repro.py --binary /absolute/path/sing-box --output ./repro-output
"""
import argparse, concurrent.futures, hashlib, json, os, pathlib, shutil, socket, socketserver, struct, subprocess, sys, tempfile, threading, time, uuid

def exact(s,n):
    b=b''
    while len(b)<n:
        x=s.recv(n-len(b))
        if not x:raise EOFError('short transfer')
        b+=x
    return b

class Receiver(socketserver.BaseRequestHandler):
    def handle(self):
        s=self.request;s.settimeout(60);s.setsockopt(socket.IPPROTO_TCP,socket.TCP_NODELAY,1)
        line=b''
        while not line.endswith(b'\n'):
            line+=exact(s,1)
            if len(line)>100:raise ValueError('long header')
        op,n=line.decode().split();n=int(n)
        if op=='UP':
            count=0
            while count<n:
                data=s.recv(min(65536,n-count))
                if not data:raise EOFError('short upload')
                if data!=b'x'*len(data):raise ValueError('wrong upload data')
                count+=len(data)
            s.sendall((str(count)+'\n').encode())
        elif op=='DOWN':
            remaining=n
            while remaining:
                data=b'x'*min(65536,remaining);s.sendall(data);remaining-=len(data)

def transfer(op,size,barrier):
    with socket.create_connection(('127.0.0.1',18890),timeout=60) as s:
        s.setsockopt(socket.IPPROTO_TCP,socket.TCP_NODELAY,1)
        s.sendall(b'\5\1\0');assert exact(s,2)==b'\5\0'
        s.sendall(b'\5\1\0\1'+socket.inet_aton('127.0.0.1')+struct.pack('!H',18080))
        h=exact(s,4);assert h[1]==0
        if h[3]==1:exact(s,6)
        elif h[3]==4:exact(s,18)
        else:exact(s,exact(s,1)[0]+2)
        barrier.wait(60);s.sendall(f'{op} {size}\n'.encode());count=0
        while count<size:
            if op=='UP':
                data=b'x'*min(65536,size-count);s.sendall(data)
            else:
                data=s.recv(min(65536,size-count))
                if not data:raise EOFError('short download')
                if data!=b'x'*len(data):raise ValueError('wrong download data')
            count+=len(data)
        if op=='UP':
            ack=b''
            while not ack.endswith(b'\n'):ack+=exact(s,1)
            assert int(ack)==size
        return count

def worker(phases):
    results=[]
    for op,mib,streams in phases:
        size=mib*1048576;barrier=threading.Barrier(streams);start=time.monotonic()
        with concurrent.futures.ThreadPoolExecutor(max_workers=streams) as pool:
            jobs=[pool.submit(transfer,op,size//streams,barrier) for _ in range(streams)]
            total=sum(j.result() for j in jobs)
        elapsed=time.monotonic()-start;assert total==size
        results.append({'direction':op,'MiB':mib,'streams':streams,'bytes':total,'seconds':round(elapsed,6),'Mbps':round(size*8/elapsed/1e6,3)})
    print(json.dumps(results),flush=True)

def main():
    ap=argparse.ArgumentParser();ap.add_argument('--binary',default='/usr/bin/sing-box');ap.add_argument('--output',required=True);ap.add_argument('--delay-ms',type=float,default=5);ap.add_argument('--rate-mbps',type=int,default=100);ap.add_argument('--rounds',type=int,default=2);a=ap.parse_args()
    if os.geteuid()!=0:raise SystemExit('Run as root: disposable network namespaces require it.')
    binary=str(pathlib.Path(a.binary).resolve());script=str(pathlib.Path(__file__).resolve());out=pathlib.Path(a.output).resolve()
    if out.exists():raise SystemExit('Output directory already exists; choose a new path.')
    out.mkdir(mode=0o700,parents=True)
    for tool in ['ip','tc','openssl']:
        if not shutil.which(tool):raise SystemExit('Missing required tool: '+tool)
    def run(args,**kw):return subprocess.run(args,check=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE,**kw)
    suffix=uuid.uuid4().hex[:8];cn='tuic-c-'+suffix;sn='tuic-s-'+suffix;names=[];processes=[];logs=[]
    def ns(n,*args):return ['ip','netns','exec',n,*args]
    def launch(args,name):
        f=(out/name).open('w');logs.append(f);env=os.environ.copy();env['QUIC_GO_DISABLE_GSO']='true'
        p=subprocess.Popen(args,stdout=f,stderr=f,env=env);processes.append(p);return p
    def stop(p):
        if p.poll() is None:
            p.terminate()
            try:p.wait(5)
            except subprocess.TimeoutExpired:p.kill();p.wait()
    result={'environment':{'uname':run(['uname','-srmo']).stdout.decode().strip(),'os_release':pathlib.Path('/etc/os-release').read_text(),'version':run([binary,'version']).stdout.decode(),'binary_sha256':hashlib.sha256(pathlib.Path(binary).read_bytes()).hexdigest()},'link':{'rate_mbps_each_direction':a.rate_mbps,'delay_ms_each_direction':a.delay_ms,'loss_percent':0,'netem_limit_packets':3000,'quic_gso_disabled_in_lab':True},'cases':[]}
    try:
        for n in [cn,sn]:run(['ip','netns','add',n]);names.append(n);run(ns(n,'ip','link','set','lo','up'))
        run(ns(cn,'ip','link','add','eth0','type','veth','peer','name','peer0'))
        run(ns(cn,'ip','link','set','peer0','netns',sn));run(ns(sn,'ip','link','set','peer0','name','eth0'))
        for n,addr in [(cn,'192.0.2.1/30'),(sn,'192.0.2.2/30')]:
            run(ns(n,'ip','addr','add',addr,'dev','eth0'));run(ns(n,'ip','link','set','eth0','up'))
            # Both namespaces remain isolated; this route only satisfies the
            # core's default-interface monitor and has no path to the Internet.
            run(ns(n,'ip','route','add','default','dev','eth0'))
            run(ns(n,'tc','qdisc','add','dev','eth0','root','handle','1:','htb','default','10'))
            run(ns(n,'tc','class','add','dev','eth0','parent','1:','classid','1:10','htb','rate',f'{a.rate_mbps}mbit','ceil',f'{a.rate_mbps}mbit','quantum','1514'))
            run(ns(n,'tc','qdisc','add','dev','eth0','parent','1:10','handle','10:','netem','limit','3000','delay',f'{a.delay_ms}ms'))
        with tempfile.TemporaryDirectory(prefix='tuic-repro-key-') as td:
            key=pathlib.Path(td)/'key.pem';cert=out/'certificate.pem'
            run(['openssl','req','-x509','-newkey','rsa:2048','-nodes','-keyout',str(key),'-out',str(cert),'-days','1','-subj','/CN=tuic-repro.test','-addext','subjectAltName=DNS:tuic-repro.test'])
            user=str(uuid.uuid4());password=uuid.uuid4().hex
            server={'log':{'level':'debug','timestamp':True},'inbounds':[{'type':'tuic','tag':'tuic-in','listen':'192.0.2.2','listen_port':14443,'users':[{'uuid':user,'password':password}],'congestion_control':'bbr','initial_packet_size':1200,'disable_path_mtu_discovery':True,'tls':{'enabled':True,'alpn':['h3'],'certificate_path':str(cert),'key_path':str(key)}}],'outbounds':[{'type':'direct','tag':'direct'}]}
            client={'log':{'level':'debug','timestamp':True},'inbounds':[{'type':'mixed','listen':'127.0.0.1','listen_port':18890}],'outbounds':[{'type':'tuic','tag':'tuic-out','server':'192.0.2.2','server_port':14443,'uuid':user,'password':password,'congestion_control':'bbr','udp_relay_mode':'native','initial_packet_size':1200,'disable_path_mtu_discovery':True,'tls':{'enabled':True,'server_name':'tuic-repro.test','alpn':['h3'],'certificate_path':str(cert)}}],'route':{'final':'tuic-out'}}
            for name,cfg in [('server.json',server),('client.json',client)]:
                p=out/name;p.write_text(json.dumps(cfg,indent=2)+'\n');p.chmod(0o600);run([binary,'check','-c',str(p)])
            sp=launch(ns(sn,binary,'run','-c',str(out/'server.json')),'server.log')
            rp=launch(ns(sn,sys.executable,script,'receiver'),'receiver.log');time.sleep(.5)
            if sp.poll() is not None or rp.poll() is not None:raise RuntimeError('receiver/server did not start; inspect logs')
            for rnd in range(1,a.rounds+1):
                variants=['fresh','after-download'] if rnd%2 else ['after-download','fresh']
                for variant in variants:
                    cp=launch(ns(cn,binary,'run','-c',str(out/'client.json')),f'client-r{rnd}-{variant}.log');time.sleep(.5)
                    if cp.poll() is not None:raise RuntimeError('client did not start; inspect logs')
                    phases=[['UP',1,1]]
                    if variant=='after-download':phases += [['UP',4,1],['DOWN',4,1],['UP',16,1],['DOWN',16,1]]
                    phases += [['UP',16,4]]
                    try:
                        data=run(ns(cn,sys.executable,script,'worker',json.dumps(phases)),timeout=240)
                        row={'round':rnd,'variant':variant,'phases':json.loads(data.stdout)};result['cases'].append(row);print(json.dumps(row),flush=True)
                    finally:stop(cp)
            result['qdisc_end']={n:json.loads(run(ns(n,'tc','-s','-j','qdisc','show','dev','eth0')).stdout) for n in [cn,sn]}
    except Exception as e:
        result['error']=type(e).__name__+': '+str(e);raise
    finally:
        for p in reversed(processes):stop(p)
        for f in logs:f.close()
        for n in reversed(names):run(['ip','netns','del',n])
        (out/'results.json').write_text(json.dumps(result,indent=2)+'\n')
        print('Results/logs saved to '+str(out)+'; temporary namespaces and key removed.',flush=True)
if __name__=='__main__':
    if len(sys.argv)>1 and sys.argv[1]=='receiver':
        class S(socketserver.ThreadingTCPServer):
            allow_reuse_address=True;daemon_threads=True
        S(('127.0.0.1',18080),Receiver).serve_forever()
    elif len(sys.argv)>1 and sys.argv[1]=='worker':worker(json.loads(sys.argv[2]))
    else:main()

Complete generated configurations from the reported run

These are the exact files used. All UUID/password values are disposable lab credentials, not redactions or production credentials. Absolute certificate/key paths refer to that run. Run the script to generate fresh files and a fresh certificate/key pair; the recorded private key was intentionally deleted at cleanup and is not attached. The certificate expires after one day, so the old captured files are evidence, not a reusable deployment bundle.

server.json
{
  "log": {
    "level": "debug",
    "timestamp": true
  },
  "inbounds": [
    {
      "type": "tuic",
      "tag": "tuic-in",
      "listen": "192.0.2.2",
      "listen_port": 14443,
      "users": [
        {
          "uuid": "d1f38bf5-4568-40a1-9c0f-0ed78b26267b",
          "password": "c1984724332e4972b4c3a709a7a7a6b3"
        }
      ],
      "congestion_control": "bbr",
      "initial_packet_size": 1200,
      "disable_path_mtu_discovery": true,
      "tls": {
        "enabled": true,
        "alpn": [
          "h3"
        ],
        "certificate_path": "/tmp/tuic-issue-work/run-final/certificate.pem",
        "key_path": "/tmp/tuic-repro-key-_kj6gbye/key.pem"
      }
    }
  ],
  "outbounds": [
    {
      "type": "direct",
      "tag": "direct"
    }
  ]
}
client.json
{
  "log": {
    "level": "debug",
    "timestamp": true
  },
  "inbounds": [
    {
      "type": "mixed",
      "listen": "127.0.0.1",
      "listen_port": 18890
    }
  ],
  "outbounds": [
    {
      "type": "tuic",
      "tag": "tuic-out",
      "server": "192.0.2.2",
      "server_port": 14443,
      "uuid": "d1f38bf5-4568-40a1-9c0f-0ed78b26267b",
      "password": "c1984724332e4972b4c3a709a7a7a6b3",
      "congestion_control": "bbr",
      "udp_relay_mode": "native",
      "initial_packet_size": 1200,
      "disable_path_mtu_discovery": true,
      "tls": {
        "enabled": true,
        "server_name": "tuic-repro.test",
        "alpn": [
          "h3"
        ],
        "certificate_path": "/tmp/tuic-issue-work/run-final/certificate.pem"
      }
    }
  ],
  "route": {
    "final": "tuic-out"
  }
}

Complete measured phases and link counters

results.json
{
  "environment": {
    "uname": "Linux 6.18.35-x64v1-xanmod1 x86_64 GNU/Linux",
    "os_release": "PRETTY_NAME=\"Debian GNU/Linux forky/sid\"\nNAME=\"Debian GNU/Linux\"\nVERSION_CODENAME=forky\nID=debian\nHOME_URL=\"https://www.debian.org/\"\nSUPPORT_URL=\"https://www.debian.org/support\"\nBUG_REPORT_URL=\"https://bugs.debian.org/\"\n",
    "version": "sing-box version 1.14.1\n\nEnvironment: go1.26.8 linux/amd64\nTags: with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale,with_ccm,with_ocm,with_cloudflared,with_naive_outbound,with_usbip,with_openvpn,with_openconnect,badlinkname,tfogo_checklinkname0,with_musl\nRevision: 1ac1a339cb1223e9c70eae14c44411c75033c02d\nCGO: enabled\n",
    "binary_sha256": "f766eb1d1733940b332cc65f38f899c6b5392c3f9e4a35d424da2d469510236e"
  },
  "link": {
    "rate_mbps_each_direction": 100,
    "delay_ms_each_direction": 5,
    "loss_percent": 0,
    "netem_limit_packets": 3000,
    "quic_gso_disabled_in_lab": true
  },
  "cases": [
    {
      "round": 1,
      "variant": "fresh",
      "phases": [
        {
          "direction": "UP",
          "MiB": 1,
          "streams": 1,
          "bytes": 1048576,
          "seconds": 0.160354,
          "Mbps": 52.313
        },
        {
          "direction": "UP",
          "MiB": 16,
          "streams": 4,
          "bytes": 16777216,
          "seconds": 1.540802,
          "Mbps": 87.109
        }
      ]
    },
    {
      "round": 1,
      "variant": "after-download",
      "phases": [
        {
          "direction": "UP",
          "MiB": 1,
          "streams": 1,
          "bytes": 1048576,
          "seconds": 0.153763,
          "Mbps": 54.555
        },
        {
          "direction": "UP",
          "MiB": 4,
          "streams": 1,
          "bytes": 4194304,
          "seconds": 0.464183,
          "Mbps": 72.287
        },
        {
          "direction": "DOWN",
          "MiB": 4,
          "streams": 1,
          "bytes": 4194304,
          "seconds": 0.386492,
          "Mbps": 86.818
        },
        {
          "direction": "UP",
          "MiB": 16,
          "streams": 1,
          "bytes": 16777216,
          "seconds": 2.244508,
          "Mbps": 59.798
        },
        {
          "direction": "DOWN",
          "MiB": 16,
          "streams": 1,
          "bytes": 16777216,
          "seconds": 2.551448,
          "Mbps": 52.605
        },
        {
          "direction": "UP",
          "MiB": 16,
          "streams": 4,
          "bytes": 16777216,
          "seconds": 2.480364,
          "Mbps": 54.112
        }
      ]
    },
    {
      "round": 2,
      "variant": "after-download",
      "phases": [
        {
          "direction": "UP",
          "MiB": 1,
          "streams": 1,
          "bytes": 1048576,
          "seconds": 0.147515,
          "Mbps": 56.866
        },
        {
          "direction": "UP",
          "MiB": 4,
          "streams": 1,
          "bytes": 4194304,
          "seconds": 0.375463,
          "Mbps": 89.368
        },
        {
          "direction": "DOWN",
          "MiB": 4,
          "streams": 1,
          "bytes": 4194304,
          "seconds": 0.863857,
          "Mbps": 38.843
        },
        {
          "direction": "UP",
          "MiB": 16,
          "streams": 1,
          "bytes": 16777216,
          "seconds": 2.475572,
          "Mbps": 54.217
        },
        {
          "direction": "DOWN",
          "MiB": 16,
          "streams": 1,
          "bytes": 16777216,
          "seconds": 2.563763,
          "Mbps": 52.352
        },
        {
          "direction": "UP",
          "MiB": 16,
          "streams": 4,
          "bytes": 16777216,
          "seconds": 2.616405,
          "Mbps": 51.299
        }
      ]
    },
    {
      "round": 2,
      "variant": "fresh",
      "phases": [
        {
          "direction": "UP",
          "MiB": 1,
          "streams": 1,
          "bytes": 1048576,
          "seconds": 0.144368,
          "Mbps": 58.106
        },
        {
          "direction": "UP",
          "MiB": 16,
          "streams": 4,
          "bytes": 16777216,
          "seconds": 1.520194,
          "Mbps": 88.29
        }
      ]
    }
  ],
  "qdisc_end": {
    "tuic-c-6119acab": [
      {
        "kind": "htb",
        "handle": "1:",
        "root": true,
        "refcnt": 3,
        "options": {
          "r2q": 10,
          "default": "0x10",
          "direct_packets_stat": 0,
          "direct_qlen": 1000
        },
        "bytes": 121001801,
        "packets": 107714,
        "drops": 0,
        "overlimits": 93420,
        "requeues": 0,
        "backlog": 0,
        "qlen": 0
      },
      {
        "kind": "netem",
        "handle": "10:",
        "parent": "1:10",
        "options": {
          "limit": 3000,
          "delay": {
            "delay": 0.005,
            "jitter": 0,
            "correlation": 0
          },
          "seed": 4143126003408259445,
          "ecn": false,
          "gap": 0
        },
        "bytes": 121001801,
        "packets": 107714,
        "drops": 0,
        "overlimits": 0,
        "requeues": 0,
        "backlog": 0,
        "qlen": 0
      }
    ],
    "tuic-s-6119acab": [
      {
        "kind": "htb",
        "handle": "1:",
        "root": true,
        "refcnt": 3,
        "options": {
          "r2q": 10,
          "default": "0x10",
          "direct_packets_stat": 0,
          "direct_qlen": 1000
        },
        "bytes": 46319512,
        "packets": 62453,
        "drops": 0,
        "overlimits": 33647,
        "requeues": 0,
        "backlog": 0,
        "qlen": 0
      },
      {
        "kind": "netem",
        "handle": "10:",
        "parent": "1:10",
        "options": {
          "limit": 3000,
          "delay": {
            "delay": 0.005,
            "jitter": 0,
            "correlation": 0
          },
          "seed": 5816516823874100442,
          "ecn": false,
          "gap": 0
        },
        "bytes": 46319512,
        "packets": 62453,
        "drops": 0,
        "overlimits": 0,
        "requeues": 0,
        "backlog": 0,
        "qlen": 0
      }
    ]
  }
}
Logs
===== client-r1-after-download.log (complete) =====
+0200 2026-09-16 14:51:03 INFO network: updated default interface eth0, index 3
+0200 2026-09-16 14:51:03 INFO inbound/mixed[0]: tcp server started at 127.0.0.1:18890
+0200 2026-09-16 14:51:03 INFO sing-box started (0.01s)
+0200 2026-09-16 14:51:04 INFO [410161785 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:56266
+0200 2026-09-16 14:51:04 INFO [410161785 0ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:04 INFO [410161785 0ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:04 DEBUG [410161785 148ms] connection: connection upload finished
+0200 2026-09-16 14:51:04 DEBUG [410161785 148ms] connection: connection download finished
+0200 2026-09-16 14:51:04 INFO [2628935898 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:56276
+0200 2026-09-16 14:51:04 INFO [2628935898 0ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:04 INFO [2628935898 0ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:05 DEBUG [2628935898 460ms] connection: connection download finished
+0200 2026-09-16 14:51:05 INFO [2293419097 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:56292
+0200 2026-09-16 14:51:05 INFO [2293419097 0ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:05 INFO [2293419097 0ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:05 DEBUG [2293419097 385ms] connection: connection download finished
+0200 2026-09-16 14:51:05 INFO [503089721 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:56302
+0200 2026-09-16 14:51:05 INFO [503089721 0ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:05 INFO [503089721 0ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:07 DEBUG [503089721 2.24s] connection: connection download finished
+0200 2026-09-16 14:51:07 INFO [249867452 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:56312
+0200 2026-09-16 14:51:07 INFO [249867452 0ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:07 INFO [249867452 0ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:10 DEBUG [249867452 2.55s] connection: connection upload finished
+0200 2026-09-16 14:51:10 DEBUG [249867452 2.55s] connection: connection download finished
+0200 2026-09-16 14:51:10 INFO [3812430176 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:44758
+0200 2026-09-16 14:51:10 INFO [3812430176 0ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:10 INFO [3812430176 0ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:10 INFO [3311180477 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:44760
+0200 2026-09-16 14:51:10 INFO [2850677357 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:44762
+0200 2026-09-16 14:51:10 INFO [719331414 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:44774
+0200 2026-09-16 14:51:10 INFO [3311180477 2ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:10 INFO [3311180477 2ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:10 INFO [719331414 0ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:10 INFO [719331414 0ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:10 INFO [2850677357 0ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:10 INFO [2850677357 0ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:12 DEBUG [719331414 2.47s] connection: connection download finished
+0200 2026-09-16 14:51:12 DEBUG [3812430176 2.47s] connection: connection download finished
+0200 2026-09-16 14:51:12 DEBUG [2850677357 2.47s] connection: connection download finished
+0200 2026-09-16 14:51:12 DEBUG [3311180477 2.47s] connection: connection download finished

===== client-r1-fresh.log (complete) =====
+0200 2026-09-16 14:51:01 INFO network: updated default interface eth0, index 3
+0200 2026-09-16 14:51:01 INFO inbound/mixed[0]: tcp server started at 127.0.0.1:18890
+0200 2026-09-16 14:51:01 INFO sing-box started (0.01s)
+0200 2026-09-16 14:51:02 INFO [3180606889 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:56208
+0200 2026-09-16 14:51:02 INFO [3180606889 1ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:02 INFO [3180606889 1ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:02 DEBUG [3180606889 155ms] connection: connection download finished
+0200 2026-09-16 14:51:02 INFO [2681109059 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:56220
+0200 2026-09-16 14:51:02 INFO [3196301115 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:56236
+0200 2026-09-16 14:51:02 INFO [3196301115 0ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:02 INFO [3196301115 0ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:02 INFO [2681109059 1ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:02 INFO [2681109059 1ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:02 INFO [2073871270 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:56252
+0200 2026-09-16 14:51:02 INFO [2030912761 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:56262
+0200 2026-09-16 14:51:02 INFO [2073871270 0ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:02 INFO [2073871270 0ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:02 INFO [2030912761 0ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:02 INFO [2030912761 0ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:03 DEBUG [2073871270 1.51s] connection: connection download finished
+0200 2026-09-16 14:51:03 DEBUG [3196301115 1.52s] connection: connection download finished
+0200 2026-09-16 14:51:03 DEBUG [2030912761 1.52s] connection: connection download finished
+0200 2026-09-16 14:51:03 DEBUG [2681109059 1.52s] connection: connection download finished

===== client-r2-after-download.log (complete) =====
+0200 2026-09-16 14:51:12 INFO network: updated default interface eth0, index 3
+0200 2026-09-16 14:51:12 INFO inbound/mixed[0]: tcp server started at 127.0.0.1:18890
+0200 2026-09-16 14:51:12 INFO sing-box started (0.01s)
+0200 2026-09-16 14:51:13 INFO [2432750507 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:44790
+0200 2026-09-16 14:51:13 INFO [2432750507 1ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:13 INFO [2432750507 1ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:13 DEBUG [2432750507 139ms] connection: connection download finished
+0200 2026-09-16 14:51:13 INFO [2761011891 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:44806
+0200 2026-09-16 14:51:13 INFO [2761011891 0ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:13 INFO [2761011891 0ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:13 DEBUG [2761011891 371ms] connection: connection download finished
+0200 2026-09-16 14:51:13 INFO [1480119445 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:44808
+0200 2026-09-16 14:51:13 INFO [1480119445 0ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:13 INFO [1480119445 0ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:14 DEBUG [1480119445 862ms] connection: connection download finished
+0200 2026-09-16 14:51:14 INFO [2954958643 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:44818
+0200 2026-09-16 14:51:14 INFO [2954958643 0ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:14 INFO [2954958643 0ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:17 DEBUG [2954958643 2.47s] connection: connection upload finished
+0200 2026-09-16 14:51:17 DEBUG [2954958643 2.47s] connection: connection download finished
+0200 2026-09-16 14:51:17 INFO [1532331366 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:44832
+0200 2026-09-16 14:51:17 INFO [1532331366 0ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:17 INFO [1532331366 0ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:19 DEBUG [1532331366 2.56s] connection: connection upload finished
+0200 2026-09-16 14:51:19 DEBUG [1532331366 2.56s] connection: connection download finished
+0200 2026-09-16 14:51:19 INFO [3971790415 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:44542
+0200 2026-09-16 14:51:19 INFO [3971790415 1ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:19 INFO [3971790415 1ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:19 INFO [2780807202 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:44554
+0200 2026-09-16 14:51:19 INFO [2972420210 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:44558
+0200 2026-09-16 14:51:19 INFO [1501913962 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:44562
+0200 2026-09-16 14:51:19 INFO [2972420210 0ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:19 INFO [2972420210 0ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:19 INFO [2780807202 1ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:19 INFO [2780807202 1ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:19 INFO [1501913962 0ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:19 INFO [1501913962 0ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:22 DEBUG [2972420210 2.61s] connection: connection download finished
+0200 2026-09-16 14:51:22 DEBUG [1501913962 2.61s] connection: connection download finished
+0200 2026-09-16 14:51:22 DEBUG [3971790415 2.61s] connection: connection download finished
+0200 2026-09-16 14:51:22 DEBUG [2780807202 2.61s] connection: connection download finished

===== client-r2-fresh.log (complete) =====
+0200 2026-09-16 14:51:22 INFO network: updated default interface eth0, index 3
+0200 2026-09-16 14:51:22 INFO inbound/mixed[0]: tcp server started at 127.0.0.1:18890
+0200 2026-09-16 14:51:22 INFO sing-box started (0.01s)
+0200 2026-09-16 14:51:23 INFO [2214238572 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:44574
+0200 2026-09-16 14:51:23 INFO [2214238572 0ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:23 INFO [2214238572 0ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:23 DEBUG [2214238572 137ms] connection: connection download finished
+0200 2026-09-16 14:51:23 INFO [1940072357 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:44590
+0200 2026-09-16 14:51:23 INFO [1940072357 0ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:23 INFO [1940072357 0ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:23 INFO [1197387053 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:44600
+0200 2026-09-16 14:51:23 INFO [1197387053 0ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:23 INFO [1197387053 0ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:23 INFO [1549478941 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:44608
+0200 2026-09-16 14:51:23 INFO [1549478941 0ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:23 INFO [1549478941 0ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:23 INFO [4287144234 0ms] inbound/mixed[0]: inbound connection from 127.0.0.1:44612
+0200 2026-09-16 14:51:23 INFO [4287144234 0ms] inbound/mixed[0]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:23 INFO [4287144234 0ms] outbound/tuic[tuic-out]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:24 DEBUG [4287144234 1.50s] connection: connection download finished
+0200 2026-09-16 14:51:24 DEBUG [1940072357 1.51s] connection: connection download finished
+0200 2026-09-16 14:51:24 DEBUG [1549478941 1.51s] connection: connection download finished
+0200 2026-09-16 14:51:24 DEBUG [1197387053 1.51s] connection: connection upload finished
+0200 2026-09-16 14:51:24 DEBUG [1197387053 1.51s] connection: connection download finished

===== receiver.log (complete) =====
(empty file)

===== server.log (complete) =====
+0200 2026-09-16 14:51:01 INFO network: updated default interface eth0, index 2
+0200 2026-09-16 14:51:01 INFO inbound/tuic[tuic-in]: udp server started at 192.0.2.2:14443
+0200 2026-09-16 14:51:01 INFO sing-box started (0.00s)
+0200 2026-09-16 14:51:02 INFO [1234130820 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:52616
+0200 2026-09-16 14:51:02 INFO [1234130820 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:02 INFO [1234130820 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:02 DEBUG [1234130820 110ms] connection: connection download finished
+0200 2026-09-16 14:51:02 DEBUG [1234130820 110ms] connection: connection upload finished
+0200 2026-09-16 14:51:02 INFO [3846648895 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:52616
+0200 2026-09-16 14:51:02 INFO [3846648895 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:02 INFO [3846648895 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:02 INFO [1110612322 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:52616
+0200 2026-09-16 14:51:02 INFO [1110612322 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:02 INFO [1110612322 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:02 INFO [1382763132 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:52616
+0200 2026-09-16 14:51:02 INFO [1382763132 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:02 INFO [1382763132 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:02 INFO [2868373285 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:52616
+0200 2026-09-16 14:51:02 INFO [2868373285 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:02 INFO [2868373285 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:03 DEBUG [2868373285 1.49s] connection: connection download finished
+0200 2026-09-16 14:51:03 DEBUG [2868373285 1.49s] connection: connection upload finished
+0200 2026-09-16 14:51:03 DEBUG [3846648895 1.50s] connection: connection download finished
+0200 2026-09-16 14:51:03 DEBUG [3846648895 1.50s] connection: connection upload finished
+0200 2026-09-16 14:51:03 DEBUG [1382763132 1.50s] connection: connection download finished
+0200 2026-09-16 14:51:03 DEBUG [1382763132 1.50s] connection: connection upload finished
+0200 2026-09-16 14:51:03 DEBUG [1110612322 1.51s] connection: connection download finished
+0200 2026-09-16 14:51:03 DEBUG [1110612322 1.51s] connection: connection upload finished
+0200 2026-09-16 14:51:03 DEBUG inbound/tuic[tuic-in]: connection failed: receive message: Application error 0x0 (remote)
+0200 2026-09-16 14:51:04 INFO [3541675581 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:44797
+0200 2026-09-16 14:51:04 INFO [3541675581 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:04 INFO [3541675581 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:04 DEBUG [3541675581 115ms] connection: connection download finished
+0200 2026-09-16 14:51:04 DEBUG [3541675581 115ms] connection: connection upload finished
+0200 2026-09-16 14:51:04 INFO [1685449423 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:44797
+0200 2026-09-16 14:51:04 INFO [1685449423 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:04 INFO [1685449423 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:05 DEBUG [1685449423 449ms] connection: connection download finished
+0200 2026-09-16 14:51:05 DEBUG [1685449423 449ms] connection: connection upload finished
+0200 2026-09-16 14:51:05 INFO [1174107626 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:44797
+0200 2026-09-16 14:51:05 INFO [1174107626 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:05 INFO [1174107626 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:05 DEBUG [1174107626 364ms] connection: connection download finished
+0200 2026-09-16 14:51:05 DEBUG [1174107626 364ms] connection: connection upload finished
+0200 2026-09-16 14:51:05 INFO [1216542039 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:44797
+0200 2026-09-16 14:51:05 INFO [1216542039 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:05 INFO [1216542039 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:07 DEBUG [1216542039 2.21s] connection: connection download finished
+0200 2026-09-16 14:51:07 DEBUG [1216542039 2.21s] connection: connection upload finished
+0200 2026-09-16 14:51:07 INFO [726890032 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:44797
+0200 2026-09-16 14:51:07 INFO [726890032 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:07 INFO [726890032 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:10 DEBUG [726890032 2.53s] connection: connection download finished
+0200 2026-09-16 14:51:10 DEBUG [726890032 2.53s] connection: connection upload finished
+0200 2026-09-16 14:51:10 INFO [88508249 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:44797
+0200 2026-09-16 14:51:10 INFO [1443310980 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:44797
+0200 2026-09-16 14:51:10 INFO [1443310980 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:10 INFO [713200345 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:44797
+0200 2026-09-16 14:51:10 INFO [713200345 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:10 INFO [1443310980 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:10 INFO [88508249 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:10 INFO [88508249 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:10 INFO [713200345 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:10 INFO [3685279073 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:44797
+0200 2026-09-16 14:51:10 INFO [3685279073 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:10 INFO [3685279073 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:12 DEBUG [3685279073 2.42s] connection: connection download finished
+0200 2026-09-16 14:51:12 DEBUG [3685279073 2.42s] connection: connection upload finished
+0200 2026-09-16 14:51:12 DEBUG [713200345 2.43s] connection: connection download finished
+0200 2026-09-16 14:51:12 DEBUG [713200345 2.43s] connection: connection upload finished
+0200 2026-09-16 14:51:12 DEBUG [1443310980 2.43s] connection: connection download finished
+0200 2026-09-16 14:51:12 DEBUG [1443310980 2.43s] connection: connection upload finished
+0200 2026-09-16 14:51:12 DEBUG [88508249 2.43s] connection: connection download finished
+0200 2026-09-16 14:51:12 DEBUG [88508249 2.43s] connection: connection upload finished
+0200 2026-09-16 14:51:12 DEBUG inbound/tuic[tuic-in]: connection failed: receive message: Application error 0x0 (remote)
+0200 2026-09-16 14:51:13 INFO [308122011 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:42549
+0200 2026-09-16 14:51:13 INFO [308122011 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:13 INFO [308122011 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:13 DEBUG [308122011 108ms] connection: connection download finished
+0200 2026-09-16 14:51:13 DEBUG [308122011 108ms] connection: connection upload finished
+0200 2026-09-16 14:51:13 INFO [1678896420 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:42549
+0200 2026-09-16 14:51:13 INFO [1678896420 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:13 INFO [1678896420 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:13 DEBUG [1678896420 360ms] connection: connection download finished
+0200 2026-09-16 14:51:13 DEBUG [1678896420 360ms] connection: connection upload finished
+0200 2026-09-16 14:51:13 INFO [2047150029 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:42549
+0200 2026-09-16 14:51:13 INFO [2047150029 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:13 INFO [2047150029 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:14 DEBUG [2047150029 850ms] connection: connection download finished
+0200 2026-09-16 14:51:14 DEBUG [2047150029 850ms] connection: connection upload finished
+0200 2026-09-16 14:51:14 INFO [3734148374 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:42549
+0200 2026-09-16 14:51:14 INFO [3734148374 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:14 INFO [3734148374 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:17 DEBUG [3734148374 2.44s] connection: connection download finished
+0200 2026-09-16 14:51:17 DEBUG [3734148374 2.44s] connection: connection upload finished
+0200 2026-09-16 14:51:17 INFO [3966288695 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:42549
+0200 2026-09-16 14:51:17 INFO [3966288695 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:17 INFO [3966288695 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:19 DEBUG [3966288695 2.55s] connection: connection download finished
+0200 2026-09-16 14:51:19 DEBUG [3966288695 2.55s] connection: connection upload finished
+0200 2026-09-16 14:51:19 INFO [3454516894 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:42549
+0200 2026-09-16 14:51:19 INFO [3454516894 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:19 INFO [3454516894 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:19 INFO [3210212329 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:42549
+0200 2026-09-16 14:51:19 INFO [3210212329 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:19 INFO [3210212329 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:19 INFO [1083976686 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:42549
+0200 2026-09-16 14:51:19 INFO [1083976686 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:19 INFO [1083976686 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:19 INFO [3934168053 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:42549
+0200 2026-09-16 14:51:19 INFO [3934168053 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:19 INFO [3934168053 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:22 DEBUG [3210212329 2.57s] connection: connection download finished
+0200 2026-09-16 14:51:22 DEBUG [3210212329 2.57s] connection: connection upload finished
+0200 2026-09-16 14:51:22 DEBUG [3454516894 2.57s] connection: connection download finished
+0200 2026-09-16 14:51:22 DEBUG [3454516894 2.58s] connection: connection upload finished
+0200 2026-09-16 14:51:22 DEBUG [1083976686 2.58s] connection: connection download finished
+0200 2026-09-16 14:51:22 DEBUG [1083976686 2.58s] connection: connection upload finished
+0200 2026-09-16 14:51:22 DEBUG [3934168053 2.58s] connection: connection download finished
+0200 2026-09-16 14:51:22 DEBUG [3934168053 2.58s] connection: connection upload finished
+0200 2026-09-16 14:51:22 DEBUG inbound/tuic[tuic-in]: connection failed: receive message: Application error 0x0 (remote)
+0200 2026-09-16 14:51:23 INFO [3986318254 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:51461
+0200 2026-09-16 14:51:23 INFO [3986318254 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:23 INFO [3986318254 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:23 DEBUG [3986318254 101ms] connection: connection download finished
+0200 2026-09-16 14:51:23 DEBUG [3986318254 102ms] connection: connection upload finished
+0200 2026-09-16 14:51:23 INFO [1216278846 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:51461
+0200 2026-09-16 14:51:23 INFO [1216278846 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:23 INFO [1216278846 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:23 INFO [1496943150 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:51461
+0200 2026-09-16 14:51:23 INFO [1496943150 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:23 INFO [1496943150 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:23 INFO [1067217407 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:51461
+0200 2026-09-16 14:51:23 INFO [1067217407 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:23 INFO [1067217407 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:23 INFO [3348663687 0ms] inbound/tuic[tuic-in]: inbound connection from 192.0.2.1:51461
+0200 2026-09-16 14:51:23 INFO [3348663687 0ms] inbound/tuic[tuic-in]: inbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:23 INFO [3348663687 0ms] outbound/direct[direct]: outbound connection to 127.0.0.1:18080
+0200 2026-09-16 14:51:24 DEBUG [3348663687 1.49s] connection: connection download finished
+0200 2026-09-16 14:51:24 DEBUG [3348663687 1.49s] connection: connection upload finished
+0200 2026-09-16 14:51:24 DEBUG [1067217407 1.50s] connection: connection download finished
+0200 2026-09-16 14:51:24 DEBUG [1067217407 1.50s] connection: connection upload finished
+0200 2026-09-16 14:51:24 DEBUG [1216278846 1.50s] connection: connection download finished
+0200 2026-09-16 14:51:24 DEBUG [1216278846 1.50s] connection: connection upload finished
+0200 2026-09-16 14:51:24 DEBUG [1496943150 1.50s] connection: connection download finished
+0200 2026-09-16 14:51:24 DEBUG [1496943150 1.50s] connection: connection upload finished
+0200 2026-09-16 14:51:24 DEBUG inbound/tuic[tuic-in]: connection failed: receive message: Application error 0x0 (remote)
+0200 2026-09-16 14:51:24 DEBUG inbound/tuic[tuic-in]: listener closed: context canceled
Supporter
Integrity requirements
  • I confirm that I have read the documentation, understand the meaning of all the configuration items I wrote, and did not pile up seemingly useful options or default values.
  • I confirm that I have provided the server and client configuration files and process that can be reproduced locally, instead of a complicated client configuration file that has been stripped of sensitive data.
  • I confirm that I have provided the simplest configuration that can be used to reproduce the error I reported, instead of depending on remote servers, TUN, graphical interface clients, or other closed-source software.
  • I confirm that I have provided the complete configuration files and logs, rather than just providing parts I think are useful out of confidence in my own intelligence.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Run repro.py with the original sing-box binary and compare the fresh and after-download results in results.json. Then read sing-quic/tuic/congestion.go and quic-go's internal/ackhandler/sent_packet_handler.go, focusing on the mentioned packerEmptyTime and OnAppLimited areas. Done means the cause is confirmed and the reproduction no longer shows the reported upload regression.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, linux, python
Domain
cli, networking, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.