feat: INP2P v0.1.0 — complete P2P tunneling system
Core modules (M1-M6): - pkg/protocol: message format, encoding, NAT type enums - pkg/config: server/client config structs, env vars, validation - pkg/auth: CRC64 token, TOTP gen/verify, one-time relay tokens - pkg/nat: UDP/TCP STUN client and server - pkg/signal: WSS message dispatch, sync request/response - pkg/punch: UDP/TCP hole punching + priority chain - pkg/mux: stream multiplexer (7B frame: StreamID+Flags+Len) - pkg/tunnel: mux-based port forwarding with stats - pkg/relay: relay manager with TOTP auth + session bridging - internal/server: signaling server (login/heartbeat/report/coordinator) - internal/client: client (NAT detect/login/punch/relay/reconnect) - cmd/inp2ps + cmd/inp2pc: main entrypoints with graceful shutdown All tests pass: 16 tests across 5 packages Code: 3559 lines core + 861 lines tests = 19 source files
This commit is contained in:
118
cmd/inp2pc/main.go
Normal file
118
cmd/inp2pc/main.go
Normal file
@@ -0,0 +1,118 @@
|
||||
// inp2pc — INP2P P2P Client
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/openp2p-cn/inp2p/internal/client"
|
||||
"github.com/openp2p-cn/inp2p/pkg/auth"
|
||||
"github.com/openp2p-cn/inp2p/pkg/config"
|
||||
)
|
||||
|
||||
func main() {
|
||||
cfg := config.DefaultClientConfig()
|
||||
|
||||
flag.StringVar(&cfg.ServerHost, "serverhost", "", "Server hostname or IP (required)")
|
||||
flag.IntVar(&cfg.ServerPort, "serverport", cfg.ServerPort, "Server WSS port")
|
||||
flag.StringVar(&cfg.Node, "node", "", "Node name (default: hostname)")
|
||||
token := flag.Uint64("token", 0, "Authentication token (uint64)")
|
||||
user := flag.String("user", "", "Username for token generation")
|
||||
pass := flag.String("password", "", "Password for token generation")
|
||||
flag.BoolVar(&cfg.Insecure, "insecure", false, "Skip TLS verification")
|
||||
flag.BoolVar(&cfg.RelayEnabled, "relay", false, "Enable relay capability")
|
||||
flag.BoolVar(&cfg.SuperRelay, "super", false, "Register as super relay node (implies -relay)")
|
||||
flag.IntVar(&cfg.RelayPort, "relay-port", cfg.RelayPort, "Relay listen port")
|
||||
flag.IntVar(&cfg.MaxRelayLoad, "relay-max", cfg.MaxRelayLoad, "Max concurrent relay sessions")
|
||||
flag.IntVar(&cfg.ShareBandwidth, "bw", cfg.ShareBandwidth, "Share bandwidth (Mbps)")
|
||||
flag.IntVar(&cfg.STUNUDP1, "stun-udp1", cfg.STUNUDP1, "UDP STUN port 1")
|
||||
flag.IntVar(&cfg.STUNUDP2, "stun-udp2", cfg.STUNUDP2, "UDP STUN port 2")
|
||||
flag.IntVar(&cfg.STUNTCP1, "stun-tcp1", cfg.STUNTCP1, "TCP STUN port 1")
|
||||
flag.IntVar(&cfg.STUNTCP2, "stun-tcp2", cfg.STUNTCP2, "TCP STUN port 2")
|
||||
flag.IntVar(&cfg.LogLevel, "log-level", cfg.LogLevel, "Log level")
|
||||
configFile := flag.String("config", "config.json", "Config file path")
|
||||
newConfig := flag.Bool("newconfig", false, "Ignore existing config, use command line args only")
|
||||
version := flag.Bool("version", false, "Print version and exit")
|
||||
flag.Parse()
|
||||
|
||||
if *version {
|
||||
fmt.Printf("inp2pc version %s\n", config.Version)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
// Load config file first (unless -newconfig)
|
||||
if !*newConfig {
|
||||
if data, err := os.ReadFile(*configFile); err == nil {
|
||||
var fileCfg config.ClientConfig
|
||||
if err := json.Unmarshal(data, &fileCfg); err == nil {
|
||||
cfg = fileCfg
|
||||
log.Printf("[main] loaded config from %s", *configFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Command line flags override config file
|
||||
flag.Visit(func(f *flag.Flag) {
|
||||
switch f.Name {
|
||||
case "serverhost":
|
||||
cfg.ServerHost = f.Value.String()
|
||||
case "serverport":
|
||||
fmt.Sscanf(f.Value.String(), "%d", &cfg.ServerPort)
|
||||
case "node":
|
||||
cfg.Node = f.Value.String()
|
||||
case "insecure":
|
||||
cfg.Insecure = true
|
||||
case "relay":
|
||||
cfg.RelayEnabled = true
|
||||
case "super":
|
||||
cfg.SuperRelay = true
|
||||
cfg.RelayEnabled = true // super implies relay
|
||||
case "bw":
|
||||
fmt.Sscanf(f.Value.String(), "%d", &cfg.ShareBandwidth)
|
||||
}
|
||||
})
|
||||
|
||||
// Token from flag or credentials
|
||||
if *token > 0 {
|
||||
cfg.Token = *token
|
||||
} else if *user != "" && *pass != "" {
|
||||
cfg.Token = auth.MakeToken(*user, *pass)
|
||||
log.Printf("[main] token: %d", cfg.Token)
|
||||
}
|
||||
|
||||
if err := cfg.Validate(); err != nil {
|
||||
log.Fatalf("[main] config error: %v", err)
|
||||
}
|
||||
|
||||
log.Printf("[main] inp2pc v%s starting", config.Version)
|
||||
log.Printf("[main] node=%s server=%s:%d relay=%v super=%v",
|
||||
cfg.Node, cfg.ServerHost, cfg.ServerPort, cfg.RelayEnabled, cfg.SuperRelay)
|
||||
|
||||
// Save config
|
||||
if data, err := json.MarshalIndent(cfg, "", " "); err == nil {
|
||||
os.WriteFile(*configFile, data, 0644)
|
||||
}
|
||||
|
||||
// Create and run client
|
||||
c := client.New(cfg)
|
||||
|
||||
// Handle shutdown
|
||||
sigCh := make(chan os.Signal, 1)
|
||||
signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM)
|
||||
go func() {
|
||||
<-sigCh
|
||||
log.Println("[main] shutting down...")
|
||||
c.Stop()
|
||||
}()
|
||||
|
||||
if err := c.Run(); err != nil {
|
||||
log.Fatalf("[main] client error: %v", err)
|
||||
}
|
||||
|
||||
log.Println("[main] goodbye")
|
||||
}
|
||||
Reference in New Issue
Block a user