{"id":31286927,"url":"https://github.com/pedramktb/go-netx","last_synced_at":"2026-02-22T21:14:22.779Z","repository":{"id":315750783,"uuid":"1060704721","full_name":"pedramktb/go-netx","owner":"pedramktb","description":"netx is a Go library that aims to extend the net standard library.","archived":false,"fork":false,"pushed_at":"2025-09-20T12:36:21.000Z","size":28,"stargazers_count":1,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-20T14:41:24.434Z","etag":null,"topics":["go","go-library","go-net","golang","golang-library","hot-routing","net","net-wrapper","server","tunnel"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pedramktb.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-20T12:26:59.000Z","updated_at":"2025-09-20T13:01:52.000Z","dependencies_parsed_at":"2025-09-20T14:41:26.910Z","dependency_job_id":"14cfc720-1864-411a-b324-0f798a60d0c7","html_url":"https://github.com/pedramktb/go-netx","commit_stats":null,"previous_names":["pedramktb/go-netx"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/pedramktb/go-netx","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedramktb%2Fgo-netx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedramktb%2Fgo-netx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedramktb%2Fgo-netx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedramktb%2Fgo-netx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pedramktb","download_url":"https://codeload.github.com/pedramktb/go-netx/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedramktb%2Fgo-netx/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276737507,"owners_count":25695699,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-24T02:00:09.776Z","response_time":97,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","go-library","go-net","golang","golang-library","hot-routing","net","net-wrapper","server","tunnel"],"created_at":"2025-09-24T10:57:59.599Z","updated_at":"2026-02-22T21:14:22.763Z","avatar_url":"https://github.com/pedramktb.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# \u003cimg src=\"./netx.svg\" alt=\"netX\" /\u003e\n\nnetX or network extended is a collection of small, focused extensions to Go's \"net\" standard library.\n\nIt provides composable building blocks that integrate well with standard `net.Conn` and `net.Listener` types without introducing heavy abstractions,\nonly introducing new interfaces and types where necessary to expose real functionality.\n\n## Contents\n- [Highlights](#highlights)\n- [Installation](#installation)\n- [Library guide](#library-guide)\n\t- [Buffered connections](#buffered-connections)\n\t- [Framed connections](#framed-connections)\n\t- [Mux and MuxClient](#mux-and-muxclient)\n\t- [Demux and DemuxClient](#demux-and-demuxclient)\n\t- [Poll connections](#poll-connections)\n\t- [Tagged connections](#tagged-connections)\n\t- [Runtime-routable server](#runtime-routable-server)\n\t- [Tunneling](#tunneling)\n\t- [Driver and wrapper system](#driver-and-wrapper-system)\n\t- [Programmatic URIs](#programmatic-uris)\n\t- [Logging](#logging)\n\t- [Design notes and guarantees](#design-notes-and-guarantees)\n- [CLI](#cli)\n\t- [Quick start](#quick-start)\n\t- [Install and upgrade](#install-and-upgrade)\n\t- [Build from source](#build-from-source)\n\t- [Example commands](#example-commands)\n\t- [Chain syntax reference](#chain-syntax-reference)\n\n## Highlights\n\n- **Buffered connections:** `NewBufConn` adds buffered read/write with explicit `Flush`.\n- **Framed connections:** `NewFramedConn` adds a simple 4-byte length-prefixed frame protocol.\n- **Mux / MuxClient:** `NewMux` wraps a `net.Listener` as a `net.Conn`; `NewMuxClient` wraps a `Dialer` as a `net.Conn` — both transparently accept/redial on EOF.\n- **Demux / DemuxClient:** session multiplexer over a single `net.Conn` using fixed-length ID prefixes. `NewDemux` returns a `net.Listener` of virtual sessions; `NewDemuxClient` returns a `Dialer`.\n- **Poll connections:** `NewPollConn` turns a request-response `net.Conn` into a persistent bidirectional stream via periodic polling.\n- **Tagged connections:** `TaggedConn` interface extends `net.Conn` with opaque tags that carry context (e.g., DNS query) from read path to write path. `TaggedPipe` provides an in-memory pair.\n- **Connection router/server:** `Server[ID]` accepts on a listener and routes new conns to handlers you register at runtime.\n- **Tunneling:** `Tun` and `TunMaster[ID]` wire two connections together for bidirectional relay (useful to bridge UDP over a framed TCP stream, add TLS, etc.).\n- **Driver/wrapper system:** pluggable `Driver` registry and typed `Wrapper` pipeline for composing connection transformations. Supports type-safe chains across `net.Listener`, `Dialer`, `net.Conn`, and `TaggedConn`.\n- **DNS tunneling:** `proto/dnst` encodes data into DNS TXT queries/responses; combine with `Mux`, `TaggedDemux`, `DemuxClient`, and `PollConn` for a full tunnel.\n- **ICMP support:** `icmp` transport for listener and dialer, tunneling traffic over ICMP Echo Request/Reply.\n- **Chainable tunnel CLI and URI builder:** compose transports and wrappers with `URI` in code or via the `netx tun` command.\n\n## Installation\n\n```bash\ngo get github.com/pedramktb/go-netx@latest\n```\n\nImport as:\n\n```go\nimport netx \"github.com/pedramktb/go-netx\"\n```\n\nProtocol implementations and drivers live in separate modules:\n\n```bash\ngo get github.com/pedramktb/go-netx/proto/aesgcm@latest   # AES-GCM conn\ngo get github.com/pedramktb/go-netx/proto/dnst@latest      # DNS tunnel conn\ngo get github.com/pedramktb/go-netx/proto/ssh@latest        # SSH conn\ngo get github.com/pedramktb/go-netx/drivers/tls@latest      # TLS driver (register via blank import)\n# ... etc.\n```\n\n## Library guide\n\n### Buffered connections\n\n```go\nc, _ := net.Dial(\"tcp\", addr)\nbc := netx.NewBufConn(c, netx.WithBufSize(8\u003c\u003c10))\n\n_, _ = bc.Write([]byte(\"hello\"))\n_ = bc.Flush() // ensure data is written now\n```\n\nNotes:\n\n- `NewBufConn` returns a `BufConn` that implements `net.Conn` plus `Flush() error`.\n- Options: `WithBufSize(uint16)` sets both reader and writer size; `WithBufReaderSize(uint16)` and `WithBufWriterSize(uint16)` set them independently. Default: 4096.\n- `Close()` will attempt to `Flush()` and close, returning a joined error if any.\n\n### Framed connections\n\n```go\nrawClient, rawServer := net.Pipe()\ndefer rawClient.Close(); defer rawServer.Close()\n\nclient := netx.NewFramedConn(rawClient)                           // default max frame size 4096\nserver := netx.NewFramedConn(rawServer, netx.WithMaxFrameSize(64\u003c\u003c10))\n\nmsg := []byte(\"hello frame\")\n_, _ = client.Write(msg) // sends a 4-byte big-endian length header then payload\n\nbuf := make([]byte, len(msg))\n_, _ = io.ReadFull(server, buf) // reads exactly one frame (may deliver across multiple Read calls)\n```\n\nNotes:\n\n- Each `Write(p)` sends one frame. Empty frames are allowed and read as `n=0, err=nil`.\n- If an incoming frame exceeds `maxFrameSize`, `Read` returns `ErrFrameTooLarge`.\n- If the underlying conn also supports `Flush` (e.g., `BufConn`), `Write` flushes to coalesce header+payload.\n\n### Mux and MuxClient\n\n`NewMux` adapts a `net.Listener` into a single `net.Conn`. Reads accept connections from the listener; when the current connection reaches EOF, the next one is accepted transparently. Writes go to the most recently accepted connection.\n\n`NewMuxClient` does the inverse: it wraps a `Dialer` function as a `net.Conn`, dialing lazily on first use and redialing on EOF.\n\n```go\n// Server side: collapse accepted connections into one conn\nln, _ := net.Listen(\"tcp\", \":9000\")\nconn := netx.NewMux(ln) // conn implements net.Conn\n\n// Client side: auto-reconnecting conn from a dialer\nclientConn := netx.NewMuxClient(func() (net.Conn, error) {\n\treturn net.Dial(\"tcp\", \"server:9000\")\n}, netx.WithMuxClientRemoteAddr(remoteAddr))\n```\n\nNotes:\n\n- Deadlines set on the mux propagate to newly accepted/dialed connections.\n- Closing the mux closes both the current connection and the underlying listener/dialer.\n\n### Demux and DemuxClient\n\n`NewDemux` is a session multiplexer: it reads from a single `net.Conn`, extracts a fixed-length session ID prefix from each packet, and routes payloads to virtual per-session connections exposed via a `net.Listener`.\n\n`NewDemuxClient` creates a `Dialer` that produces connections which automatically prepend/strip a session ID on every write/read.\n\n```go\n// Server: multiplex sessions over a single conn\nsessListener := netx.NewDemux(conn, 4, // 4-byte session ID\n\tnetx.WithDemuxSessQueueSize(16),\n\tnetx.WithDemuxAccQueueSize(8),\n)\ndefer sessListener.Close()\n\nfor {\n\tsess, _ := sessListener.Accept() // each session is a net.Conn\n\tgo handleSession(sess)\n}\n```\n\n```go\n// Client: wrap a conn with a session ID\ndial := netx.NewDemuxClient(conn, []byte{0x01, 0x02, 0x03, 0x04})\nsessConn, _ := dial() // net.Conn with ID prepended on writes, stripped on reads\n```\n\nOptions:\n\n| Option | Default | Purpose |\n|---|---|---|\n| `WithDemuxAccQueueSize(uint16)` | 0 (unbuffered) | Accept queue capacity |\n| `WithDemuxSessQueueSize(uint16)` | 8 | Per-session read queue depth |\n| `WithDemuxBufSize(uint16)` | 4096 | Underlying read buffer size |\n| `WithDemuxClientBufSize(uint16)` | 4096 | Client read/write buffer size |\n\n### Poll connections\n\n`NewPollConn` converts a request-response style `net.Conn` into a persistent bidirectional stream. It sends user data (or empty polls on idle) and reads back responses in a continuous loop.\n\n```go\npollConn := netx.NewPollConn(reqRespConn,\n\tnetx.WithPollInterval(50*time.Millisecond),\n\tnetx.WithPollBufSize(4096),\n\tnetx.WithPollSendQueueSize(32),\n\tnetx.WithPollRecvQueueSize(32),\n)\ndefer pollConn.Close()\n\n_, _ = pollConn.Write(data) // queued, sent on next cycle\n_, _ = pollConn.Read(buf)   // blocks until a response arrives\n```\n\nThis is essential for protocols where the client must poll to receive data (e.g., DNS tunneling where the server can only respond to queries).\n\n### Tagged connections\n\n`TaggedConn` extends `net.Conn` semantics with an opaque `any` tag that carries context from the read path to the write path. This is critical for protocols where responses must correspond to specific requests (e.g., DNS queries).\n\n```go\ntype TaggedConn interface {\n\tReadTagged([]byte, *any) (int, error)   // read payload + capture tag\n\tWriteTagged([]byte, any) (int, error)   // write payload + attach tag\n\tClose() error\n\tLocalAddr() net.Addr\n\tRemoteAddr() net.Addr\n\tSetDeadline(t time.Time) error\n\tSetReadDeadline(t time.Time) error\n\tSetWriteDeadline(t time.Time) error\n}\n```\n\n`TaggedPipe()` creates an in-memory bidirectional `TaggedConn` pair (analogous to `net.Pipe()`), useful for testing.\n\n`NewTaggedDemux` is the tag-aware variant of `NewDemux`: it routes `{payload, tag}` pairs to sessions, and sessions consume tags on write so the response is constructed with the original request context.\n\n### Runtime-routable server\n\nRegister handlers keyed by an ID (any comparable type). Each handler decides if it matches an incoming connection and returns an `io.Closer` to track (often the conn itself or a wrapped version).\n\n```go\nvar s netx.Server[string]\n\n// Route A: TLS connections\ns.SetRoute(\"tls\", func(ctx context.Context, conn net.Conn, closed func()) (bool, io.Closer) {\n\tif _, ok := conn.(interface{ ConnectionState() tls.ConnectionState }); !ok {\n\t\treturn false, nil\n\t}\n\t// handle TLS conn; call closed() when the connection is fully done\n\tgo func() { /* ... */ ; closed() }()\n\treturn true, conn\n})\n\n// Route B: plain connections (fallback)\ns.SetRoute(\"plain\", func(ctx context.Context, conn net.Conn, closed func()) (bool, io.Closer) {\n\tif _, ok := conn.(interface{ ConnectionState() tls.ConnectionState }); ok {\n\t\treturn false, nil\n\t}\n\tgo func() { /* ... */ ; closed() }()\n\treturn true, conn\n})\n\nln, _ := net.Listen(\"tcp\", \":8080\")\ngo s.Serve(context.Background(), ln)\n\n// Hot-swap or remove routes at runtime\ns.SetRoute(\"plain\", newHandler)\ns.RemoveRoute(\"tls\")\n\n// Graceful shutdown\nctx, cancel := context.WithTimeout(context.Background(), time.Second)\ndefer cancel()\n_ = s.Shutdown(ctx) // waits for tracked connections or force-closes on deadline\n```\n\nHandler contract:\n\n- Return `(matched=false, _ )` quickly if the connection is not yours; the server will try the next route.\n- If you take ownership, return `(true, closer)`. Use `closed()` exactly once when you are logically done so the server stops tracking it.\n- If you return `nil` for the closer, the server will track the original `conn`.\n- `Close()` immediately stops accepting and closes tracked connections. `Shutdown(ctx)` stops accepting and waits for tracked connections until `ctx` is done, after which remaining connections are force-closed.\n\n### Tunneling\n\n`Tun` relays bytes bidirectionally between two endpoints. `TunMaster[ID]` builds on `Server[ID]` to create tunnels from accepted conns.\n\nBridge UDP over a framed TCP stream:\n\n```go\n// Server side: accept a TCP stream, frame it, and relay to a UDP socket\nvar tm netx.TunMaster[string]\ntm.SetRoute(\"udp-over-tcp\", func(ctx context.Context, conn net.Conn) (bool, context.Context, netx.Tun) {\n\tframed := netx.NewFramedConn(conn)\n\tudpConn, _ := net.DialUDP(\"udp\", nil, serverUDPAddr)\n\treturn true, ctx, netx.Tun{Conn: framed, Peer: udpConn, BufferSize: 64 \u003c\u003c 10}\n})\n\nln, _ := net.Listen(\"tcp\", \":9000\")\ngo tm.Serve(context.Background(), ln)\n```\n\nNotes:\n\n- `Tun.Relay(ctx)` runs two half-duplex copies until either side closes; `Close()` shuts both sides.\n- `BufferSize` controls the copy buffer (default 32KiB).\n- `TunMaster.SetRoute` starts `Relay` in a goroutine and calls the server's `closed()` when finished; it also logs tunnel start/close using the configured `Logger`.\n\n### Driver and wrapper system\n\nnetX uses a pluggable driver registry and a typed wrapper pipeline for composing connection transformations.\n\n**Drivers** are registered globally and instantiate `Wrapper` values from parameters:\n\n```go\n// Register a custom driver (typically in an init function)\nnetx.Register(\"myproto\", func(params map[string]string, listener bool) (netx.Wrapper, error) {\n\treturn netx.Wrapper{\n\t\tName:       \"myproto\",\n\t\tParams:     params,\n\t\tListener:   listener,\n\t\tConnToConn: func(c net.Conn) (net.Conn, error) { return myWrap(c), nil },\n\t}, nil\n})\n```\n\n**Wrappers** form a typed pipeline that chains transformations. Each wrapper declares which pipe type it accepts and produces (`net.Listener`, `Dialer`, `net.Conn`, or `TaggedConn`):\n\n```go\n// Apply wrappers manually\nvar wrappers netx.Wrappers\n_ = wrappers.UnmarshalText([]byte(\"tls{cert=...,key=...}+framed\"), true) // true = listener side\n\nwrapped, _ := wrappers.Apply(rawListener) // net.Listener → net.Listener\n```\n\n**Schemes** combine a transport with wrappers:\n\n```go\nvar s netx.ListenerScheme\n_ = s.UnmarshalText([]byte(\"tcp+tls{cert=...,key=...}+framed\"))\nln, _ := s.Listen(ctx, \":9000\")\n```\n\nBuilt-in drivers available via blank import of `drivers/*` packages: `aesgcm`, `dnst`, `dtls`, `dtlspsk`, `ssh`, `tls`, `tlspsk`, `utls`. Core drivers (`buffered`, `framed`, `mux`, `demux`) are registered automatically.\n\n### Programmatic URIs\n\nThe chainable URI system composes a transport, wrappers, and address into a single string. URIs follow the format `\u003ctransport\u003e+\u003cwrapper1\u003e{params}+\u003cwrapper2\u003e://\u003caddress\u003e`.\n\n```go\nctx := context.Background()\n\nvar listenURI netx.ListenerURI\n_ = listenURI.UnmarshalText([]byte(\"tcp+tls{cert=...hex...,key=...hex...}://:9000\"))\nln, _ := listenURI.Listen(ctx)\n\nvar dialURI netx.DialerURI\n_ = dialURI.UnmarshalText([]byte(\"udp+aesgcm{key=...hex...}://127.0.0.1:5555\"))\npeerConn, _ := dialURI.Dial(ctx)\n\nserverConn, _ := ln.Accept()\n\ntun := netx.Tun{Conn: serverConn, Peer: peerConn}\ngo tun.Relay(ctx)\n```\n\n`ListenerURI.Listen` and `DialerURI.Dial` instantiate the transport, apply each wrapper in order, and enforce type-safe pipeline validation.\n\n### Logging\n\nYou can plug any logger that implements the simple `Logger` interface:\n\n```go\ntype Logger interface {\n\tDebugContext(ctx context.Context, msg string, args ...any)\n\tInfoContext(ctx context.Context, msg string, args ...any)\n\tWarnContext(ctx context.Context, msg string, args ...any)\n\tErrorContext(ctx context.Context, msg string, args ...any)\n}\n```\n\nIf `Logger` is nil, the server/tunnel use `slog.Default()`.\n\n### Design notes and guarantees\n\n- All wrappers implement `net.Conn` (or `TaggedConn`) where applicable to remain drop-in.\n- The wrapper pipeline validates type compatibility at parse time — mismatched chains fail early.\n- Server routes use copy-on-write updates; `SetRoute`/`RemoveRoute` are safe to call concurrently.\n- Unhandled connections are dropped immediately after all routes decline.\n- `Shutdown(ctx)` will close listeners, then wait for tracked connections until `ctx` is done, after which remaining connections are force-closed.\n- Mux and MuxClient transparently handle connection cycling (accept/redial on EOF).\n- Demux sessions are fully independent `net.Conn` values with their own read queues; backpressure is per-session.\n\n## CLI\n\nThe CLI is available at `cli/cmd/netx` with a `tun` subcommand to relay between chainable endpoints.\n\n### Quick start\n\n1. Install the CLI.\n\n\t ```bash\n\t go install github.com/pedramktb/go-netx/cli/cmd/netx@latest\n\t ```\n\n2. Compose listener and dialer URIs. Quote them so shells do not mangle the `+`, `{`, or `,` characters.\n\n\t ```bash\n\t netx tun \\\n\t\t --from \"tcp+tls{cert=$(cat server.crt | xxd -p),key=$(cat server.key | xxd -p)}://:9000\" \\\n\t\t --to   \"udp+aesgcm{key=00112233445566778899aabbccddeeff}://127.0.0.1:5555\"\n\t ```\n\n3. Watch the logs. Adjust verbosity with `--log debug`, or hit `Ctrl+C` for a graceful shutdown.\n\n### Install and upgrade\n\n```bash\ngo install github.com/pedramktb/go-netx/cli/cmd/netx@latest\n```\n\n### Build from source\n\n```bash\ntask build\n```\n\n### Example commands\n\n```bash\n# Show help\nnetx tun -h\n\n# Example: TCP TLS server to TCP TLS+buffered+framed+aesgcm client\nnetx tun \\\n\t--from tcp+tls{cert=server.crt,key=server.key}://:9000 \\\n\t--to tcp+tls{cert=client.crt}+buffered{size=8192}+framed{maxsize=4096}+aesgcm{key=00112233445566778899aabbccddeeff}://example.com:9443\n\n# Example: UDP DTLS server to UDP aesgcm client\nnetx tun \\\n\t--from udp+dtls{cert=server.crt,key=server.key}://:4444 \\\n\t--to udp+aesgcm{key=00112233445566778899aabbccddeeff}://10.0.0.10:5555\n\n# Example: DNS tunnel server\nnetx tun \\\n\t--from udp+dnst{domain=t.example.com}+demux{id=0000,sessqueuesize=16}://:53 \\\n\t--to tcp://internal-service:8080\n```\n\nOptions:\n\n- `--from \u003cchain\u003e://listenAddr` - Incoming side chain URI (required)\n- `--to \u003cchain\u003e://connectAddr` - Peer side chain URI (required)\n- `--log \u003clevel\u003e` - Log level: debug|info|warn|error (default: info)\n- `-h` - Show help\n\n### Chain syntax reference\n\nChains use the form `\u003ctransport\u003e+\u003cwrapper1\u003e+\u003cwrapper2\u003e+...://host:port` where `\u003ctransport\u003e` is a base transport, optionally followed by `+`-separated wrappers with parameters in braces.\n\n**Supported base transports:**\n\n- `tcp` - TCP listener or dialer\n- `udp` - UDP listener or dialer\n- `icmp` - ICMP listener or dialer (tunnels over Echo Request/Reply)\n\n**Supported wrappers:**\n\n- `buffered` - Buffered read/write for better performance\n\t- Params: `size` (optional, default: 4096)\n\n- `framed` - Length-prefixed frames for packet semantics over streams\n\t- Params: `maxsize` (optional, default: 4096)\n\n- `mux` - Collapse a listener into a single `net.Conn` (server) or auto-reconnecting dialer into a `net.Conn` (client)\n\t- No params\n\n- `demux` - Session multiplexer over a single conn\n\t- Params: `id` (hex, required for client), `bufsize` (optional), `accqueuesize` (optional), `sessqueuesize` (optional)\n\n- `dnst` - DNS tunnel encoding (Base32 in TXT queries/responses)\n\t- Params: `domain` (required)\n\n- `poll` - Convert request-response conn into persistent bidirectional stream\n\t- Params: `interval` (optional), `bufsize` (optional), `sendqueuesize` (optional), `recvqueuesize` (optional)\n\n- `aesgcm` - AES-GCM encryption with passive IV exchange\n\t- Params: `key`, `maxpacket` (optional, default: 32768)\n\n- `tls` - Transport Layer Security\n\t- Server params: `cert`, `key`\n\t- Client params: `cert` (optional, for SPKI pinning), `servername` (required if cert not provided)\n\n- `utls` - TLS with client fingerprint camouflage via uTLS\n\t- Client-side only\n\t- Params: `cert` (optional, for SPKI pinning), `servername` (required if cert not provided), `hello` (optional: chrome, firefox, ios, android, safari, edge, randomized; default: chrome)\n\n- `dtls` - Datagram Transport Layer Security\n\t- Server params: `cert`, `key`\n\t- Client params: `cert` (optional, for SPKI pinning), `servername` (required if cert not provided)\n\n- `tlspsk` - TLS with pre-shared key (cipher: TLS_DHE_PSK_WITH_AES_256_CBC_SHA)\n\t- Params: `key`\n\n- `dtlspsk` - DTLS with pre-shared key (cipher: TLS_PSK_WITH_AES_128_GCM_SHA256)\n\t- Params: `key`\n\n- `ssh` - SSH tunneling via \"direct-tcpip\" channels\n\t- Server params: `key`, `pass` (optional), `pubkey` (optional, required if no pass)\n\t- Client params: `pubkey`, `pass` (optional), `key` (optional, required if no pass)\n\n**Notes:**\n- All passwords, keys and certificates must be provided as hex-encoded strings.\n- When using `cert` for client-side `tls`/`utls`/`dtls`, default validation is disabled and a manual SPKI (SubjectPublicKeyInfo) hash comparison is performed against the provided certificate. This is certificate pinning and will fail if the server presents a different key.\n- SSH server must accept \"direct-tcpip\" channels (most do by default).\n- See [docs/mux-tag-poll.md](docs/mux-tag-poll.md) for the full architecture and data-flow diagrams of the mux/demux/poll/tagged system.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpedramktb%2Fgo-netx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpedramktb%2Fgo-netx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpedramktb%2Fgo-netx/lists"}