Wade Simmons 2 年 前
コミット
4c89b3c6a3
6 ファイル変更35 行追加19 行削除
  1. 1 1
      go.mod
  2. 1 0
      handshake_ix.go
  3. 3 2
      handshake_manager.go
  4. 1 1
      hostmap.go
  5. 10 3
      mutex.go
  6. 19 12
      mutex_debug.go

+ 1 - 1
go.mod

@@ -19,6 +19,7 @@ require (
 	github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
 	github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8
 	github.com/stretchr/testify v1.8.4
+	github.com/timandy/routine v1.1.1
 	github.com/vishvananda/netlink v1.1.0
 	golang.org/x/crypto v0.12.0
 	golang.org/x/exp v0.0.0-20230425010034-47ecfdc1ba53
@@ -43,7 +44,6 @@ require (
 	github.com/prometheus/common v0.42.0 // indirect
 	github.com/prometheus/procfs v0.10.1 // indirect
 	github.com/rogpeppe/go-internal v1.10.0 // indirect
-	github.com/timandy/routine v1.1.1 // indirect
 	github.com/vishvananda/netns v0.0.4 // indirect
 	golang.org/x/mod v0.10.0 // indirect
 	golang.org/x/tools v0.8.0 // indirect

+ 1 - 0
handshake_ix.go

@@ -130,6 +130,7 @@ func ixHandshakeStage1(f *Interface, addr *udp.Addr, via *ViaSender, packet []by
 	}
 
 	hostinfo := &HostInfo{
+		syncRWMutex:       newSyncRWMutex(mutexKey{Type: mutexKeyTypeHostInfo, ID: uint32(vpnIp)}),
 		ConnectionState:   ci,
 		localIndexId:      myIndex,
 		remoteIndexId:     hs.Details.InitiatorIndex,

+ 3 - 2
handshake_manager.go

@@ -7,7 +7,6 @@ import (
 	"encoding/binary"
 	"errors"
 	"net"
-	"sync"
 	"time"
 
 	"github.com/rcrowley/go-metrics"
@@ -44,7 +43,7 @@ type HandshakeConfig struct {
 
 type HandshakeManager struct {
 	// Mutex for interacting with the vpnIps and indexes maps
-	sync.RWMutex
+	syncRWMutex
 
 	vpnIps  map[iputil.VpnIp]*HostInfo
 	indexes map[uint32]*HostInfo
@@ -65,6 +64,7 @@ type HandshakeManager struct {
 
 func NewHandshakeManager(l *logrus.Logger, tunCidr *net.IPNet, preferredRanges []*net.IPNet, mainHostMap *HostMap, lightHouse *LightHouse, outside udp.Conn, config HandshakeConfig) *HandshakeManager {
 	return &HandshakeManager{
+		syncRWMutex:            newSyncRWMutex(mutexKey{Type: mutexKeyTypeHandshakeManager}),
 		vpnIps:                 map[iputil.VpnIp]*HostInfo{},
 		indexes:                map[uint32]*HostInfo{},
 		mainHostMap:            mainHostMap,
@@ -308,6 +308,7 @@ func (c *HandshakeManager) AddVpnIp(vpnIp iputil.VpnIp, init func(*HostInfo)) *H
 	}
 
 	hostinfo := &HostInfo{
+		syncRWMutex:     newSyncRWMutex(mutexKey{Type: mutexKeyTypeHostInfo, ID: uint32(vpnIp)}),
 		vpnIp:           vpnIp,
 		HandshakePacket: make(map[uint8][]byte, 0),
 		relayState: RelayState{

+ 1 - 1
hostmap.go

@@ -264,7 +264,7 @@ func NewHostMap(l *logrus.Logger, vpnCIDR *net.IPNet, preferredRanges []*net.IPN
 	r := map[uint32]*HostInfo{}
 	relays := map[uint32]*HostInfo{}
 	m := HostMap{
-		syncRWMutex:     newSyncRWMutex(mutexKey{Type: "hostmap"}),
+		syncRWMutex:     newSyncRWMutex(mutexKey{Type: mutexKeyTypeHostMap}),
 		Indexes:         i,
 		Relays:          relays,
 		RemoteIndexes:   r,

+ 10 - 3
mutex.go

@@ -9,12 +9,19 @@ import (
 
 type syncRWMutex = sync.RWMutex
 
+type mutexKeyType string
+
+const (
+	mutexKeyTypeHostMap          mutexKeyType = "hostmap"
+	mutexKeyTypeHostInfo                      = "hostinfo"
+	mutexKeyTypeHandshakeManager              = "handshake-manager"
+)
+
 func newSyncRWMutex(mutexKey) syncRWMutex {
 	return sync.RWMutex{}
 }
 
 type mutexKey struct {
-	Type    string
-	SubType string
-	ID      uint32
+	Type mutexKeyType
+	ID   uint32
 }

+ 19 - 12
mutex_debug.go

@@ -13,10 +13,17 @@ import (
 
 var threadLocal routine.ThreadLocal = routine.NewThreadLocalWithInitial(func() any { return map[mutexKey]mutexValue{} })
 
+type mutexKeyType string
+
+const (
+	mutexKeyTypeHostMap          mutexKeyType = "hostmap"
+	mutexKeyTypeHostInfo                      = "hostinfo"
+	mutexKeyTypeHandshakeManager              = "handshake-manager"
+)
+
 type mutexKey struct {
-	Type    string
-	SubType string
-	ID      uint32
+	Type mutexKeyType
+	ID   uint32
 }
 
 type mutexValue struct {
@@ -37,22 +44,22 @@ func newSyncRWMutex(key mutexKey) syncRWMutex {
 
 func checkMutex(state map[mutexKey]mutexValue, add mutexKey) {
 	switch add.Type {
-	case "hostinfo":
+	case mutexKeyTypeHostInfo:
 		// Check for any other hostinfo keys:
 		for k := range state {
-			if k.Type == "hostinfo" {
+			if k.Type == mutexKeyTypeHostInfo {
 				panic(fmt.Errorf("grabbing hostinfo lock and already have a hostinfo lock: state=%v add=%v", state, add))
 			}
 		}
-		if _, ok := state[mutexKey{Type: "hostmap", SubType: "main"}]; ok {
-			panic(fmt.Errorf("grabbing hostinfo lock and already have hostmap-main: state=%v add=%v", state, add))
+		if _, ok := state[mutexKey{Type: mutexKeyTypeHostMap}]; ok {
+			panic(fmt.Errorf("grabbing hostinfo lock and already have hostmap: state=%v add=%v", state, add))
 		}
-		if _, ok := state[mutexKey{Type: "hostmap", SubType: "pending"}]; ok {
-			panic(fmt.Errorf("grabbing hostinfo lock and already have hostmap-pending: state=%v add=%v", state, add))
+		if _, ok := state[mutexKey{Type: mutexKeyTypeHandshakeManager}]; ok {
+			panic(fmt.Errorf("grabbing hostinfo lock and already have handshake-manager: state=%v add=%v", state, add))
 		}
-	case "hostmap-pending":
-		if _, ok := state[mutexKey{Type: "hostmap", SubType: "main"}]; ok {
-			panic(fmt.Errorf("grabbing hostmap-pending lock and already have hostmap-main: state=%v add=%v", state, add))
+	case mutexKeyTypeHandshakeManager:
+		if _, ok := state[mutexKey{Type: mutexKeyTypeHostMap}]; ok {
+			panic(fmt.Errorf("grabbing handshake-manager lock and already have hostmap: state=%v add=%v", state, add))
 		}
 	}
 }