Holepunch to the right endpoint

This commit is contained in:
Owen
2025-07-21 17:04:05 -07:00
parent 510e78437c
commit f1fcc13e66
3 changed files with 65 additions and 47 deletions

View File

@@ -55,11 +55,20 @@ func closeClients() {
} }
} }
func clientsHandleNewtConnection(publicKey string) { func clientsHandleNewtConnection(publicKey string, endpoint string) {
if wgService == nil { if wgService == nil {
return return
} }
wgService.SetServerPubKey(publicKey)
// split off the port from the endpoint
parts := strings.Split(endpoint, ":")
if len(parts) < 2 {
logger.Error("Invalid endpoint format: %s", endpoint)
return
}
endpoint = strings.Join(parts[:len(parts)-1], ":")
wgService.StartHolepunch(publicKey, endpoint)
} }
func clientsOnConnect() { func clientsOnConnect() {

48
main.go
View File

@@ -334,8 +334,6 @@ func main() {
return return
} }
clientsHandleNewtConnection(wgData.PublicKey)
logger.Debug("Received: %+v", msg) logger.Debug("Received: %+v", msg)
tun, tnet, err = netstack.CreateNetTUN( tun, tnet, err = netstack.CreateNetTUN(
[]netip.Addr{netip.MustParseAddr(wgData.TunnelIP)}, []netip.Addr{netip.MustParseAddr(wgData.TunnelIP)},
@@ -365,6 +363,8 @@ func main() {
return return
} }
clientsHandleNewtConnection(wgData.PublicKey, endpoint)
// Configure WireGuard // Configure WireGuard
config := fmt.Sprintf(`private_key=%s config := fmt.Sprintf(`private_key=%s
public_key=%s public_key=%s
@@ -578,30 +578,34 @@ persistent_keepalive_interval=5`, fixKey(privateKey.String()), fixKey(wgData.Pub
WasPreviouslyConnected: res.Node.WasPreviouslyConnected, WasPreviouslyConnected: res.Node.WasPreviouslyConnected,
}) })
} }
// If we were previously connected and there is at least one other good node, // If we were previously connected and there is at least one other good node,
// exclude the previously connected node from pingResults sent to the cloud. // exclude the previously connected node from pingResults sent to the cloud so we don't try to reconnect to it
var filteredPingResults []ExitNodePingResult // This is to avoid issues where the previously connected node might be down or unreachable
previouslyConnectedNodeIdx := -1 if connected {
for i, res := range pingResults { var filteredPingResults []ExitNodePingResult
if res.WasPreviouslyConnected { previouslyConnectedNodeIdx := -1
previouslyConnectedNodeIdx = i
}
}
// Count good nodes (latency > 0, no error, not previously connected)
goodNodeCount := 0
for i, res := range pingResults {
if i != previouslyConnectedNodeIdx && res.LatencyMs > 0 && res.Error == "" {
goodNodeCount++
}
}
if previouslyConnectedNodeIdx != -1 && goodNodeCount > 0 {
for i, res := range pingResults { for i, res := range pingResults {
if i != previouslyConnectedNodeIdx { if res.WasPreviouslyConnected {
filteredPingResults = append(filteredPingResults, res) previouslyConnectedNodeIdx = i
} }
} }
pingResults = filteredPingResults // Count good nodes (latency > 0, no error, not previously connected)
logger.Info("Excluding previously connected exit node from ping results due to other available nodes") goodNodeCount := 0
for i, res := range pingResults {
if i != previouslyConnectedNodeIdx && res.LatencyMs > 0 && res.Error == "" {
goodNodeCount++
}
}
if previouslyConnectedNodeIdx != -1 && goodNodeCount > 0 {
for i, res := range pingResults {
if i != previouslyConnectedNodeIdx {
filteredPingResults = append(filteredPingResults, res)
}
}
pingResults = filteredPingResults
logger.Info("Excluding previously connected exit node from ping results due to other available nodes")
}
} }
// Send the ping results to the cloud for selection // Send the ping results to the cloud for selection

View File

@@ -49,21 +49,22 @@ type PeerReading struct {
} }
type WireGuardService struct { type WireGuardService struct {
interfaceName string interfaceName string
mtu int mtu int
client *websocket.Client client *websocket.Client
wgClient *wgctrl.Client wgClient *wgctrl.Client
config WgConfig config WgConfig
key wgtypes.Key key wgtypes.Key
newtId string newtId string
lastReadings map[string]PeerReading lastReadings map[string]PeerReading
mu sync.Mutex mu sync.Mutex
Port uint16 Port uint16
stopHolepunch chan struct{} stopHolepunch chan struct{}
host string host string
serverPubKey string serverPubKey string
token string holePunchEndpoint string
stopGetConfig func() token string
stopGetConfig func()
} }
// Add this type definition // Add this type definition
@@ -211,13 +212,6 @@ func NewWireGuardService(interfaceName string, mtu int, generateAndSaveKeyTo str
wsClient.RegisterHandler("newt/wg/peer/remove", service.handleRemovePeer) wsClient.RegisterHandler("newt/wg/peer/remove", service.handleRemovePeer)
wsClient.RegisterHandler("newt/wg/peer/update", service.handleUpdatePeer) wsClient.RegisterHandler("newt/wg/peer/update", service.handleUpdatePeer)
if err := service.sendUDPHolePunch(service.host + ":21820"); err != nil {
logger.Error("Failed to send UDP hole punch: %v", err)
}
// start the UDP holepunch
go service.keepSendingUDPHolePunch(service.host)
return service, nil return service, nil
} }
@@ -241,8 +235,14 @@ func (s *WireGuardService) Close(rm bool) {
} }
} }
func (s *WireGuardService) SetServerPubKey(serverPubKey string) { func (s *WireGuardService) StartHolepunch(serverPubKey string, endpoint string) {
s.serverPubKey = serverPubKey s.serverPubKey = serverPubKey
s.holePunchEndpoint = endpoint
logger.Debug("Starting UDP hole punch to %s", s.holePunchEndpoint)
// start the UDP holepunch
go s.keepSendingUDPHolePunch(s.holePunchEndpoint)
} }
func (s *WireGuardService) SetToken(token string) { func (s *WireGuardService) SetToken(token string) {
@@ -926,6 +926,11 @@ func (s *WireGuardService) encryptPayload(payload []byte) (interface{}, error) {
} }
func (s *WireGuardService) keepSendingUDPHolePunch(host string) { func (s *WireGuardService) keepSendingUDPHolePunch(host string) {
// send initial hole punch
if err := s.sendUDPHolePunch(host + ":21820"); err != nil {
logger.Error("Failed to send initial UDP hole punch: %v", err)
}
ticker := time.NewTicker(3 * time.Second) ticker := time.NewTicker(3 * time.Second)
defer ticker.Stop() defer ticker.Stop()