add debug logging for VPN packet flow diagnosis

Add comprehensive console logging at key data path points:
- [TUN-RX]: per-packet TUN read (size, proto, src/dst IP, slow write detection)
- [TUN-TX]: per-packet TUN write (size, success/error)
- [WS-RX]: per-packet WebSocket read from client (size, proto, src/dst IP)
- [WS-TX]: per-packet WebSocket write to client (size, lockWaitMs, writeMs)
- [ROUTE]: routing decisions (TUN->client, client->tun, client->relay, anti-spoof)
- [CONN]: connection lifecycle (init, ready, stats every 10s, disconnect with final stats)
- [STATS]: global traffic stats every 10s (clients, rx/tx bytes and rates)
- [PING]: WebSocket ping failures
- [WS]: WebSocket upgrade with client IP and auth method
- [TUN]: MTU set confirmation, VPN start/stop environment info
This commit is contained in:
2026-07-08 19:14:48 +08:00
parent 3306fc7ee4
commit 616d30bc08
6 changed files with 167 additions and 22 deletions
+48 -7
View File
@@ -155,10 +155,13 @@ func (s *VpnService) ApplySettings(settings model.VpnSetting, reservations4, res
s.mu.Unlock()
go s.serveTUN()
log.Printf("VPN 服务已启动: tun=%s subnet=%s server=%s", tun.Name(), ipNet.String(), serverIP.String())
go s.startStatsLogger()
log.Printf("[TUN] created name=%s mtu=%d", tun.Name(), settings.MTU)
log.Printf("[TUN] ipv4 addr=%s/%d subnet=%s server=%s", serverIP.String(), prefix, ipNet.String(), serverIP.String())
if ipNet6 != nil {
log.Printf(" IPv6: subnet=%s server=%s", ipNet6.String(), serverIP6.String())
log.Printf("[TUN] ipv6 addr=%s/%d subnet=%s server=%s", serverIP6.String(), prefix6, ipNet6.String(), serverIP6.String())
}
log.Printf("[VPN] started c2c=%v bufSize=%d", settings.AllowClientToClient, settings.MTU+64)
return nil
}
@@ -174,17 +177,49 @@ func (s *VpnService) serveTUN() {
for {
n, err := tun.Iface.Read(packet)
if err != nil {
log.Printf("TUN 读取结束: %v", err)
log.Printf("[TUN-RX] read ended: %v", err)
close(done)
return
}
if n < 1 {
continue
}
targets := switchx.RouteFromTUN(packet[:n])
for _, t := range targets {
_ = t.WritePacket(packet[:n])
pkt := packet[:n]
srcIP, destIP, ok := parseIPAddrs(pkt)
if ok {
log.Printf("[TUN-RX] size=%d proto=%s src=%s dst=%s", n, protoName(pkt), srcIP, destIP)
} else {
log.Printf("[TUN-RX] size=%d parse=fail", n)
}
iterStart := time.Now()
targets := switchx.RouteFromTUN(pkt)
for _, t := range targets {
_ = t.WritePacket(pkt)
}
if iterDur := time.Since(iterStart); iterDur > 10*time.Millisecond {
log.Printf("[TUN-RX] slow write iterMs=%d targets=%d size=%d", iterDur.Milliseconds(), len(targets), n)
}
}
}
func (s *VpnService) startStatsLogger() {
ticker := time.NewTicker(10 * time.Second)
defer ticker.Stop()
var lastRx, lastTx int64
for range ticker.C {
if !s.Running() {
return
}
rx, tx := s.TotalLiveTraffic()
rxRate := rx - lastRx
txRate := tx - lastTx
s.mu.RLock()
n := len(s.clients)
s.mu.RUnlock()
log.Printf("[STATS] clients=%d totalRx=%d totalTx=%d intervalRx=%d(%dB/s) intervalTx=%d(%dB/s)",
n, rx, tx, rxRate, rxRate/10, txRate, txRate/10)
lastRx = rx
lastTx = tx
}
}
@@ -210,7 +245,7 @@ func (s *VpnService) Stop() error {
<-done
}
}
log.Printf("VPN 服务已停止")
log.Printf("[VPN] stopped")
return nil
}
@@ -242,9 +277,15 @@ func (s *VpnService) WriteToTUN(packet []byte) error {
tun := s.tun
s.mu.RUnlock()
if tun == nil {
log.Printf("[TUN-TX] size=%d ok=false err=TUN not ready", len(packet))
return errors.New("TUN 未就绪")
}
_, err := tun.Iface.Write(packet)
if err != nil {
log.Printf("[TUN-TX] size=%d ok=false err=%v", len(packet), err)
} else {
log.Printf("[TUN-TX] size=%d ok=true", len(packet))
}
return err
}