xtaci/kcptun

Client panics when using mtu > 1472

Opened this issue · 0 comments

I wrote a test to demonstrate the bug:

client/main_test.go

package main

import (
	"fmt"
	"math/rand"
	"net"
	"os"
	"testing"
	"time"
)

func Test_Main(t *testing.T) {
	port := chooseRandomUnusedPort()

	os.Args = []string{
		"test",
		"-localaddr", fmt.Sprintf(":%d", port),
		"-remoteaddr", "localhost:29900", // arbitrary address, no need to have a running server here
		"-crypt", "none",
		"-mtu", "1500",
		"-nocomp", "true",
	}

	go main()
	time.Sleep(time.Second)

	conn, err := net.Dial("tcp", fmt.Sprintf("localhost:%d", port))
	if err != nil {
		t.Fatal(err)
	}
	defer conn.Close()

	if _, err := conn.Write(make([]byte, 1500)); err != nil {
		t.Fatal(err)
	}

	time.Sleep(time.Second)
}

func chooseRandomUnusedPort() (port int) {
	for i := 0; i < 10; i++ {
		port = 40000 + int(rand.Int31n(10000))
		if listener, err := net.Listen("tcp", fmt.Sprintf(":%d", port)); err == nil {
			_ = listener.Close()
			break
		}
	}
	return port
}

$ go test github.com/xtaci/kcptun/client
2024/11/01 22:11:17 main.go:304: version: SELFBUILD
2024/11/01 22:11:17 main.go:322: smux version: 1
2024/11/01 22:11:17 main.go:323: listening on: [::]:45737
2024/11/01 22:11:17 main.go:324: encryption: none
2024/11/01 22:11:17 main.go:325: QPP: false
2024/11/01 22:11:17 main.go:326: QPP Count: 61
2024/11/01 22:11:17 main.go:327: nodelay parameters: 0 30 2 1
2024/11/01 22:11:17 main.go:328: remote address: localhost:29900
2024/11/01 22:11:17 main.go:329: sndwnd: 128 rcvwnd: 512
2024/11/01 22:11:17 main.go:330: compression: false
2024/11/01 22:11:17 main.go:331: mtu: 1500
2024/11/01 22:11:17 main.go:332: datashard: 10 parityshard: 3
2024/11/01 22:11:17 main.go:333: acknodelay: false
2024/11/01 22:11:17 main.go:334: dscp: 0
2024/11/01 22:11:17 main.go:335: sockbuf: 4194304
2024/11/01 22:11:17 main.go:336: smuxbuf: 4194304
2024/11/01 22:11:17 main.go:337: streambuf: 2097152
2024/11/01 22:11:17 main.go:338: keepalive: 10
2024/11/01 22:11:17 main.go:339: conn: 1
2024/11/01 22:11:17 main.go:340: autoexpire: 0
2024/11/01 22:11:17 main.go:341: scavengettl: 600
2024/11/01 22:11:17 main.go:342: snmplog: 
2024/11/01 22:11:17 main.go:343: snmpperiod: 60
2024/11/01 22:11:17 main.go:344: quiet: false
2024/11/01 22:11:17 main.go:345: tcp: false
2024/11/01 22:11:17 main.go:346: pprof: false
2024/11/01 22:11:17 main.go:376: initiating key derivation
2024/11/01 22:11:17 main.go:378: key derivation done
2024/11/01 22:11:18 main.go:433: smux version: 1 on connection: 0.0.0.0:41452 -> 127.0.0.1:29900
2024/11/01 22:11:18 main.go:522: stream opened in: 127.0.0.1:42044 out: 127.0.0.1:29900(3)
panic: runtime error: slice bounds out of range [:1528] with capacity 1500

goroutine 33 [running]:
github.com/xtaci/kcp-go/v5.newUDPSession.func1({0xc000394600, 0x5dc, 0x4?}, 0x5dc)
	/xtaci/kcptun/vendor/github.com/xtaci/kcp-go/v5/sess.go:218 +0x1ae
github.com/xtaci/kcp-go/v5.(*KCP).flush.func1(0xc000055600?)
	/xtaci/kcptun/vendor/github.com/xtaci/kcp-go/v5/kcp.go:695 +0x5d
github.com/xtaci/kcp-go/v5.(*KCP).flush(0xc0000ee7e0, 0x0)
	/xtaci/kcptun/vendor/github.com/xtaci/kcp-go/v5/kcp.go:844 +0xaa8
github.com/xtaci/kcp-go/v5.(*UDPSession).WriteBuffers(0xc000002180, {0xc00011a030, 0x2, 0x0?})
	/xtaci/kcptun/vendor/github.com/xtaci/kcp-go/v5/sess.go:378 +0x8a5
github.com/xtaci/smux.(*Session).sendLoop(0xc0000fe500)
	/xtaci/kcptun/vendor/github.com/xtaci/smux/session.go:548 +0x2db
created by github.com/xtaci/smux.newSession in goroutine 26
	/xtaci/kcptun/vendor/github.com/xtaci/smux/session.go:151 +0x365
FAIL	github.com/xtaci/kcptun/client	1.014s
FAIL

Test was run on v20241031 tag.