break: replace muxed workers with 1:1 tunnels
Worker frames are now FrameType + payload; there is no stream id. Each player gets its own worker conn. maxTunnels (default 256) caps concurrent tunnels. The old maxConn pool size is ignored so existing configs do not silently admit only a handful of players. Resume, per-direction windows, the control session, and the DATA-only shaper stay. A dropped worker still hangs that one player and reattaches over a fresh conn. Add a hub-side per-IP limiter for player intents only (default 8/s, burst 16, 64 concurrent). Unmatched hostnames consume a token; Intent 17 is never counted. 0 disables each knob.
This commit is contained in:
@@ -27,17 +27,15 @@ func echoRounds(t *testing.T, hubAddr string, rounds, size int) {
|
||||
}
|
||||
|
||||
// TestSlowPlayerDoesNotStallOthers: a player that stops reading while megabytes
|
||||
// are echoed back to it must not stall another stream on the same worker
|
||||
// connection (maxConn=1 forces sharing). Before per-stream flow control, the
|
||||
// hub paused the whole worker socket once that player's write queue filled,
|
||||
// freezing every other stream's downstream data.
|
||||
// are echoed back to it must not stall another player. Flow control and the
|
||||
// 1:1 worker model keep a jammed tunnel from taking anyone else with it.
|
||||
func TestSlowPlayerDoesNotStallOthers(t *testing.T) {
|
||||
const psk = "e2e-slowplayer"
|
||||
port := freePort(t)
|
||||
hubAddr := fmt.Sprintf("127.0.0.1:%d", port)
|
||||
startHub(t, port, psk)
|
||||
dest := newMockDest(t, modeEcho)
|
||||
startClient(t, hubAddr, psk, 1, []client.Mapping{
|
||||
startClient(t, hubAddr, psk, 2, []client.Mapping{
|
||||
{Pattern: "mc.local", Destination: dest.addr},
|
||||
})
|
||||
|
||||
@@ -52,7 +50,7 @@ func TestSlowPlayerDoesNotStallOthers(t *testing.T) {
|
||||
// Let the slow stream jam: its flow-control window fills and stays full.
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
// The fast player shares the single worker conn and must still round-trip.
|
||||
// The fast player has its own worker conn and must still round-trip.
|
||||
echoRounds(t, hubAddr, 10, 8*1024)
|
||||
}
|
||||
|
||||
@@ -67,7 +65,7 @@ func TestSlowDestinationDoesNotStallOthers(t *testing.T) {
|
||||
startHub(t, port, psk)
|
||||
dest := newMockDest(t, modeEcho)
|
||||
hole := newMockDest(t, modeBlackhole)
|
||||
startClient(t, hubAddr, psk, 1, []client.Mapping{
|
||||
startClient(t, hubAddr, psk, 2, []client.Mapping{
|
||||
{Pattern: "mc.local", Destination: dest.addr},
|
||||
{Pattern: "hole.local", Destination: hole.addr},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user