Compare commits
1 Commits
main
...
crawshaw/d
Author | SHA1 | Date |
---|---|---|
![]() |
980badbcec |
|
@ -111,7 +111,7 @@ var derpMagicIP = net.ParseIP(DerpMagicIP).To4()
|
|||
|
||||
// activeDerp contains fields for an active DERP connection.
|
||||
type activeDerp struct {
|
||||
c *derphttp.Client
|
||||
c *derphttp.Client // Conn.derpMu must be held
|
||||
cancel context.CancelFunc
|
||||
writeCh chan<- derpWriteRequest
|
||||
lastWrite *time.Time
|
||||
|
@ -412,7 +412,9 @@ func (c *Conn) setNearestDERP(derpNum int) (wantDERP bool) {
|
|||
c.myDerp = derpNum
|
||||
c.logf("home DERP server is now %v, %v", derpNum, c.derps.ServerByID(derpNum))
|
||||
for i, ad := range c.activeDerp {
|
||||
go ad.c.NotePreferred(i == c.myDerp)
|
||||
if ad.c != nil {
|
||||
go ad.c.NotePreferred(i == c.myDerp)
|
||||
}
|
||||
}
|
||||
if derpNum != 0 && derpNum != c.myDerp {
|
||||
// On change, start connecting to it:
|
||||
|
@ -707,32 +709,51 @@ func (c *Conn) derpWriteChanOfAddr(addr *net.UDPAddr) chan<- derpWriteRequest {
|
|||
return nil
|
||||
}
|
||||
|
||||
// TODO(bradfitz): don't hold derpMu here. It's slow. Release first and use singleflight to dial+re-lock to add.
|
||||
dc, err := derphttp.NewClient(c.privateKey, "https://"+derpSrv.HostHTTPS+"/derp", c.logf)
|
||||
if err != nil {
|
||||
c.logf("derphttp.NewClient: port %d, host %q invalid? err: %v", addr.Port, derpSrv.HostHTTPS, err)
|
||||
return nil
|
||||
}
|
||||
dc.NotePreferred(c.myDerp == addr.Port)
|
||||
dc.DNSCache = dnscache.Get()
|
||||
dc.TLSConfig = c.derpTLSConfig
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ch := make(chan derpWriteRequest, bufferedDerpWritesBeforeDrop)
|
||||
|
||||
ad.c = dc
|
||||
ad.writeCh = ch
|
||||
ad.cancel = cancel
|
||||
ad.lastWrite = new(time.Time)
|
||||
c.activeDerp[addr.Port] = ad
|
||||
|
||||
go c.runDerpReader(ctx, addr, dc)
|
||||
go c.runDerpWriter(ctx, addr, dc, ch)
|
||||
go c.dialDerp(ctx, addr, &ad, ch, derpSrv)
|
||||
}
|
||||
*ad.lastWrite = time.Now()
|
||||
return ad.writeCh
|
||||
}
|
||||
|
||||
func (c *Conn) dialDerp(ctx context.Context, addr *net.UDPAddr, ad *activeDerp, ch chan derpWriteRequest, derpSrv *derpmap.Server) {
|
||||
dc, err := derphttp.NewClient(c.privateKey, "https://"+derpSrv.HostHTTPS+"/derp", c.logf)
|
||||
if err != nil {
|
||||
c.logf("derphttp.NewClient: port %d, host %q invalid? err: %v", addr.Port, derpSrv.HostHTTPS, err)
|
||||
|
||||
c.derpMu.Lock()
|
||||
if ctx.Err() == nil {
|
||||
ad.cancel()
|
||||
delete(c.activeDerp, addr.Port)
|
||||
}
|
||||
c.derpMu.Unlock()
|
||||
|
||||
return
|
||||
}
|
||||
dc.NotePreferred(c.myDerp == addr.Port)
|
||||
dc.DNSCache = dnscache.Get()
|
||||
dc.TLSConfig = c.derpTLSConfig
|
||||
|
||||
c.derpMu.Lock()
|
||||
if ctx.Err() != nil {
|
||||
// Some other dialDerp beat us to the punch.
|
||||
c.derpMu.Unlock()
|
||||
dc.Close()
|
||||
return
|
||||
}
|
||||
ad.c = dc
|
||||
c.activeDerp[addr.Port] = *ad
|
||||
c.derpMu.Unlock()
|
||||
|
||||
go c.runDerpReader(ctx, addr, dc)
|
||||
go c.runDerpWriter(ctx, addr, dc, ch)
|
||||
}
|
||||
|
||||
// derpReadResult is the type sent by runDerpClient to ReceiveIPv4
|
||||
// when a DERP packet is available.
|
||||
//
|
||||
|
@ -1035,7 +1056,9 @@ func (c *Conn) closeAllDerpLocked() {
|
|||
func (c *Conn) closeDerpLocked(node int) {
|
||||
if ad, ok := c.activeDerp[node]; ok {
|
||||
c.logf("closing connection to derp%v", node)
|
||||
go ad.c.Close()
|
||||
if ad.c != nil {
|
||||
go ad.c.Close()
|
||||
}
|
||||
ad.cancel()
|
||||
delete(c.activeDerp, node)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue