softether-go/docs/structure.md
Git Sagar 17c1063e1f refactor: extract session/netcfg/tunnel, add mac/dhcp/policy-route flags
- Split cmd/softether-go into main.go (flags, reconnect loop) and
  session.go (session lifecycle, DHCP orchestration)
- Extract network config to pkg/netcfg (TAP config, routing, DNS, policy routes)
- Move frame bridging to pkg/client/tunnel.go as Bridge() method
- Add -mac, -dhcp, -policy-route-table CLI flags
- Add SetMAC() to pkg/tap for deterministic DHCP assignments
- Update all docs to reflect new structure and flags

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-06-06 16:43:12 +05:30

3.8 KiB

Project structure

softether-go/
├── cmd/softether-go/
│   ├── main.go              Flag parsing, TAP setup, reconnect loop
│   └── session.go           Session lifecycle, DHCP orchestration
├── pkg/
│   ├── client/
│   │   ├── client.go        SoftEther handshake and session
│   │   ├── tunnel.go        TCP block framing, keepalive, frame bridging
│   │   └── crypto.go        SHA-0 and password hashing
│   ├── protocol/
│   │   ├── http.go          TLS connection, HTTP transport layer
│   │   └── pack.go          Pack binary serialization
│   ├── dhcp/
│   │   └── dhcp.go          DHCP client (raw Ethernet frames)
│   ├── netcfg/
│   │   └── netcfg.go        TAP configuration, routing, DNS management
│   └── 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, split into two files:

main.go — flag parsing, TAP device creation, MAC configuration, signal handling, and the reconnect loop. Calls runSession for each connection attempt.

session.go — one VPN session lifecycle: connect to server, start bridge, run DHCP, configure TAP (IP/routes/DNS/policy routing), and wait for disconnect or signal. Also contains runDHCP which orchestrates the DHCP exchange through the tunnel.

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 completes. ReadFrames() reads batches of Ethernet frames from the server. WriteFrames() sends batches. Bridge() runs bidirectional frame forwarding between the tunnel and a TAP device, with an optional FrameHandler callback for intercepting frames (used by DHCP). StartKeepalive() sends periodic keepalive packets (every 3s).

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/netcfg

netcfg.go — network configuration for the VPN tunnel. ConfigureTAP() sets IP address, routes, and DNS on the TAP interface from a DHCP lease. ConfigurePolicyRoute() sets up policy routing for asymmetric return paths. AddServerRoute() adds a host route to the VPN server via the current default gateway. ResolveHost() resolves hostnames to IPv4.

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() and SetMAC() for hardware address management, and SetUp() to bring the interface up.