# 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.
