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
80 lines
1.8 KiB
Go
80 lines
1.8 KiB
Go
package client
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/openp2p-cn/inp2p/internal/server"
|
|
"github.com/openp2p-cn/inp2p/pkg/config"
|
|
"github.com/openp2p-cn/inp2p/pkg/nat"
|
|
)
|
|
|
|
func TestClientLogin(t *testing.T) {
|
|
// Server
|
|
sCfg := config.DefaultServerConfig()
|
|
sCfg.WSPort = 29400
|
|
sCfg.STUNUDP1 = 29482
|
|
sCfg.STUNUDP2 = 29484
|
|
sCfg.STUNTCP1 = 29480
|
|
sCfg.STUNTCP2 = 29481
|
|
sCfg.Token = 777
|
|
|
|
stunQuit := make(chan struct{})
|
|
defer close(stunQuit)
|
|
go nat.ServeUDPSTUN(sCfg.STUNUDP1, stunQuit)
|
|
go nat.ServeUDPSTUN(sCfg.STUNUDP2, stunQuit)
|
|
go nat.ServeTCPSTUN(sCfg.STUNTCP1, stunQuit)
|
|
go nat.ServeTCPSTUN(sCfg.STUNTCP2, stunQuit)
|
|
|
|
srv := server.New(sCfg)
|
|
srv.StartCleanup()
|
|
mux := http.NewServeMux()
|
|
mux.HandleFunc("/ws", srv.HandleWS)
|
|
go http.ListenAndServe(fmt.Sprintf(":%d", sCfg.WSPort), mux)
|
|
time.Sleep(300 * time.Millisecond)
|
|
|
|
// Client
|
|
cCfg := config.DefaultClientConfig()
|
|
cCfg.ServerHost = "127.0.0.1"
|
|
cCfg.ServerPort = 29400
|
|
cCfg.Node = "testClient"
|
|
cCfg.Token = 777
|
|
cCfg.Insecure = true
|
|
cCfg.RelayEnabled = true
|
|
cCfg.STUNUDP1 = 29482
|
|
cCfg.STUNUDP2 = 29484
|
|
cCfg.STUNTCP1 = 29480
|
|
cCfg.STUNTCP2 = 29481
|
|
|
|
c := New(cCfg)
|
|
|
|
// Run in background, should connect within 8 seconds
|
|
connected := make(chan struct{})
|
|
go func() {
|
|
// We'll just let it run for a bit
|
|
c.Run()
|
|
}()
|
|
|
|
// Wait for login
|
|
time.Sleep(8 * time.Second)
|
|
|
|
nodes := srv.GetOnlineNodes()
|
|
log.Printf("Online nodes: %d", len(nodes))
|
|
for _, n := range nodes {
|
|
log.Printf(" - %s (NAT=%s, relay=%v)", n.Name, n.NATType, n.RelayEnabled)
|
|
}
|
|
|
|
if len(nodes) == 1 && nodes[0].Name == "testClient" {
|
|
close(connected)
|
|
log.Println("✅ Client connected successfully!")
|
|
} else {
|
|
t.Fatalf("Expected testClient online, got %d nodes", len(nodes))
|
|
}
|
|
|
|
c.Stop()
|
|
srv.Stop()
|
|
}
|