@ -109,13 +109,14 @@ type userspaceEngine struct {
sentActivityAt map [ packet . IP ] * int64 // value is atomic int64 of unixtime
sentActivityAt map [ packet . IP ] * int64 // value is atomic int64 of unixtime
destIPActivityFuncs map [ packet . IP ] func ( )
destIPActivityFuncs map [ packet . IP ] func ( )
mu sync . Mutex // guards following; see lock order comment below
mu sync . Mutex // guards following; see lock order comment below
closing bool // Close was called (even if we're still closing)
closing bool // Close was called (even if we're still closing)
statusCallback StatusCallback
statusCallback StatusCallback
peerSequence [ ] wgcfg . Key
linkChangeCallback func ( major bool , newState * interfaces . State )
endpoints [ ] string
peerSequence [ ] wgcfg . Key
pingers map [ wgcfg . Key ] * pinger // legacy pingers for pre-discovery peers
endpoints [ ] string
linkState * interfaces . State
pingers map [ wgcfg . Key ] * pinger // legacy pingers for pre-discovery peers
linkState * interfaces . State
// Lock ordering: magicsock.Conn.mu, wgLock, then mu.
// Lock ordering: magicsock.Conn.mu, wgLock, then mu.
}
}
@ -1110,15 +1111,15 @@ func (e *userspaceEngine) Wait() {
<- e . waitCh
<- e . waitCh
}
}
func ( e * userspaceEngine ) setLinkState ( st * interfaces . State ) ( changed bool ) {
func ( e * userspaceEngine ) setLinkState ( st * interfaces . State ) ( changed bool , cb func ( major bool , newState * interfaces . State ) ) {
if st == nil {
if st == nil {
return false
return false , nil
}
}
e . mu . Lock ( )
e . mu . Lock ( )
defer e . mu . Unlock ( )
defer e . mu . Unlock ( )
changed = e . linkState == nil || ! st . Equal ( e . linkState )
changed = e . linkState == nil || ! st . Equal ( e . linkState )
e . linkState = st
e . linkState = st
return changed
return changed , e . linkChangeCallback
}
}
func ( e * userspaceEngine ) LinkChange ( isExpensive bool ) {
func ( e * userspaceEngine ) LinkChange ( isExpensive bool ) {
@ -1128,7 +1129,7 @@ func (e *userspaceEngine) LinkChange(isExpensive bool) {
return
return
}
}
cur . IsExpensive = isExpensive
cur . IsExpensive = isExpensive
needRebind := e . setLinkState ( cur )
needRebind , linkChangeCallback := e . setLinkState ( cur )
if needRebind {
if needRebind {
e . logf ( "LinkChange: major, rebinding. New state: %+v" , cur )
e . logf ( "LinkChange: major, rebinding. New state: %+v" , cur )
@ -1142,6 +1143,15 @@ func (e *userspaceEngine) LinkChange(isExpensive bool) {
e . magicConn . Rebind ( )
e . magicConn . Rebind ( )
}
}
e . magicConn . ReSTUN ( why )
e . magicConn . ReSTUN ( why )
if linkChangeCallback != nil {
go linkChangeCallback ( needRebind , cur )
}
}
func ( e * userspaceEngine ) SetLinkChangeCallback ( cb func ( major bool , newState * interfaces . State ) ) {
e . mu . Lock ( )
defer e . mu . Unlock ( )
e . linkChangeCallback = cb
}
}
func getLinkState ( ) ( * interfaces . State , error ) {
func getLinkState ( ) ( * interfaces . State , error ) {