mirror of
https://github.com/tailscale/tailscale.git
synced 2025-02-18 02:48:40 +00:00
ipn, wgengine/magicsock: add ipn.Prefs.DisableDERP bool
Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
parent
bf704a5218
commit
eac62ec5ff
@ -167,8 +167,10 @@ func (b *LocalBackend) Start(opts Options) error {
|
|||||||
b.notify = opts.Notify
|
b.notify = opts.Notify
|
||||||
b.netMapCache = nil
|
b.netMapCache = nil
|
||||||
persist := b.prefs.Persist
|
persist := b.prefs.Persist
|
||||||
|
wantDERP := !b.prefs.DisableDERP
|
||||||
b.mu.Unlock()
|
b.mu.Unlock()
|
||||||
|
|
||||||
|
b.e.SetDERPEnabled(wantDERP)
|
||||||
b.updateFilter(nil)
|
b.updateFilter(nil)
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
@ -53,6 +53,9 @@ type Prefs struct {
|
|||||||
// TODO(danderson): remove?
|
// TODO(danderson): remove?
|
||||||
NotepadURLs bool
|
NotepadURLs bool
|
||||||
|
|
||||||
|
// DisableDERP prevents DERP from being used.
|
||||||
|
DisableDERP bool
|
||||||
|
|
||||||
// The Persist field is named 'Config' in the file for backward
|
// The Persist field is named 'Config' in the file for backward
|
||||||
// compatibility with earlier versions.
|
// compatibility with earlier versions.
|
||||||
// TODO(apenwarr): We should move this out of here, it's not a pref.
|
// TODO(apenwarr): We should move this out of here, it's not a pref.
|
||||||
@ -99,6 +102,7 @@ func (p *Prefs) Equals(p2 *Prefs) bool {
|
|||||||
p.CorpDNS == p2.CorpDNS &&
|
p.CorpDNS == p2.CorpDNS &&
|
||||||
p.WantRunning == p2.WantRunning &&
|
p.WantRunning == p2.WantRunning &&
|
||||||
p.NotepadURLs == p2.NotepadURLs &&
|
p.NotepadURLs == p2.NotepadURLs &&
|
||||||
|
p.DisableDERP == p2.DisableDERP &&
|
||||||
p.UsePacketFilter == p2.UsePacketFilter &&
|
p.UsePacketFilter == p2.UsePacketFilter &&
|
||||||
compareIPNets(p.AdvertiseRoutes, p2.AdvertiseRoutes) &&
|
compareIPNets(p.AdvertiseRoutes, p2.AdvertiseRoutes) &&
|
||||||
p.Persist.Equals(p2.Persist)
|
p.Persist.Equals(p2.Persist)
|
||||||
|
@ -20,7 +20,7 @@ func fieldsOf(t reflect.Type) (fields []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPrefsEqual(t *testing.T) {
|
func TestPrefsEqual(t *testing.T) {
|
||||||
prefsHandles := []string{"ControlURL", "RouteAll", "AllowSingleHosts", "CorpDNS", "WantRunning", "UsePacketFilter", "AdvertiseRoutes", "NotepadURLs", "Persist"}
|
prefsHandles := []string{"ControlURL", "RouteAll", "AllowSingleHosts", "CorpDNS", "WantRunning", "UsePacketFilter", "AdvertiseRoutes", "NotepadURLs", "DisableDERP", "Persist"}
|
||||||
if have := fieldsOf(reflect.TypeOf(Prefs{})); !reflect.DeepEqual(have, prefsHandles) {
|
if have := fieldsOf(reflect.TypeOf(Prefs{})); !reflect.DeepEqual(have, prefsHandles) {
|
||||||
t.Errorf("Prefs.Equal check might be out of sync\nfields: %q\nhandled: %q\n",
|
t.Errorf("Prefs.Equal check might be out of sync\nfields: %q\nhandled: %q\n",
|
||||||
have, prefsHandles)
|
have, prefsHandles)
|
||||||
|
@ -80,6 +80,7 @@ type Conn struct {
|
|||||||
derpRecvCh chan derpReadResult
|
derpRecvCh chan derpReadResult
|
||||||
|
|
||||||
derpMu sync.Mutex
|
derpMu sync.Mutex
|
||||||
|
wantDerp bool
|
||||||
privateKey key.Private
|
privateKey key.Private
|
||||||
myDerp int // nearest DERP server; 0 means none/unknown
|
myDerp int // nearest DERP server; 0 means none/unknown
|
||||||
derpConn map[int]*derphttp.Client // magic derp port (see derpmap.go) to its client
|
derpConn map[int]*derphttp.Client // magic derp port (see derpmap.go) to its client
|
||||||
@ -160,6 +161,7 @@ func Listen(opts Options) (*Conn, error) {
|
|||||||
epFunc: opts.endpointsFunc(),
|
epFunc: opts.endpointsFunc(),
|
||||||
logf: log.Printf,
|
logf: log.Printf,
|
||||||
addrsByUDP: make(map[udpAddr]*AddrSet),
|
addrsByUDP: make(map[udpAddr]*AddrSet),
|
||||||
|
wantDerp: true,
|
||||||
derpRecvCh: make(chan derpReadResult),
|
derpRecvCh: make(chan derpReadResult),
|
||||||
udpRecvCh: make(chan udpReadResult),
|
udpRecvCh: make(chan udpReadResult),
|
||||||
}
|
}
|
||||||
@ -263,7 +265,9 @@ func (c *Conn) updateNetInfo() {
|
|||||||
// one.
|
// one.
|
||||||
ni.PreferredDERP = c.pickDERPFallback()
|
ni.PreferredDERP = c.pickDERPFallback()
|
||||||
}
|
}
|
||||||
c.setNearestDerp(ni.PreferredDERP)
|
if !c.setNearestDERP(ni.PreferredDERP) {
|
||||||
|
ni.PreferredDERP = 0
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: set link type
|
// TODO: set link type
|
||||||
|
|
||||||
@ -327,16 +331,19 @@ func (c *Conn) SetNetInfoCallback(fn func(*tailcfg.NetInfo)) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Conn) setNearestDerp(derpNum int) (changed bool) {
|
func (c *Conn) setNearestDERP(derpNum int) (wantDERP bool) {
|
||||||
c.derpMu.Lock()
|
c.derpMu.Lock()
|
||||||
defer c.derpMu.Unlock()
|
defer c.derpMu.Unlock()
|
||||||
changed = c.myDerp != derpNum
|
if !c.wantDerp {
|
||||||
if changed && derpNum != 0 {
|
c.myDerp = 0
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if derpNum != 0 && derpNum != c.myDerp {
|
||||||
// On change, start connecting to it:
|
// On change, start connecting to it:
|
||||||
go c.derpWriteChanOfAddr(&net.UDPAddr{IP: derpMagicIP, Port: derpNum})
|
go c.derpWriteChanOfAddr(&net.UDPAddr{IP: derpMagicIP, Port: derpNum})
|
||||||
}
|
}
|
||||||
c.myDerp = derpNum
|
c.myDerp = derpNum
|
||||||
return changed
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
// determineEndpoints returns the machine's endpoint addresses. It
|
// determineEndpoints returns the machine's endpoint addresses. It
|
||||||
@ -560,7 +567,15 @@ var errDropDerpPacket = errors.New("too many DERP packets queued; dropping")
|
|||||||
// or a fake UDP address representing a DERP server (see derpmap.go).
|
// or a fake UDP address representing a DERP server (see derpmap.go).
|
||||||
// The provided public key identifies the recipient.
|
// The provided public key identifies the recipient.
|
||||||
func (c *Conn) sendAddr(addr *net.UDPAddr, pubKey key.Public, b []byte) error {
|
func (c *Conn) sendAddr(addr *net.UDPAddr, pubKey key.Public, b []byte) error {
|
||||||
if ch := c.derpWriteChanOfAddr(addr); ch != nil {
|
if !addr.IP.Equal(derpMagicIP) {
|
||||||
|
_, err := c.pconn.WriteTo(b, addr)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ch := c.derpWriteChanOfAddr(addr)
|
||||||
|
if ch == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
errc := make(chan error, 1)
|
errc := make(chan error, 1)
|
||||||
select {
|
select {
|
||||||
case <-c.donec():
|
case <-c.donec():
|
||||||
@ -577,9 +592,6 @@ func (c *Conn) sendAddr(addr *net.UDPAddr, pubKey key.Public, b []byte) error {
|
|||||||
return errDropDerpPacket
|
return errDropDerpPacket
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_, err := c.pconn.WriteTo(b, addr)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// bufferedDerpWritesBeforeDrop is how many packets writes can be
|
// bufferedDerpWritesBeforeDrop is how many packets writes can be
|
||||||
// queued up the DERP client to write on the wire before we start
|
// queued up the DERP client to write on the wire before we start
|
||||||
@ -597,6 +609,9 @@ func (c *Conn) derpWriteChanOfAddr(addr *net.UDPAddr) chan<- derpWriteRequest {
|
|||||||
}
|
}
|
||||||
c.derpMu.Lock()
|
c.derpMu.Lock()
|
||||||
defer c.derpMu.Unlock()
|
defer c.derpMu.Unlock()
|
||||||
|
if !c.wantDerp {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
if c.privateKey.IsZero() {
|
if c.privateKey.IsZero() {
|
||||||
c.logf("DERP lookup of %v with no private key; ignoring", addr.IP)
|
c.logf("DERP lookup of %v with no private key; ignoring", addr.IP)
|
||||||
return nil
|
return nil
|
||||||
@ -864,6 +879,18 @@ func (c *Conn) SetPrivateKey(privateKey wgcfg.PrivateKey) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetDERPEnabled controls whether DERP is used.
|
||||||
|
// New connections have it enabled by default.
|
||||||
|
func (c *Conn) SetDERPEnabled(wantDerp bool) {
|
||||||
|
c.derpMu.Lock()
|
||||||
|
defer c.derpMu.Unlock()
|
||||||
|
|
||||||
|
c.wantDerp = wantDerp
|
||||||
|
if !wantDerp {
|
||||||
|
c.closeAllDerpLocked()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// c.derpMu must be held.
|
// c.derpMu must be held.
|
||||||
func (c *Conn) closeAllDerpLocked() {
|
func (c *Conn) closeAllDerpLocked() {
|
||||||
for _, c := range c.derpConn {
|
for _, c := range c.derpConn {
|
||||||
|
@ -604,3 +604,7 @@ func (e *userspaceEngine) LinkChange(isExpensive bool) {
|
|||||||
func (e *userspaceEngine) SetNetInfoCallback(cb NetInfoCallback) {
|
func (e *userspaceEngine) SetNetInfoCallback(cb NetInfoCallback) {
|
||||||
e.magicConn.SetNetInfoCallback(cb)
|
e.magicConn.SetNetInfoCallback(cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *userspaceEngine) SetDERPEnabled(v bool) {
|
||||||
|
e.magicConn.SetDERPEnabled(v)
|
||||||
|
}
|
||||||
|
@ -78,6 +78,9 @@ func (e *watchdogEngine) RequestStatus() {
|
|||||||
func (e *watchdogEngine) LinkChange(isExpensive bool) {
|
func (e *watchdogEngine) LinkChange(isExpensive bool) {
|
||||||
e.watchdog("LinkChange", func() { e.wrap.LinkChange(isExpensive) })
|
e.watchdog("LinkChange", func() { e.wrap.LinkChange(isExpensive) })
|
||||||
}
|
}
|
||||||
|
func (e *watchdogEngine) SetDERPEnabled(v bool) {
|
||||||
|
e.watchdog("SetDERPEnabled", func() { e.wrap.SetDERPEnabled(v) })
|
||||||
|
}
|
||||||
func (e *watchdogEngine) Close() {
|
func (e *watchdogEngine) Close() {
|
||||||
e.watchdog("Close", e.wrap.Close)
|
e.watchdog("Close", e.wrap.Close)
|
||||||
}
|
}
|
||||||
|
@ -127,6 +127,10 @@ type Engine interface {
|
|||||||
// such as mobile data on a phone.
|
// such as mobile data on a phone.
|
||||||
LinkChange(isExpensive bool)
|
LinkChange(isExpensive bool)
|
||||||
|
|
||||||
|
// SetDERPEnabled controls whether DERP is enabled.
|
||||||
|
// It starts enabled by default.
|
||||||
|
SetDERPEnabled(bool)
|
||||||
|
|
||||||
// SetNetInfoCallback sets the function to call when a
|
// SetNetInfoCallback sets the function to call when a
|
||||||
// new NetInfo summary is available.
|
// new NetInfo summary is available.
|
||||||
SetNetInfoCallback(NetInfoCallback)
|
SetNetInfoCallback(NetInfoCallback)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user