Built-in DHCP (raw Ethernet frames through tunnel), automatic reconnection, host route management, classless static routes (option 121/249), DNS config. Single static binary, Linux only. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2.9 KiB
Project structure
softether-go/
├── cmd/softether-go/
│ └── main.go CLI entry point
├── pkg/
│ ├── client/
│ │ ├── client.go SoftEther handshake and session
│ │ ├── tunnel.go TCP block framing and keepalive
│ │ └── crypto.go SHA-0 and password hashing
│ ├── protocol/
│ │ ├── http.go HTTP transport layer
│ │ └── pack.go Pack binary serialization
│ ├── dhcp/
│ │ └── dhcp.go DHCP client (raw Ethernet frames)
│ └── tap/
│ └── tap.go Linux TAP device management
├── docs/ Documentation
├── vendor/ Vendored Go dependencies
├── flake.nix Nix build definition
├── go.mod
└── go.sum
Package details
cmd/softether-go
CLI entry point. Handles flag parsing, signal handling, and the reconnection loop. On each session:
- Connects to the server
- Runs DHCP through the tunnel
- Configures the TAP interface (IP, routes, DNS)
- Bridges Ethernet frames between the TAP device and the VPN tunnel
- Cleans up on disconnect and retries
pkg/client
client.go — implements the SoftEther handshake: TLS connect, signature upload, hello/auth/welcome pack exchange. Exports Connect(Config) (*Session, error) and the Config/Session types.
tunnel.go — TCP block framing after the HTTP handshake. ReadFrames() reads batches of Ethernet frames from the server. WriteFrames() sends batches. StartKeepalive() sends periodic keepalive packets (every 3s) to prevent server timeout.
crypto.go — SHA-0 implementation (differs from SHA-1 only in the message schedule — no left-rotate). HashPassword() produces SHA0(password). SecurePassword() produces SHA0(hashed + serverRandom).
pkg/protocol
http.go — HTTP transport layer. DialTLS() establishes the TLS connection. UploadSignature() sends the protocol signature. SendPack() and RecvPack() exchange binary Packs as HTTP POST request/response bodies.
pack.go — SoftEther Pack binary serialization. A Pack is a list of named Elements, each containing typed Values (int, string, data, ip4). Handles the BufStr wire format (uint32(strlen+1) then strlen bytes) and the pencore random padding element.
pkg/dhcp
dhcp.go — DHCP client that constructs complete Ethernet/IP/UDP/DHCP frames. The full DHCP exchange (DISCOVER → OFFER → REQUEST → ACK) runs through the VPN tunnel's frame transport. Parses lease information including classless static routes (option 121/249, RFC 3442).
pkg/tap
tap.go — Linux TAP (Layer 2) device management via /dev/net/tun. Opens TAP devices with IFF_TAP | IFF_NO_PI, reads/writes raw Ethernet frames. Provides MAC() to get the hardware address and SetUp() to bring the interface up.