- The sower frame checksum now covers the command and port in addition to
the target, using HMAC-SHA256 (length-extension resistant) so a
man-in-the-middle on a plaintext link cannot retarget a captured frame
to an arbitrary port.
- Unwrap rejects empty or control-character target hosts.
- The SOCKS5 server writes the RFC 1928 METHOD=0xFF failure response
instead of leaving the peer hanging on an unusable negotiation.
- DHCP discovery validates the reply (matching xid, BOOTREPLY, message
type OFFER) and skips unrelated packets instead of trusting the first
datagram, closing a LAN-side DNS-hijack vector; the socket also sets
SO_BROADCAST explicitly (Go 1.26 removed UDPConn.SetBroadcast).
- The uTLS handshake gets a bounded default deadline when the dialer has
no timeout, so it cannot hang open forever.
- The suffix tree trims every trailing dot so dirty rule files cannot
build unreachable empty-label subtrees.
sumChecksum used binary.Uvarint over the digest, which stops at the
first byte with a clear continuation bit: ~50% of checksums collapsed
to 7 bits of entropy (~15 bits effective), making the auth check
brute-forceable. Take a fixed 64-bit window of a SHA-256 digest
instead. Wire layout is unchanged (checksum stays 8 bytes), and the
randomized field also removes the "high bytes all zero" fingerprint.
Trojan transport, config options, and tests are removed entirely.
The sowerd probe abstraction now handles only the sower protocol;
adding new transports requires only a new proxyProtocolHandler impl.
- transport/trojan/: deleted
- cmd/sower/proxy.go: remove trojan import and branch
- config/sower.go,sowerd.go: remove trojan from type options and validate
- transport/transport_test.go: remove trojan test cases