From 995504d76173b1e4fd8aed70a2dc1f2d414e1b4b Mon Sep 17 00:00:00 2001 From: Git Sagar Date: Sat, 6 Jun 2026 17:08:28 +0530 Subject: [PATCH 1/3] netcfg: add verbose logging for TAP configuration Log each step: address assignment, static routes, default route, DNS changes, and cleanup flush. Co-Authored-By: Claude Opus 4.6 (1M context) --- pkg/netcfg/netcfg.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pkg/netcfg/netcfg.go b/pkg/netcfg/netcfg.go index d937729..df5bfcd 100644 --- a/pkg/netcfg/netcfg.go +++ b/pkg/netcfg/netcfg.go @@ -30,6 +30,7 @@ func ConfigureTAP(ifname string, lease *dhcp.Lease, acceptDefaultGW, acceptStati ones, _ := lease.SubnetMask.Size() addr := fmt.Sprintf("%s/%d", lease.ClientIP, ones) + log.Printf("tap %s: adding address %s", ifname, addr) if err := run("ip", "addr", "add", addr, "dev", ifname); err != nil { return noop, fmt.Errorf("ip addr add: %w", err) } @@ -39,12 +40,16 @@ func ConfigureTAP(ifname string, lease *dhcp.Lease, acceptDefaultGW, acceptStati dest := r.Dest.String() if dest == "0.0.0.0/0" { if acceptDefaultGW { + log.Printf("tap %s: adding static default route via %s", ifname, r.Gateway) if err := run("ip", "route", "add", "default", "via", r.Gateway.String(), "dev", ifname, "metric", "50"); err != nil { log.Printf("warning: static default route: %v", err) } + } else { + log.Printf("tap %s: skipping static default route via %s (accept-default-gateway not set)", ifname, r.Gateway) } continue } + log.Printf("tap %s: adding static route %s via %s", ifname, dest, r.Gateway) if err := run("ip", "route", "add", dest, "via", r.Gateway.String(), "dev", ifname); err != nil { log.Printf("warning: static route %s via %s: %v", dest, r.Gateway, err) } @@ -52,6 +57,7 @@ func ConfigureTAP(ifname string, lease *dhcp.Lease, acceptDefaultGW, acceptStati } if acceptDefaultGW && lease.Gateway != nil && !hasDefaultRoute(lease.Routes) { + log.Printf("tap %s: adding default route via %s", ifname, lease.Gateway) if err := run("ip", "route", "add", "default", "via", lease.Gateway.String(), "dev", ifname, "metric", "50"); err != nil { log.Printf("warning: default route: %v", err) } @@ -59,11 +65,13 @@ func ConfigureTAP(ifname string, lease *dhcp.Lease, acceptDefaultGW, acceptStati var savedResolv []byte if acceptDNS && len(lease.DNS) > 0 { + log.Printf("tap %s: setting DNS servers %v", ifname, lease.DNS) savedResolv = backupResolv() writeResolv(lease.DNS) } cleanup := func() { + log.Printf("tap %s: flushing addresses", ifname) run("ip", "addr", "flush", "dev", ifname) if savedResolv != nil { restoreResolv(savedResolv) From ed672e7311e01b7d7862f4e3cb62ea3cdf7c720e Mon Sep 17 00:00:00 2001 From: Git Sagar Date: Sat, 6 Jun 2026 17:11:32 +0530 Subject: [PATCH 2/3] client: rename client string to Softether Go Client Co-Authored-By: Claude Opus 4.6 (1M context) --- pkg/client/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/client/client.go b/pkg/client/client.go index 088fd29..2321dfb 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -21,7 +21,7 @@ import ( ) const ( - clientStr = "SoftEther VPN Client" + clientStr = "Softether Go Client" clientVer = 502 clientBuild = 5187 From 3feb93e679176f6eb934e306b1e2d8ce33da06ce Mon Sep 17 00:00:00 2001 From: Git Sagar Date: Sat, 6 Jun 2026 17:15:35 +0530 Subject: [PATCH 3/3] client: fix version display and rename client string - Rename client to "Softether Go Client" - Fix node info int fields to use LittleEndian32 encoding matching the C client's OutRpcNodeInfo (Admin.c:14693) Co-Authored-By: Claude Opus 4.6 (1M context) --- pkg/client/client.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/pkg/client/client.go b/pkg/client/client.go index 2321dfb..6d735ce 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -128,6 +128,14 @@ func Connect(cfg Config) (*Session, error) { return sess, nil } +// swapLE32 byte-swaps a uint32 to encode it as little-endian within a big-endian Pack int. +// SoftEther's OutRpcNodeInfo wraps node info fields with LittleEndian32() before PackAddInt, +// and InRpcNodeInfo reads them with LittleEndian32(PackGetInt(...)). Our Pack writes big-endian, +// so we pre-swap to match the C client's wire format. +func swapLE32(v uint32) uint32 { + return (v>>24)&0xFF | (v>>8)&0xFF00 | (v<<8)&0xFF0000 | (v<<24)&0xFF000000 +} + // buildAuthPack constructs the authentication Pack sent to the server. // This includes credentials, client version, connection options, node info, and OS info. // See: https://github.com/SoftEtherVPN/SoftEtherVPN/blob/v5.02.5187/src/Cedar/Protocol.c#L7289 @@ -206,8 +214,10 @@ func buildAuthPack(cfg Config, random [sha1Size]byte) *protocol.Pack { // (case-insensitive), and PackRead returns NULL on AddElement failure. // p.AddStr("HubName", cfg.Hub) p.AddData("UniqueId", uniqueID[:16]) - p.AddInt("ClientProductVer", clientVer) - p.AddInt("ClientProductBuild", clientBuild) + // Node info ints use LittleEndian32 encoding (see Admin.c:OutRpcNodeInfo). + // The server reads them back with LittleEndian32(PackGetInt(...)). + p.AddInt("ClientProductVer", swapLE32(clientVer)) + p.AddInt("ClientProductBuild", swapLE32(clientBuild)) p.AddInt("ServerProductVer", 0) p.AddInt("ServerProductBuild", 0) p.AddIP4("ClientIpAddress", 0)