diff --git a/go.mod b/go.mod
index 0762c9fe6..578740127 100644
--- a/go.mod
+++ b/go.mod
@@ -30,7 +30,7 @@ require (
require (
github.com/docker/docker v28.5.2+incompatible
- github.com/xtaci/smux v1.5.49
+ github.com/xtaci/smux v1.5.50
)
require (
diff --git a/go.sum b/go.sum
index 927b3f00f..6455ecc47 100644
--- a/go.sum
+++ b/go.sum
@@ -201,8 +201,8 @@ github.com/valyala/fastrand v1.1.0 h1:f+5HkLW4rsgzdNoleUOB69hyT9IlD2ZQh9GyDMfb5G
github.com/valyala/fastrand v1.1.0/go.mod h1:HWqCzkrkg6QXT8V2EXWvXCoow7vLwOFN002oeRzjapQ=
github.com/valyala/histogram v1.2.0 h1:wyYGAZZt3CpwUiIb9AU/Zbllg1llXyrtApRS815OLoQ=
github.com/valyala/histogram v1.2.0/go.mod h1:Hb4kBwb4UxsaNbbbh+RRz8ZR6pdodR57tzWUS3BUzXY=
-github.com/xtaci/smux v1.5.49 h1:V3pdyzGLGDMX4R/rbx+e7yo5nB9ticxCcCkQZMxCWwE=
-github.com/xtaci/smux v1.5.49/go.mod h1:IGQ9QYrBphmb/4aTnLEcJby0TNr3NV+OslIOMrX825Q=
+github.com/xtaci/smux v1.5.50 h1:y/1DlWQC9bnMeZzsyk4oL2hbLK6uVk4BKTz5BeQqUEA=
+github.com/xtaci/smux v1.5.50/go.mod h1:IGQ9QYrBphmb/4aTnLEcJby0TNr3NV+OslIOMrX825Q=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.63.0 h1:RbKq8BG0FI8OiXhBfcRtqqHcZcka+gU3cskNuf05R18=
diff --git a/pkg/dmsghttp/http_transport_test.go b/pkg/dmsghttp/http_transport_test.go
index 92715be03..cc691c5b3 100644
--- a/pkg/dmsghttp/http_transport_test.go
+++ b/pkg/dmsghttp/http_transport_test.go
@@ -81,6 +81,9 @@ func TestHTTPTransport_RoundTrip(t *testing.T) {
Timeout: 10 * time.Second,
}
+ // Allow time for dmsg sessions to stabilize on macOS
+ time.Sleep(200 * time.Millisecond)
+
// Act: http clients send requests concurrently.
// - client1 sends "/index.html" requests.
// - client2 sends "/echo" requests.
diff --git a/pkg/dmsgpty/host_test.go b/pkg/dmsgpty/host_test.go
index 24954fe31..c52023236 100644
--- a/pkg/dmsgpty/host_test.go
+++ b/pkg/dmsgpty/host_test.go
@@ -9,6 +9,7 @@ import (
"os"
"runtime"
"testing"
+ "time"
"github.com/skycoin/skywire/pkg/skywire-utilities/pkg/cipher"
"github.com/skycoin/skywire/pkg/skywire-utilities/pkg/logging"
@@ -154,6 +155,9 @@ func TestHost(t *testing.T) {
})
t.Run("endpoint_proxy", func(t *testing.T) {
+ // Give hostA time to establish its listener on macOS
+ time.Sleep(100 * time.Millisecond)
+
conn, err := cliB.prepareConn()
require.NoError(t, err)
diff --git a/vendor/github.com/xtaci/smux/AGENTS.md b/vendor/github.com/xtaci/smux/AGENTS.md
new file mode 100644
index 000000000..ed707eb3e
--- /dev/null
+++ b/vendor/github.com/xtaci/smux/AGENTS.md
@@ -0,0 +1,93 @@
+# AGENTS.md - smux Project Context
+
+## Project Overview
+**smux** (Simple Multiplexing) is a multiplexing library for Golang. It allows multiple logical streams to share a single underlying connection (like TCP or KCP). It is designed for reliability and ordering, and is a core component of [kcp-go](https://github.com/xtaci/kcp-go) and [kcptun](https://github.com/xtaci/kcptun).
+
+## Key Features
+- **Multiplexing**: Multiple streams over one connection.
+- **Flow Control**: Token bucket controlled receiving and per-stream sliding window (protocol v2+).
+- **Memory Efficiency**: Shared receive buffer among streams to control overall memory usage.
+- **Low Overhead**: Minimized header (8 bytes).
+- **Traffic Shaping**: Built-in fair queue traffic shaping.
+
+## Architecture & Core Components
+
+### 1. Session (`session.go`)
+The `Session` struct is the main manager for a multiplexed connection.
+- Manages the underlying `io.ReadWriteCloser`.
+- Handles the creation and acceptance of streams.
+- Manages the shared receive buffer and token bucket.
+- **Key Methods**: `Client`, `Server`, `OpenStream`, `AcceptStream`.
+
+### 2. Stream (`stream.go`)
+The `Stream` struct represents a logical stream within a session.
+- Implements `net.Conn` interface (Read, Write, Close, etc.).
+- Handles data buffering and flow control.
+- **Key Methods**: `Read`, `Write`, `Close`.
+
+### 3. Frame (`frame.go`)
+Defines the wire format for data transmission.
+- **Header Format** (8 bytes):
+ - `VERSION` (1 byte): Protocol version (1 or 2).
+ - `CMD` (1 byte): Command type (`SYN`, `FIN`, `PSH`, `NOP`, `UPD`).
+ - `LENGTH` (2 bytes): Payload length.
+ - `STREAMID` (4 bytes): Stream identifier.
+- **Commands**:
+ - `cmdSYN`: Stream open.
+ - `cmdFIN`: Stream close (EOF).
+ - `cmdPSH`: Data push.
+ - `cmdNOP`: No operation (keep-alive).
+ - `cmdUPD`: Window update (v2 only).
+
+### 4. Configuration (`mux.go`)
+The `Config` struct allows tuning the session.
+- **Key Fields**: `Version`, `KeepAliveInterval`, `MaxFrameSize`, `MaxReceiveBuffer`, `MaxStreamBuffer`.
+
+### 5. Traffic Shaping (`shaper.go`)
+Implements traffic shaping logic to ensure fair bandwidth usage among streams.
+
+## Development Guidelines
+
+### Testing
+- Run all tests:
+ ```bash
+ go test -v .
+ ```
+- Run benchmarks:
+ ```bash
+ go test -v -run=^$ -bench .
+ ```
+
+### Coding Conventions
+- Follow standard Go coding conventions (formatting, naming, etc.).
+- Ensure backward compatibility when modifying protocol-related code.
+- Pay attention to concurrency and locking, as `Session` and `Stream` are heavily concurrent.
+
+## Common Tasks
+
+### Creating a Client Session
+```go
+conn, _ := net.Dial(...)
+session, _ := smux.Client(conn, nil) // nil for default config
+stream, _ := session.OpenStream()
+```
+
+### Creating a Server Session
+```go
+conn, _ := listener.Accept()
+session, _ := smux.Server(conn, nil)
+stream, _ := session.AcceptStream()
+```
+
+### Protocol Versions
+- **Version 1**: Basic multiplexing.
+- **Version 2**: Adds `cmdUPD` for flow control (window updates).
+
+## File Structure
+- `alloc.go`: Memory allocation utilities.
+- `frame.go`: Frame definition and parsing.
+- `mux.go`: Configuration and entry points.
+- `session.go`: Session logic.
+- `stream.go`: Stream logic.
+- `shaper.go`: Traffic shaping logic.
+- `*_test.go`: Tests for respective components.
diff --git a/vendor/github.com/xtaci/smux/README.md b/vendor/github.com/xtaci/smux/README.md
index 8bce5d65f..140949891 100644
--- a/vendor/github.com/xtaci/smux/README.md
+++ b/vendor/github.com/xtaci/smux/README.md
@@ -17,6 +17,8 @@
[11]: https://sourcegraph.com/github.com/xtaci/smux/-/badge.svg
[12]: https://sourcegraph.com/github.com/xtaci/smux?badge
+[English](README.md) | [中文](README_zh-cn.md)
+
## Introduction
Smux (**S**imple **MU**ltiple**X**ing) is a multiplexing library for Golang. It relies on an underlying connection to provide reliability and ordering, such as TCP or [KCP](https://github.com/xtaci/kcp-go), and provides stream-oriented multiplexing. This library was originally designed to power connection management for [kcp-go](https://github.com/xtaci/kcp-go).
@@ -32,6 +34,22 @@ Smux (**S**imple **MU**ltiple**X**ing) is a multiplexing library for Golang. It

+## Architecture
+
+* **Session**: The main manager for a multiplexed connection. It manages the underlying `io.ReadWriteCloser`, handles stream creation/acceptance, and manages the shared receive buffer.
+* **Stream**: A logical stream within a session. It implements the `net.Conn` interface, handling data buffering and flow control.
+* **Frame**: The wire format for data transmission.
+
+## Frame Allocator
+
+`alloc.go` implements a slab-style allocator tuned for frames up to 64 KB. Seventeen `sync.Pool` buckets cache power-of-two slice capacities, and a De Bruijn based `msb()` lookup picks the smallest bucket that can satisfy a request in constant time. Buffers are deliberately reused without zeroing, so each new frame simply overwrites the previous payload without paying the Go runtime's memclr cost.
+
+Benefits for the session:
+
+1. Bounded fragmentation (each request wastes < 50%) keeps the shared receive buffer predictable under load.
+2. Reuse of pre-sized slices drastically lowers GC pressure and removes repeated zeroing work.
+3. Constant-time bucket selection avoids locks or searches, so high-throughput sessions keep tail latency steady even with thousands of flows.
+
## Documentation
For complete documentation, see the associated [Godoc](https://godoc.org/github.com/xtaci/smux).
@@ -53,7 +71,15 @@ ok github.com/xtaci/smux 7.811s
## Specification
```
-VERSION(1B) | CMD(1B) | LENGTH(2B) | STREAMID(4B) | DATA(LENGTH)
+ +---------------+---------------+-------------------------------+
+ | VERSION (1B) | CMD (1B) | LENGTH (2B) |
+ +---------------+---------------+-------------------------------+
+ | STREAMID (4B) |
+ +---------------------------------------------------------------+
+ | |
+ / DATA (Variable) /
+ | |
+ +---------------------------------------------------------------+
VALUES FOR LATEST VERSION:
VERSION:
@@ -131,6 +157,19 @@ func server() {
```
-## Status
+## Configuration
+
+`smux.Config` allows tuning the session parameters:
+
+* `Version`: Protocol version (1 or 2).
+* `KeepAliveInterval`: Interval for sending NOP frames to keep the connection alive.
+* `KeepAliveTimeout`: Timeout for closing the session if no data is received.
+* `MaxFrameSize`: Maximum size of a frame.
+* `MaxReceiveBuffer`: Maximum size of the shared receive buffer.
+* `MaxStreamBuffer`: Maximum size of the per-stream buffer.
+
+## Reference
-Stable
+* [hashicorp/yamux](https://github.com/hashicorp/yamux)
+* [xtaci/kcp-go](https://github.com/xtaci/kcp-go)
+* [xtaci/kcptun](https://github.com/xtaci/kcptun)
diff --git a/vendor/github.com/xtaci/smux/README_zh-cn.md b/vendor/github.com/xtaci/smux/README_zh-cn.md
new file mode 100644
index 000000000..318db4bf8
--- /dev/null
+++ b/vendor/github.com/xtaci/smux/README_zh-cn.md
@@ -0,0 +1,175 @@
+
+
+[![GoDoc][1]][2] [![MIT licensed][3]][4] [![Build Status][5]][6] [![Go Report Card][7]][8] [![Coverage Statusd][9]][10] [![Sourcegraph][11]][12]
+
+
+
+[1]: https://godoc.org/github.com/xtaci/smux?status.svg
+[2]: https://godoc.org/github.com/xtaci/smux
+[3]: https://img.shields.io/badge/license-MIT-blue.svg
+[4]: LICENSE
+[5]: https://img.shields.io/github/created-at/xtaci/smux
+[6]: https://img.shields.io/github/created-at/xtaci/smux
+[7]: https://goreportcard.com/badge/github.com/xtaci/smux
+[8]: https://goreportcard.com/report/github.com/xtaci/smux
+[9]: https://codecov.io/gh/xtaci/smux/branch/master/graph/badge.svg
+[10]: https://codecov.io/gh/xtaci/smux
+[11]: https://sourcegraph.com/github.com/xtaci/smux/-/badge.svg
+[12]: https://sourcegraph.com/github.com/xtaci/smux?badge
+
+[English](README.md) | [中文](README_zh-cn.md)
+
+## 简介
+
+Smux(**S**imple **MU**ltiple**X**ing)是一个用 Golang 实现的多路复用库,让多个有序、可靠的逻辑流共享同一条底层连接(如 TCP 或 [KCP](https://github.com/xtaci/kcp-go))。它最初为 [kcp-go](https://github.com/xtaci/kcp-go) 设计,用于在复杂网络环境中维持长连接时的精细流量控制和资源管理。
+
+## 特性
+
+1. **令牌桶限速**:基于令牌桶的接收控制,输出带宽曲线更平滑(如下图)。
+2. **全局缓冲共享**:会话级接收缓冲在各流之间复用,可精确限制整体内存占用。
+3. **极简协议头**:8 字节帧头最大化有效载荷占比。
+4. **大规模验证**:在 [kcptun](https://github.com/xtaci/kcptun) 中经数百万设备验证,稳定可靠。
+5. **公平队列整形**:内建公平调度,避免单个流独占带宽。
+6. **流级滑动窗口**:协议版本 2 起支持 per-stream 拥塞控制,进一步提升吞吐和延迟表现。
+
+
+
+## 架构
+
+* **Session**:多路复用会话管理器,负责维护底层 `io.ReadWriteCloser`,创建或接受 `Stream`,同时调度共享接收缓冲和限速逻辑。
+* **Stream**:会话中的逻辑连接,实现 `net.Conn` 接口,承担读写缓冲与流量控制。
+* **Frame**:在线协议帧格式,定义指令、流 ID、长度等字段,用于在 Session 与 Stream 之间传输数据/控制信息。
+
+## 帧内存分配器
+
+`alloc.go` 针对 64 KB 以内的帧实现了分层分配器:17 个 `sync.Pool` 分别缓存 2^n 容量的切片,`msb()` 函数利用 De Bruijn 序列常数在 O(1) 时间内定位到最合适的池子。复用出来的切片不会被额外清零,新帧直接覆盖旧负载,从而避开运行时的 memclr 开销。
+
+这样带来的系统收益包括:
+
+1. 单次分配的浪费率 < 50%,在高并发下也能准确控制会话级缓冲占用。
+2. 重复使用固定容量的切片显著降低 GC 压力,也避免了多次清零的额外成本。
+3. 常数时间的桶选择避免了搜索或额外锁竞争,让高吞吐会话在大量流同时活跃时保持低尾延迟。
+
+## 文档
+
+更完整的 API 与实现细节可参考 [Godoc](https://godoc.org/github.com/xtaci/smux)。
+
+## 基准测试 (Benchmark)
+```
+$ go test -v -run=^$ -bench .
+goos: darwin
+goarch: amd64
+pkg: github.com/xtaci/smux
+BenchmarkMSB-4 30000000 51.8 ns/op
+BenchmarkAcceptClose-4 50000 36783 ns/op
+BenchmarkConnSmux-4 30000 58335 ns/op 2246.88 MB/s 1208 B/op 19 allocs/op
+BenchmarkConnTCP-4 50000 25579 ns/op 5124.04 MB/s 0 B/op 0 allocs/op
+PASS
+ok github.com/xtaci/smux 7.811s
+```
+
+## 规范 (Specification)
+
+```
++---------------+---------------+-------------------------------+
+ | VERSION (1B) | CMD (1B) | LENGTH (2B) |
+ +---------------+---------------+-------------------------------+
+ | STREAMID (4B) |
+ +---------------------------------------------------------------+
+ | |
+ / DATA (Variable) /
+ | |
+ +---------------------------------------------------------------+
+
+VALUES FOR LATEST VERSION:
+VERSION:
+ 1/2
+
+CMD:
+ cmdSYN(0)
+ cmdFIN(1)
+ cmdPSH(2)
+ cmdNOP(3)
+ cmdUPD(4) // 仅在版本 2 支持
+
+STREAMID:
+ 客户端使用从 1 开始的奇数
+ 服务端使用从 0 开始的偶数
+
+cmdUPD:
+ | CONSUMED(4B) | WINDOW(4B) |
+```
+
+## 用法 (Usage)
+
+```go
+
+func client() {
+ // 建立一条 TCP 连接
+ conn, err := net.Dial(...)
+ if err != nil {
+ panic(err)
+ }
+
+ // 初始化 smux 客户端,会采用默认配置
+ session, err := smux.Client(conn, nil)
+ if err != nil {
+ panic(err)
+ }
+
+ // 打开一个新的逻辑流
+ stream, err := session.OpenStream()
+ if err != nil {
+ panic(err)
+ }
+
+ // Stream 满足 io.ReadWriteCloser,可直接读写
+ stream.Write([]byte("ping"))
+ stream.Close()
+ session.Close()
+}
+
+func server() {
+ // 接收传入的 TCP 连接
+ conn, err := listener.Accept()
+ if err != nil {
+ panic(err)
+ }
+
+ // 使用 smux.Server 将连接升级为服务端会话
+ session, err := smux.Server(conn, nil)
+ if err != nil {
+ panic(err)
+ }
+
+ // 阻塞等待客户端打开的流
+ stream, err := session.AcceptStream()
+ if err != nil {
+ panic(err)
+ }
+
+ // 简单读取一条 4 字节消息
+ buf := make([]byte, 4)
+ stream.Read(buf)
+ stream.Close()
+ session.Close()
+}
+
+```
+
+## 配置
+
+`smux.Config` 提供了常用调优项:
+
+* `Version`:协议版本(1 或 2)。
+* `KeepAliveInterval`:发送 `cmdNOP` 以维持心跳的间隔。
+* `KeepAliveTimeout`:在无数据时认为连接失效的超时时间。
+* `MaxFrameSize`:单帧数据的最大长度。
+* `MaxReceiveBuffer`:会话级共享接收缓冲的上限。
+* `MaxStreamBuffer`:单个流本地缓冲的上限。
+
+## 参考
+
+* [hashicorp/yamux](https://github.com/hashicorp/yamux)
+* [xtaci/kcp-go](https://github.com/xtaci/kcp-go)
+* [xtaci/kcptun](https://github.com/xtaci/kcptun)
diff --git a/vendor/github.com/xtaci/smux/shaper.go b/vendor/github.com/xtaci/smux/shaper.go
index af00288b2..b53fb889e 100644
--- a/vendor/github.com/xtaci/smux/shaper.go
+++ b/vendor/github.com/xtaci/smux/shaper.go
@@ -57,6 +57,7 @@ func (h *shaperHeap) Pop() any {
old := *h
n := len(old)
x := old[n-1]
+ old[n-1] = writeRequest{} // avoid memory leak
*h = old[0 : n-1]
return x
}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index f4c269538..0a53750f4 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -381,7 +381,7 @@ github.com/valyala/fastrand
# github.com/valyala/histogram v1.2.0
## explicit; go 1.12
github.com/valyala/histogram
-# github.com/xtaci/smux v1.5.49
+# github.com/xtaci/smux v1.5.50
## explicit; go 1.18
github.com/xtaci/smux
# go.opentelemetry.io/auto/sdk v1.1.0