mirror of
https://github.com/tailscale/tailscale.git
synced 2025-10-28 13:10:02 +00:00
net/netmon: remove usage of direct callbacks from netmon (#17292)
The callback itself is not removed as it is used in other repos, making it simpler for those to slowly transition to the eventbus. Updates #15160 Signed-off-by: Claus Lensbøl <claus@tailscale.com>
This commit is contained in:
@@ -104,14 +104,10 @@ func runMonitor(ctx context.Context, loop bool) error {
|
|||||||
}
|
}
|
||||||
defer mon.Close()
|
defer mon.Close()
|
||||||
|
|
||||||
mon.RegisterChangeCallback(func(delta *netmon.ChangeDelta) {
|
eventClient := b.Client("debug.runMonitor")
|
||||||
if !delta.Major {
|
m := eventClient.Monitor(changeDeltaWatcher(eventClient, ctx, dump))
|
||||||
log.Printf("Network monitor fired; not a major change")
|
defer m.Close()
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Printf("Network monitor fired. New state:")
|
|
||||||
dump(delta.New)
|
|
||||||
})
|
|
||||||
if loop {
|
if loop {
|
||||||
log.Printf("Starting link change monitor; initial state:")
|
log.Printf("Starting link change monitor; initial state:")
|
||||||
}
|
}
|
||||||
@@ -124,6 +120,27 @@ func runMonitor(ctx context.Context, loop bool) error {
|
|||||||
select {}
|
select {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func changeDeltaWatcher(ec *eventbus.Client, ctx context.Context, dump func(st *netmon.State)) func(*eventbus.Client) {
|
||||||
|
changeSub := eventbus.Subscribe[netmon.ChangeDelta](ec)
|
||||||
|
return func(ec *eventbus.Client) {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
case <-ec.Done():
|
||||||
|
return
|
||||||
|
case delta := <-changeSub.Events():
|
||||||
|
if !delta.Major {
|
||||||
|
log.Printf("Network monitor fired; not a major change")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Printf("Network monitor fired. New state:")
|
||||||
|
dump(delta.New)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func getURL(ctx context.Context, urlStr string) error {
|
func getURL(ctx context.Context, urlStr string) error {
|
||||||
if urlStr == "login" {
|
if urlStr == "login" {
|
||||||
urlStr = "https://login.tailscale.com"
|
urlStr = "https://login.tailscale.com"
|
||||||
|
|||||||
@@ -433,7 +433,13 @@ func run() (err error) {
|
|||||||
|
|
||||||
var publicLogID logid.PublicID
|
var publicLogID logid.PublicID
|
||||||
if buildfeatures.HasLogTail {
|
if buildfeatures.HasLogTail {
|
||||||
pol := logpolicy.New(logtail.CollectionNode, netMon, sys.HealthTracker.Get(), nil /* use log.Printf */)
|
|
||||||
|
pol := logpolicy.Options{
|
||||||
|
Collection: logtail.CollectionNode,
|
||||||
|
NetMon: netMon,
|
||||||
|
Health: sys.HealthTracker.Get(),
|
||||||
|
Bus: sys.Bus.Get(),
|
||||||
|
}.New()
|
||||||
pol.SetVerbosityLevel(args.verbose)
|
pol.SetVerbosityLevel(args.verbose)
|
||||||
publicLogID = pol.PublicID
|
publicLogID = pol.PublicID
|
||||||
logPol = pol
|
logPol = pol
|
||||||
@@ -470,7 +476,7 @@ func run() (err error) {
|
|||||||
// Always clean up, even if we're going to run the server. This covers cases
|
// Always clean up, even if we're going to run the server. This covers cases
|
||||||
// such as when a system was rebooted without shutting down, or tailscaled
|
// such as when a system was rebooted without shutting down, or tailscaled
|
||||||
// crashed, and would for example restore system DNS configuration.
|
// crashed, and would for example restore system DNS configuration.
|
||||||
dns.CleanUp(logf, netMon, sys.HealthTracker.Get(), args.tunname)
|
dns.CleanUp(logf, netMon, sys.Bus.Get(), sys.HealthTracker.Get(), args.tunname)
|
||||||
router.CleanUp(logf, netMon, args.tunname)
|
router.CleanUp(logf, netMon, args.tunname)
|
||||||
// If the cleanUp flag was passed, then exit.
|
// If the cleanUp flag was passed, then exit.
|
||||||
if args.cleanUp {
|
if args.cleanUp {
|
||||||
@@ -616,6 +622,7 @@ func getLocalBackend(ctx context.Context, logf logger.Logf, logID logid.PublicID
|
|||||||
}
|
}
|
||||||
|
|
||||||
dialer := &tsdial.Dialer{Logf: logf} // mutated below (before used)
|
dialer := &tsdial.Dialer{Logf: logf} // mutated below (before used)
|
||||||
|
dialer.SetBus(sys.Bus.Get())
|
||||||
sys.Set(dialer)
|
sys.Set(dialer)
|
||||||
|
|
||||||
onlyNetstack, err := createEngine(logf, sys)
|
onlyNetstack, err := createEngine(logf, sys)
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ func newIPN(jsConfig js.Value) map[string]any {
|
|||||||
sys := tsd.NewSystem()
|
sys := tsd.NewSystem()
|
||||||
sys.Set(store)
|
sys.Set(store)
|
||||||
dialer := &tsdial.Dialer{Logf: logf}
|
dialer := &tsdial.Dialer{Logf: logf}
|
||||||
|
dialer.SetBus(sys.Bus.Get())
|
||||||
eng, err := wgengine.NewUserspaceEngine(logf, wgengine.Config{
|
eng, err := wgengine.NewUserspaceEngine(logf, wgengine.Config{
|
||||||
Dialer: dialer,
|
Dialer: dialer,
|
||||||
SetSubsystem: sys.Set,
|
SetSubsystem: sys.Set,
|
||||||
@@ -463,7 +464,6 @@ func (s *jsSSHSession) Run() {
|
|||||||
cols = s.pendingResizeCols
|
cols = s.pendingResizeCols
|
||||||
}
|
}
|
||||||
err = session.RequestPty("xterm", rows, cols, ssh.TerminalModes{})
|
err = session.RequestPty("xterm", rows, cols, ssh.TerminalModes{})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
writeError("Pseudo Terminal", err)
|
writeError("Pseudo Terminal", err)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -223,6 +223,7 @@ func TestDirectProxyManual(t *testing.T) {
|
|||||||
|
|
||||||
dialer := &tsdial.Dialer{}
|
dialer := &tsdial.Dialer{}
|
||||||
dialer.SetNetMon(netmon.NewStatic())
|
dialer.SetNetMon(netmon.NewStatic())
|
||||||
|
dialer.SetBus(bus)
|
||||||
|
|
||||||
opts := Options{
|
opts := Options{
|
||||||
Persist: persist.Persist{},
|
Persist: persist.Persist{},
|
||||||
@@ -300,6 +301,7 @@ func testHTTPS(t *testing.T, withProxy bool) {
|
|||||||
|
|
||||||
dialer := &tsdial.Dialer{}
|
dialer := &tsdial.Dialer{}
|
||||||
dialer.SetNetMon(netmon.NewStatic())
|
dialer.SetNetMon(netmon.NewStatic())
|
||||||
|
dialer.SetBus(bus)
|
||||||
dialer.SetSystemDialerForTest(func(ctx context.Context, network, addr string) (net.Conn, error) {
|
dialer.SetSystemDialerForTest(func(ctx context.Context, network, addr string) (net.Conn, error) {
|
||||||
host, _, err := net.SplitHostPort(addr)
|
host, _, err := net.SplitHostPort(addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -27,13 +27,15 @@ func TestNewDirect(t *testing.T) {
|
|||||||
bus := eventbustest.NewBus(t)
|
bus := eventbustest.NewBus(t)
|
||||||
|
|
||||||
k := key.NewMachine()
|
k := key.NewMachine()
|
||||||
|
dialer := tsdial.NewDialer(netmon.NewStatic())
|
||||||
|
dialer.SetBus(bus)
|
||||||
opts := Options{
|
opts := Options{
|
||||||
ServerURL: "https://example.com",
|
ServerURL: "https://example.com",
|
||||||
Hostinfo: hi,
|
Hostinfo: hi,
|
||||||
GetMachinePrivateKey: func() (key.MachinePrivate, error) {
|
GetMachinePrivateKey: func() (key.MachinePrivate, error) {
|
||||||
return k, nil
|
return k, nil
|
||||||
},
|
},
|
||||||
Dialer: tsdial.NewDialer(netmon.NewStatic()),
|
Dialer: dialer,
|
||||||
Bus: bus,
|
Bus: bus,
|
||||||
}
|
}
|
||||||
c, err := NewDirect(opts)
|
c, err := NewDirect(opts)
|
||||||
@@ -105,13 +107,15 @@ func TestTsmpPing(t *testing.T) {
|
|||||||
bus := eventbustest.NewBus(t)
|
bus := eventbustest.NewBus(t)
|
||||||
|
|
||||||
k := key.NewMachine()
|
k := key.NewMachine()
|
||||||
|
dialer := tsdial.NewDialer(netmon.NewStatic())
|
||||||
|
dialer.SetBus(bus)
|
||||||
opts := Options{
|
opts := Options{
|
||||||
ServerURL: "https://example.com",
|
ServerURL: "https://example.com",
|
||||||
Hostinfo: hi,
|
Hostinfo: hi,
|
||||||
GetMachinePrivateKey: func() (key.MachinePrivate, error) {
|
GetMachinePrivateKey: func() (key.MachinePrivate, error) {
|
||||||
return k, nil
|
return k, nil
|
||||||
},
|
},
|
||||||
Dialer: tsdial.NewDialer(netmon.NewStatic()),
|
Dialer: dialer,
|
||||||
Bus: bus,
|
Bus: bus,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import (
|
|||||||
"tailscale.com/tstest/nettest"
|
"tailscale.com/tstest/nettest"
|
||||||
"tailscale.com/types/key"
|
"tailscale.com/types/key"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
|
"tailscale.com/util/eventbus/eventbustest"
|
||||||
)
|
)
|
||||||
|
|
||||||
// maxAllowedNoiseVersion is the highest we expect the Tailscale
|
// maxAllowedNoiseVersion is the highest we expect the Tailscale
|
||||||
@@ -175,6 +176,7 @@ func (tt noiseClientTest) run(t *testing.T) {
|
|||||||
serverPrivate := key.NewMachine()
|
serverPrivate := key.NewMachine()
|
||||||
clientPrivate := key.NewMachine()
|
clientPrivate := key.NewMachine()
|
||||||
chalPrivate := key.NewChallenge()
|
chalPrivate := key.NewChallenge()
|
||||||
|
bus := eventbustest.NewBus(t)
|
||||||
|
|
||||||
const msg = "Hello, client"
|
const msg = "Hello, client"
|
||||||
h2 := &http2.Server{}
|
h2 := &http2.Server{}
|
||||||
@@ -194,6 +196,7 @@ func (tt noiseClientTest) run(t *testing.T) {
|
|||||||
defer hs.Close()
|
defer hs.Close()
|
||||||
|
|
||||||
dialer := tsdial.NewDialer(netmon.NewStatic())
|
dialer := tsdial.NewDialer(netmon.NewStatic())
|
||||||
|
dialer.SetBus(bus)
|
||||||
if nettest.PreferMemNetwork() {
|
if nettest.PreferMemNetwork() {
|
||||||
dialer.SetSystemDialerForTest(nw.Dial)
|
dialer.SetSystemDialerForTest(nw.Dial)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,6 +149,8 @@ func testControlHTTP(t *testing.T, param httpTestParam) {
|
|||||||
proxy := param.proxy
|
proxy := param.proxy
|
||||||
client, server := key.NewMachine(), key.NewMachine()
|
client, server := key.NewMachine(), key.NewMachine()
|
||||||
|
|
||||||
|
bus := eventbustest.NewBus(t)
|
||||||
|
|
||||||
const testProtocolVersion = 1
|
const testProtocolVersion = 1
|
||||||
const earlyWriteMsg = "Hello, world!"
|
const earlyWriteMsg = "Hello, world!"
|
||||||
sch := make(chan serverResult, 1)
|
sch := make(chan serverResult, 1)
|
||||||
@@ -218,6 +220,7 @@ func testControlHTTP(t *testing.T, param httpTestParam) {
|
|||||||
|
|
||||||
netMon := netmon.NewStatic()
|
netMon := netmon.NewStatic()
|
||||||
dialer := tsdial.NewDialer(netMon)
|
dialer := tsdial.NewDialer(netMon)
|
||||||
|
dialer.SetBus(bus)
|
||||||
a := &Dialer{
|
a := &Dialer{
|
||||||
Hostname: "localhost",
|
Hostname: "localhost",
|
||||||
HTTPPort: strconv.Itoa(httpLn.Addr().(*net.TCPAddr).Port),
|
HTTPPort: strconv.Itoa(httpLn.Addr().(*net.TCPAddr).Port),
|
||||||
@@ -775,7 +778,7 @@ func runDialPlanTest(t *testing.T, plan *tailcfg.ControlDialPlan, want []netip.A
|
|||||||
if allowFallback {
|
if allowFallback {
|
||||||
host = fallbackAddr.String()
|
host = fallbackAddr.String()
|
||||||
}
|
}
|
||||||
|
bus := eventbustest.NewBus(t)
|
||||||
a := &Dialer{
|
a := &Dialer{
|
||||||
Hostname: host,
|
Hostname: host,
|
||||||
HTTPPort: httpPort,
|
HTTPPort: httpPort,
|
||||||
@@ -790,7 +793,7 @@ func runDialPlanTest(t *testing.T, plan *tailcfg.ControlDialPlan, want []netip.A
|
|||||||
omitCertErrorLogging: true,
|
omitCertErrorLogging: true,
|
||||||
testFallbackDelay: 50 * time.Millisecond,
|
testFallbackDelay: 50 * time.Millisecond,
|
||||||
Clock: clock,
|
Clock: clock,
|
||||||
HealthTracker: health.NewTracker(eventbustest.NewBus(t)),
|
HealthTracker: health.NewTracker(bus),
|
||||||
}
|
}
|
||||||
|
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
|
|||||||
@@ -526,7 +526,7 @@ func NewLocalBackend(logf logger.Logf, logID logid.PublicID, sys *tsd.System, lo
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
netMon := sys.NetMon.Get()
|
netMon := sys.NetMon.Get()
|
||||||
b.sockstatLogger, err = sockstatlog.NewLogger(logpolicy.LogsDir(logf), logf, logID, netMon, sys.HealthTracker.Get())
|
b.sockstatLogger, err = sockstatlog.NewLogger(logpolicy.LogsDir(logf), logf, logID, netMon, sys.HealthTracker.Get(), sys.Bus.Get())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("error setting up sockstat logger: %v", err)
|
log.Printf("error setting up sockstat logger: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -480,7 +480,9 @@ func newTestLocalBackendWithSys(t testing.TB, sys *tsd.System) *LocalBackend {
|
|||||||
t.Log("Added fake userspace engine for testing")
|
t.Log("Added fake userspace engine for testing")
|
||||||
}
|
}
|
||||||
if _, ok := sys.Dialer.GetOK(); !ok {
|
if _, ok := sys.Dialer.GetOK(); !ok {
|
||||||
sys.Set(tsdial.NewDialer(netmon.NewStatic()))
|
dialer := tsdial.NewDialer(netmon.NewStatic())
|
||||||
|
dialer.SetBus(sys.Bus.Get())
|
||||||
|
sys.Set(dialer)
|
||||||
t.Log("Added static dialer for testing")
|
t.Log("Added static dialer for testing")
|
||||||
}
|
}
|
||||||
lb, err := NewLocalBackend(logf, logid.PublicID{}, sys, 0)
|
lb, err := NewLocalBackend(logf, logid.PublicID{}, sys, 0)
|
||||||
@@ -3108,12 +3110,14 @@ func TestAutoExitNodeSetNetInfoCallback(t *testing.T) {
|
|||||||
b.hostinfo = hi
|
b.hostinfo = hi
|
||||||
k := key.NewMachine()
|
k := key.NewMachine()
|
||||||
var cc *mockControl
|
var cc *mockControl
|
||||||
|
dialer := tsdial.NewDialer(netmon.NewStatic())
|
||||||
|
dialer.SetBus(sys.Bus.Get())
|
||||||
opts := controlclient.Options{
|
opts := controlclient.Options{
|
||||||
ServerURL: "https://example.com",
|
ServerURL: "https://example.com",
|
||||||
GetMachinePrivateKey: func() (key.MachinePrivate, error) {
|
GetMachinePrivateKey: func() (key.MachinePrivate, error) {
|
||||||
return k, nil
|
return k, nil
|
||||||
},
|
},
|
||||||
Dialer: tsdial.NewDialer(netmon.NewStatic()),
|
Dialer: dialer,
|
||||||
Logf: b.logf,
|
Logf: b.logf,
|
||||||
PolicyClient: polc,
|
PolicyClient: polc,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,6 +54,8 @@ func fakeControlClient(t *testing.T, c *http.Client) (*controlclient.Auto, *even
|
|||||||
bus := eventbustest.NewBus(t)
|
bus := eventbustest.NewBus(t)
|
||||||
|
|
||||||
k := key.NewMachine()
|
k := key.NewMachine()
|
||||||
|
dialer := tsdial.NewDialer(netmon.NewStatic())
|
||||||
|
dialer.SetBus(bus)
|
||||||
opts := controlclient.Options{
|
opts := controlclient.Options{
|
||||||
ServerURL: "https://example.com",
|
ServerURL: "https://example.com",
|
||||||
Hostinfo: hi,
|
Hostinfo: hi,
|
||||||
@@ -63,7 +65,7 @@ func fakeControlClient(t *testing.T, c *http.Client) (*controlclient.Auto, *even
|
|||||||
HTTPTestClient: c,
|
HTTPTestClient: c,
|
||||||
NoiseTestClient: c,
|
NoiseTestClient: c,
|
||||||
Observer: observerFunc(func(controlclient.Status) {}),
|
Observer: observerFunc(func(controlclient.Status) {}),
|
||||||
Dialer: tsdial.NewDialer(netmon.NewStatic()),
|
Dialer: dialer,
|
||||||
Bus: bus,
|
Bus: bus,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1668,6 +1668,7 @@ func newLocalBackendWithMockEngineAndControl(t *testing.T, enableLogging bool) (
|
|||||||
sys := tsd.NewSystemWithBus(bus)
|
sys := tsd.NewSystemWithBus(bus)
|
||||||
sys.Set(dialer)
|
sys.Set(dialer)
|
||||||
sys.Set(dialer.NetMon())
|
sys.Set(dialer.NetMon())
|
||||||
|
dialer.SetBus(bus)
|
||||||
|
|
||||||
magicConn, err := magicsock.NewConn(magicsock.Options{
|
magicConn, err := magicsock.NewConn(magicsock.Options{
|
||||||
Logf: logf,
|
Logf: logf,
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import (
|
|||||||
"tailscale.com/net/sockstats"
|
"tailscale.com/net/sockstats"
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/types/logid"
|
"tailscale.com/types/logid"
|
||||||
|
"tailscale.com/util/eventbus"
|
||||||
"tailscale.com/util/mak"
|
"tailscale.com/util/mak"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -97,7 +98,7 @@ func SockstatLogID(logID logid.PublicID) logid.PrivateID {
|
|||||||
//
|
//
|
||||||
// The netMon parameter is optional. It should be specified in environments where
|
// The netMon parameter is optional. It should be specified in environments where
|
||||||
// Tailscaled is manipulating the routing table.
|
// Tailscaled is manipulating the routing table.
|
||||||
func NewLogger(logdir string, logf logger.Logf, logID logid.PublicID, netMon *netmon.Monitor, health *health.Tracker) (*Logger, error) {
|
func NewLogger(logdir string, logf logger.Logf, logID logid.PublicID, netMon *netmon.Monitor, health *health.Tracker, bus *eventbus.Bus) (*Logger, error) {
|
||||||
if !sockstats.IsAvailable || !buildfeatures.HasLogTail {
|
if !sockstats.IsAvailable || !buildfeatures.HasLogTail {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
@@ -127,6 +128,7 @@ func NewLogger(logdir string, logf logger.Logf, logID logid.PublicID, netMon *ne
|
|||||||
PrivateID: SockstatLogID(logID),
|
PrivateID: SockstatLogID(logID),
|
||||||
Collection: "sockstats.log.tailscale.io",
|
Collection: "sockstats.log.tailscale.io",
|
||||||
Buffer: filch,
|
Buffer: filch,
|
||||||
|
Bus: bus,
|
||||||
CompressLogs: true,
|
CompressLogs: true,
|
||||||
FlushDelayFn: func() time.Duration {
|
FlushDelayFn: func() time.Duration {
|
||||||
// set flush delay to 100 years so it never flushes automatically
|
// set flush delay to 100 years so it never flushes automatically
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ func TestResourceCleanup(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
lg, err := NewLogger(td, logger.Discard, id.Public(), nil, nil)
|
lg, err := NewLogger(td, logger.Discard, id.Public(), nil, nil, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ import (
|
|||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/types/logid"
|
"tailscale.com/types/logid"
|
||||||
"tailscale.com/util/clientmetric"
|
"tailscale.com/util/clientmetric"
|
||||||
|
"tailscale.com/util/eventbus"
|
||||||
"tailscale.com/util/must"
|
"tailscale.com/util/must"
|
||||||
"tailscale.com/util/racebuild"
|
"tailscale.com/util/racebuild"
|
||||||
"tailscale.com/util/syspolicy/pkey"
|
"tailscale.com/util/syspolicy/pkey"
|
||||||
@@ -489,6 +490,11 @@ type Options struct {
|
|||||||
// If non-nil, it's used to construct the default HTTP client.
|
// If non-nil, it's used to construct the default HTTP client.
|
||||||
Health *health.Tracker
|
Health *health.Tracker
|
||||||
|
|
||||||
|
// Bus is an optional parameter for communication on the eventbus.
|
||||||
|
// If non-nil, it's passed to logtail for use in interface monitoring.
|
||||||
|
// TODO(cmol): Make this non-optional when it's plumbed in by the clients.
|
||||||
|
Bus *eventbus.Bus
|
||||||
|
|
||||||
// Logf is an optional logger to use.
|
// Logf is an optional logger to use.
|
||||||
// If nil, [log.Printf] will be used instead.
|
// If nil, [log.Printf] will be used instead.
|
||||||
Logf logger.Logf
|
Logf logger.Logf
|
||||||
@@ -615,6 +621,7 @@ func (opts Options) init(disableLogging bool) (*logtail.Config, *Policy) {
|
|||||||
Stderr: logWriter{console},
|
Stderr: logWriter{console},
|
||||||
CompressLogs: true,
|
CompressLogs: true,
|
||||||
MaxUploadSize: opts.MaxUploadSize,
|
MaxUploadSize: opts.MaxUploadSize,
|
||||||
|
Bus: opts.Bus,
|
||||||
}
|
}
|
||||||
if opts.Collection == logtail.CollectionNode {
|
if opts.Collection == logtail.CollectionNode {
|
||||||
conf.MetricsDelta = clientmetric.EncodeLogTailMetricsDelta
|
conf.MetricsDelta = clientmetric.EncodeLogTailMetricsDelta
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
"tailscale.com/tstime"
|
"tailscale.com/tstime"
|
||||||
"tailscale.com/types/logid"
|
"tailscale.com/types/logid"
|
||||||
|
"tailscale.com/util/eventbus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DefaultHost is the default host name to upload logs to when
|
// DefaultHost is the default host name to upload logs to when
|
||||||
@@ -34,6 +35,7 @@ type Config struct {
|
|||||||
LowMemory bool // if true, logtail minimizes memory use
|
LowMemory bool // if true, logtail minimizes memory use
|
||||||
Clock tstime.Clock // if set, Clock.Now substitutes uses of time.Now
|
Clock tstime.Clock // if set, Clock.Now substitutes uses of time.Now
|
||||||
Stderr io.Writer // if set, logs are sent here instead of os.Stderr
|
Stderr io.Writer // if set, logs are sent here instead of os.Stderr
|
||||||
|
Bus *eventbus.Bus // if set, uses the eventbus for awaitInternetUp instead of callback
|
||||||
StderrLevel int // max verbosity level to write to stderr; 0 means the non-verbose messages only
|
StderrLevel int // max verbosity level to write to stderr; 0 means the non-verbose messages only
|
||||||
Buffer Buffer // temp storage, if nil a MemoryBuffer
|
Buffer Buffer // temp storage, if nil a MemoryBuffer
|
||||||
CompressLogs bool // whether to compress the log uploads
|
CompressLogs bool // whether to compress the log uploads
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import (
|
|||||||
"tailscale.com/tstime"
|
"tailscale.com/tstime"
|
||||||
tslogger "tailscale.com/types/logger"
|
tslogger "tailscale.com/types/logger"
|
||||||
"tailscale.com/types/logid"
|
"tailscale.com/types/logid"
|
||||||
|
"tailscale.com/util/eventbus"
|
||||||
"tailscale.com/util/set"
|
"tailscale.com/util/set"
|
||||||
"tailscale.com/util/truncate"
|
"tailscale.com/util/truncate"
|
||||||
"tailscale.com/util/zstdframe"
|
"tailscale.com/util/zstdframe"
|
||||||
@@ -120,6 +121,10 @@ func NewLogger(cfg Config, logf tslogger.Logf) *Logger {
|
|||||||
shutdownStart: make(chan struct{}),
|
shutdownStart: make(chan struct{}),
|
||||||
shutdownDone: make(chan struct{}),
|
shutdownDone: make(chan struct{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cfg.Bus != nil {
|
||||||
|
l.eventClient = cfg.Bus.Client("logtail.Logger")
|
||||||
|
}
|
||||||
l.SetSockstatsLabel(sockstats.LabelLogtailLogger)
|
l.SetSockstatsLabel(sockstats.LabelLogtailLogger)
|
||||||
l.compressLogs = cfg.CompressLogs
|
l.compressLogs = cfg.CompressLogs
|
||||||
|
|
||||||
@@ -156,6 +161,7 @@ type Logger struct {
|
|||||||
privateID logid.PrivateID
|
privateID logid.PrivateID
|
||||||
httpDoCalls atomic.Int32
|
httpDoCalls atomic.Int32
|
||||||
sockstatsLabel atomicSocktatsLabel
|
sockstatsLabel atomicSocktatsLabel
|
||||||
|
eventClient *eventbus.Client
|
||||||
|
|
||||||
procID uint32
|
procID uint32
|
||||||
includeProcSequence bool
|
includeProcSequence bool
|
||||||
@@ -221,6 +227,9 @@ func (l *Logger) Shutdown(ctx context.Context) error {
|
|||||||
l.httpc.CloseIdleConnections()
|
l.httpc.CloseIdleConnections()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
if l.eventClient != nil {
|
||||||
|
l.eventClient.Close()
|
||||||
|
}
|
||||||
l.shutdownStartMu.Lock()
|
l.shutdownStartMu.Lock()
|
||||||
select {
|
select {
|
||||||
case <-l.shutdownStart:
|
case <-l.shutdownStart:
|
||||||
@@ -417,6 +426,10 @@ func (l *Logger) internetUp() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *Logger) awaitInternetUp(ctx context.Context) {
|
func (l *Logger) awaitInternetUp(ctx context.Context) {
|
||||||
|
if l.eventClient != nil {
|
||||||
|
l.awaitInternetUpBus(ctx)
|
||||||
|
return
|
||||||
|
}
|
||||||
upc := make(chan bool, 1)
|
upc := make(chan bool, 1)
|
||||||
defer l.netMonitor.RegisterChangeCallback(func(delta *netmon.ChangeDelta) {
|
defer l.netMonitor.RegisterChangeCallback(func(delta *netmon.ChangeDelta) {
|
||||||
if delta.New.AnyInterfaceUp() {
|
if delta.New.AnyInterfaceUp() {
|
||||||
@@ -436,6 +449,24 @@ func (l *Logger) awaitInternetUp(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (l *Logger) awaitInternetUpBus(ctx context.Context) {
|
||||||
|
if l.internetUp() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sub := eventbus.Subscribe[netmon.ChangeDelta](l.eventClient)
|
||||||
|
defer sub.Close()
|
||||||
|
select {
|
||||||
|
case delta := <-sub.Events():
|
||||||
|
if delta.New.AnyInterfaceUp() {
|
||||||
|
fmt.Fprintf(l.stderr, "logtail: internet back up\n")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Fprintf(l.stderr, "logtail: network changed, but is not up")
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// upload uploads body to the log server.
|
// upload uploads body to the log server.
|
||||||
// origlen indicates the pre-compression body length.
|
// origlen indicates the pre-compression body length.
|
||||||
// origlen of -1 indicates that the body is not compressed.
|
// origlen of -1 indicates that the body is not compressed.
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import (
|
|||||||
"github.com/go-json-experiment/json/jsontext"
|
"github.com/go-json-experiment/json/jsontext"
|
||||||
"tailscale.com/tstest"
|
"tailscale.com/tstest"
|
||||||
"tailscale.com/tstime"
|
"tailscale.com/tstime"
|
||||||
|
"tailscale.com/util/eventbus/eventbustest"
|
||||||
"tailscale.com/util/must"
|
"tailscale.com/util/must"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -30,6 +31,7 @@ func TestFastShutdown(t *testing.T) {
|
|||||||
|
|
||||||
l := NewLogger(Config{
|
l := NewLogger(Config{
|
||||||
BaseURL: testServ.URL,
|
BaseURL: testServ.URL,
|
||||||
|
Bus: eventbustest.NewBus(t),
|
||||||
}, t.Logf)
|
}, t.Logf)
|
||||||
err := l.Shutdown(ctx)
|
err := l.Shutdown(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -62,7 +64,10 @@ func NewLogtailTestHarness(t *testing.T) (*LogtailTestServer, *Logger) {
|
|||||||
|
|
||||||
t.Cleanup(ts.srv.Close)
|
t.Cleanup(ts.srv.Close)
|
||||||
|
|
||||||
l := NewLogger(Config{BaseURL: ts.srv.URL}, t.Logf)
|
l := NewLogger(Config{
|
||||||
|
BaseURL: ts.srv.URL,
|
||||||
|
Bus: eventbustest.NewBus(t),
|
||||||
|
}, t.Logf)
|
||||||
|
|
||||||
// There is always an initial "logtail started" message
|
// There is always an initial "logtail started" message
|
||||||
body := <-ts.uploaded
|
body := <-ts.uploaded
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import (
|
|||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/util/clientmetric"
|
"tailscale.com/util/clientmetric"
|
||||||
"tailscale.com/util/dnsname"
|
"tailscale.com/util/dnsname"
|
||||||
|
"tailscale.com/util/eventbus"
|
||||||
"tailscale.com/util/slicesx"
|
"tailscale.com/util/slicesx"
|
||||||
"tailscale.com/util/syspolicy/policyclient"
|
"tailscale.com/util/syspolicy/policyclient"
|
||||||
)
|
)
|
||||||
@@ -600,7 +601,7 @@ func (m *Manager) FlushCaches() error {
|
|||||||
// No other state needs to be instantiated before this runs.
|
// No other state needs to be instantiated before this runs.
|
||||||
//
|
//
|
||||||
// health must not be nil
|
// health must not be nil
|
||||||
func CleanUp(logf logger.Logf, netMon *netmon.Monitor, health *health.Tracker, interfaceName string) {
|
func CleanUp(logf logger.Logf, netMon *netmon.Monitor, bus *eventbus.Bus, health *health.Tracker, interfaceName string) {
|
||||||
if !buildfeatures.HasDNS {
|
if !buildfeatures.HasDNS {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -611,6 +612,7 @@ func CleanUp(logf logger.Logf, netMon *netmon.Monitor, health *health.Tracker, i
|
|||||||
}
|
}
|
||||||
d := &tsdial.Dialer{Logf: logf}
|
d := &tsdial.Dialer{Logf: logf}
|
||||||
d.SetNetMon(netMon)
|
d.SetNetMon(netMon)
|
||||||
|
d.SetBus(bus)
|
||||||
dns := NewManager(logf, oscfg, health, d, nil, nil, runtime.GOOS)
|
dns := NewManager(logf, oscfg, health, d, nil, nil, runtime.GOOS)
|
||||||
if err := dns.Down(); err != nil {
|
if err := dns.Down(); err != nil {
|
||||||
logf("dns down: %v", err)
|
logf("dns down: %v", err)
|
||||||
|
|||||||
@@ -90,7 +90,10 @@ func TestDNSOverTCP(t *testing.T) {
|
|||||||
SearchDomains: fqdns("coffee.shop"),
|
SearchDomains: fqdns("coffee.shop"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
m := NewManager(t.Logf, &f, health.NewTracker(eventbustest.NewBus(t)), tsdial.NewDialer(netmon.NewStatic()), nil, nil, "")
|
bus := eventbustest.NewBus(t)
|
||||||
|
dialer := tsdial.NewDialer(netmon.NewStatic())
|
||||||
|
dialer.SetBus(bus)
|
||||||
|
m := NewManager(t.Logf, &f, health.NewTracker(bus), dialer, nil, nil, "")
|
||||||
m.resolver.TestOnlySetHook(f.SetResolver)
|
m.resolver.TestOnlySetHook(f.SetResolver)
|
||||||
m.Set(Config{
|
m.Set(Config{
|
||||||
Hosts: hosts(
|
Hosts: hosts(
|
||||||
@@ -175,7 +178,10 @@ func TestDNSOverTCP_TooLarge(t *testing.T) {
|
|||||||
SearchDomains: fqdns("coffee.shop"),
|
SearchDomains: fqdns("coffee.shop"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
m := NewManager(log, &f, health.NewTracker(eventbustest.NewBus(t)), tsdial.NewDialer(netmon.NewStatic()), nil, nil, "")
|
bus := eventbustest.NewBus(t)
|
||||||
|
dialer := tsdial.NewDialer(netmon.NewStatic())
|
||||||
|
dialer.SetBus(bus)
|
||||||
|
m := NewManager(log, &f, health.NewTracker(bus), dialer, nil, nil, "")
|
||||||
m.resolver.TestOnlySetHook(f.SetResolver)
|
m.resolver.TestOnlySetHook(f.SetResolver)
|
||||||
m.Set(Config{
|
m.Set(Config{
|
||||||
Hosts: hosts("andrew.ts.com.", "1.2.3.4"),
|
Hosts: hosts("andrew.ts.com.", "1.2.3.4"),
|
||||||
|
|||||||
@@ -933,7 +933,10 @@ func TestManager(t *testing.T) {
|
|||||||
goos = "linux"
|
goos = "linux"
|
||||||
}
|
}
|
||||||
knobs := &controlknobs.Knobs{}
|
knobs := &controlknobs.Knobs{}
|
||||||
m := NewManager(t.Logf, &f, health.NewTracker(eventbustest.NewBus(t)), tsdial.NewDialer(netmon.NewStatic()), nil, knobs, goos)
|
bus := eventbustest.NewBus(t)
|
||||||
|
dialer := tsdial.NewDialer(netmon.NewStatic())
|
||||||
|
dialer.SetBus(bus)
|
||||||
|
m := NewManager(t.Logf, &f, health.NewTracker(bus), dialer, nil, knobs, goos)
|
||||||
m.resolver.TestOnlySetHook(f.SetResolver)
|
m.resolver.TestOnlySetHook(f.SetResolver)
|
||||||
|
|
||||||
if err := m.Set(test.in); err != nil {
|
if err := m.Set(test.in); err != nil {
|
||||||
@@ -1039,7 +1042,10 @@ func TestConfigRecompilation(t *testing.T) {
|
|||||||
SearchDomains: fqdns("foo.ts.net"),
|
SearchDomains: fqdns("foo.ts.net"),
|
||||||
}
|
}
|
||||||
|
|
||||||
m := NewManager(t.Logf, f, health.NewTracker(eventbustest.NewBus(t)), tsdial.NewDialer(netmon.NewStatic()), nil, nil, "darwin")
|
bus := eventbustest.NewBus(t)
|
||||||
|
dialer := tsdial.NewDialer(netmon.NewStatic())
|
||||||
|
dialer.SetBus(bus)
|
||||||
|
m := NewManager(t.Logf, f, health.NewTracker(bus), dialer, nil, nil, "darwin")
|
||||||
|
|
||||||
var managerConfig *resolver.Config
|
var managerConfig *resolver.Config
|
||||||
m.resolver.TestOnlySetHook(func(cfg resolver.Config) {
|
m.resolver.TestOnlySetHook(func(cfg resolver.Config) {
|
||||||
|
|||||||
@@ -122,7 +122,6 @@ func TestResolversWithDelays(t *testing.T) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetRCode(t *testing.T) {
|
func TestGetRCode(t *testing.T) {
|
||||||
@@ -454,6 +453,7 @@ func runTestQuery(tb testing.TB, request []byte, modify func(*forwarder), ports
|
|||||||
|
|
||||||
var dialer tsdial.Dialer
|
var dialer tsdial.Dialer
|
||||||
dialer.SetNetMon(netMon)
|
dialer.SetNetMon(netMon)
|
||||||
|
dialer.SetBus(bus)
|
||||||
|
|
||||||
fwd := newForwarder(logf, netMon, nil, &dialer, health.NewTracker(bus), nil)
|
fwd := newForwarder(logf, netMon, nil, &dialer, health.NewTracker(bus), nil)
|
||||||
if modify != nil {
|
if modify != nil {
|
||||||
|
|||||||
@@ -353,10 +353,13 @@ func TestRDNSNameToIPv6(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func newResolver(t testing.TB) *Resolver {
|
func newResolver(t testing.TB) *Resolver {
|
||||||
|
bus := eventbustest.NewBus(t)
|
||||||
|
dialer := tsdial.NewDialer(netmon.NewStatic())
|
||||||
|
dialer.SetBus(bus)
|
||||||
return New(t.Logf,
|
return New(t.Logf,
|
||||||
nil, // no link selector
|
nil, // no link selector
|
||||||
tsdial.NewDialer(netmon.NewStatic()),
|
dialer,
|
||||||
health.NewTracker(eventbustest.NewBus(t)),
|
health.NewTracker(bus),
|
||||||
nil, // no control knobs
|
nil, // no control knobs
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
|
"tailscale.com/util/eventbus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// LinkChangeLogLimiter returns a new [logger.Logf] that logs each unique
|
// LinkChangeLogLimiter returns a new [logger.Logf] that logs each unique
|
||||||
@@ -17,13 +18,12 @@ import (
|
|||||||
// done.
|
// done.
|
||||||
func LinkChangeLogLimiter(ctx context.Context, logf logger.Logf, nm *Monitor) logger.Logf {
|
func LinkChangeLogLimiter(ctx context.Context, logf logger.Logf, nm *Monitor) logger.Logf {
|
||||||
var formatSeen sync.Map // map[string]bool
|
var formatSeen sync.Map // map[string]bool
|
||||||
unregister := nm.RegisterChangeCallback(func(cd *ChangeDelta) {
|
nm.b.Monitor(nm.changeDeltaWatcher(nm.b, ctx, func(cd ChangeDelta) {
|
||||||
// If we're in a major change or a time jump, clear the seen map.
|
// If we're in a major change or a time jump, clear the seen map.
|
||||||
if cd.Major || cd.TimeJumped {
|
if cd.Major || cd.TimeJumped {
|
||||||
formatSeen.Clear()
|
formatSeen.Clear()
|
||||||
}
|
}
|
||||||
})
|
}))
|
||||||
context.AfterFunc(ctx, unregister)
|
|
||||||
|
|
||||||
return func(format string, args ...any) {
|
return func(format string, args ...any) {
|
||||||
// We only store 'true' in the map, so if it's present then it
|
// We only store 'true' in the map, so if it's present then it
|
||||||
@@ -42,3 +42,19 @@ func LinkChangeLogLimiter(ctx context.Context, logf logger.Logf, nm *Monitor) lo
|
|||||||
logf(format, args...)
|
logf(format, args...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (nm *Monitor) changeDeltaWatcher(ec *eventbus.Client, ctx context.Context, fn func(ChangeDelta)) func(*eventbus.Client) {
|
||||||
|
sub := eventbus.Subscribe[ChangeDelta](ec)
|
||||||
|
return func(ec *eventbus.Client) {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
case <-sub.Done():
|
||||||
|
return
|
||||||
|
case change := <-sub.Events():
|
||||||
|
fn(change)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"testing/synctest"
|
"testing/synctest"
|
||||||
|
|
||||||
"tailscale.com/util/eventbus"
|
"tailscale.com/util/eventbus"
|
||||||
|
"tailscale.com/util/eventbus/eventbustest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLinkChangeLogLimiter(t *testing.T) { synctest.Test(t, syncTestLinkChangeLogLimiter) }
|
func TestLinkChangeLogLimiter(t *testing.T) { synctest.Test(t, syncTestLinkChangeLogLimiter) }
|
||||||
@@ -61,21 +62,15 @@ func syncTestLinkChangeLogLimiter(t *testing.T) {
|
|||||||
// string cache and allow the next log to write to our log buffer.
|
// string cache and allow the next log to write to our log buffer.
|
||||||
//
|
//
|
||||||
// InjectEvent doesn't work because it's not a major event, so we
|
// InjectEvent doesn't work because it's not a major event, so we
|
||||||
// instead reach into the netmon and grab the callback, and then call
|
// instead inject the event ourselves.
|
||||||
// it ourselves.
|
injector := eventbustest.NewInjector(t, bus)
|
||||||
mon.mu.Lock()
|
eventbustest.Inject(injector, ChangeDelta{Major: true})
|
||||||
var cb func(*ChangeDelta)
|
synctest.Wait()
|
||||||
for _, c := range mon.cbs {
|
|
||||||
cb = c
|
|
||||||
break
|
|
||||||
}
|
|
||||||
mon.mu.Unlock()
|
|
||||||
|
|
||||||
cb(&ChangeDelta{Major: true})
|
|
||||||
|
|
||||||
logf("hello %s", "world")
|
logf("hello %s", "world")
|
||||||
if got := logBuffer.String(); got != "hello world\nother message\nhello world\n" {
|
want := "hello world\nother message\nhello world\n"
|
||||||
t.Errorf("unexpected log buffer contents: %q", got)
|
if got := logBuffer.String(); got != want {
|
||||||
|
t.Errorf("unexpected log buffer contents, got: %q, want, %q", got, want)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Canceling the context we passed to LinkChangeLogLimiter should
|
// Canceling the context we passed to LinkChangeLogLimiter should
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import (
|
|||||||
"tailscale.com/types/logger"
|
"tailscale.com/types/logger"
|
||||||
"tailscale.com/types/netmap"
|
"tailscale.com/types/netmap"
|
||||||
"tailscale.com/util/clientmetric"
|
"tailscale.com/util/clientmetric"
|
||||||
|
"tailscale.com/util/eventbus"
|
||||||
"tailscale.com/util/mak"
|
"tailscale.com/util/mak"
|
||||||
"tailscale.com/util/testenv"
|
"tailscale.com/util/testenv"
|
||||||
"tailscale.com/version"
|
"tailscale.com/version"
|
||||||
@@ -86,6 +87,8 @@ type Dialer struct {
|
|||||||
dnsCache *dnscache.MessageCache // nil until first non-empty SetExitDNSDoH
|
dnsCache *dnscache.MessageCache // nil until first non-empty SetExitDNSDoH
|
||||||
nextSysConnID int
|
nextSysConnID int
|
||||||
activeSysConns map[int]net.Conn // active connections not yet closed
|
activeSysConns map[int]net.Conn // active connections not yet closed
|
||||||
|
eventClient *eventbus.Client
|
||||||
|
eventBusSubs eventbus.Monitor
|
||||||
}
|
}
|
||||||
|
|
||||||
// sysConn wraps a net.Conn that was created using d.SystemDial.
|
// sysConn wraps a net.Conn that was created using d.SystemDial.
|
||||||
@@ -158,6 +161,9 @@ func (d *Dialer) SetRoutes(routes, localRoutes []netip.Prefix) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Dialer) Close() error {
|
func (d *Dialer) Close() error {
|
||||||
|
if d.eventClient != nil {
|
||||||
|
d.eventBusSubs.Close()
|
||||||
|
}
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
defer d.mu.Unlock()
|
defer d.mu.Unlock()
|
||||||
d.closed = true
|
d.closed = true
|
||||||
@@ -186,6 +192,14 @@ func (d *Dialer) SetNetMon(netMon *netmon.Monitor) {
|
|||||||
d.netMonUnregister = nil
|
d.netMonUnregister = nil
|
||||||
}
|
}
|
||||||
d.netMon = netMon
|
d.netMon = netMon
|
||||||
|
// Having multiple watchers could lead to problems,
|
||||||
|
// so remove the eventClient if it exists.
|
||||||
|
// This should really not happen, but better checking for it than not.
|
||||||
|
// TODO(cmol): Should this just be a panic?
|
||||||
|
if d.eventClient != nil {
|
||||||
|
d.eventBusSubs.Close()
|
||||||
|
d.eventClient = nil
|
||||||
|
}
|
||||||
d.netMonUnregister = d.netMon.RegisterChangeCallback(d.linkChanged)
|
d.netMonUnregister = d.netMon.RegisterChangeCallback(d.linkChanged)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,6 +211,35 @@ func (d *Dialer) NetMon() *netmon.Monitor {
|
|||||||
return d.netMon
|
return d.netMon
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Dialer) SetBus(bus *eventbus.Bus) {
|
||||||
|
d.mu.Lock()
|
||||||
|
defer d.mu.Unlock()
|
||||||
|
if d.eventClient != nil {
|
||||||
|
panic("eventbus has already been set")
|
||||||
|
}
|
||||||
|
// Having multiple watchers could lead to problems,
|
||||||
|
// so unregister the callback if it exists.
|
||||||
|
if d.netMonUnregister != nil {
|
||||||
|
d.netMonUnregister()
|
||||||
|
}
|
||||||
|
d.eventClient = bus.Client("tsdial.Dialer")
|
||||||
|
d.eventBusSubs = d.eventClient.Monitor(d.linkChangeWatcher(d.eventClient))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *Dialer) linkChangeWatcher(ec *eventbus.Client) func(*eventbus.Client) {
|
||||||
|
linkChangeSub := eventbus.Subscribe[netmon.ChangeDelta](ec)
|
||||||
|
return func(ec *eventbus.Client) {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ec.Done():
|
||||||
|
return
|
||||||
|
case cd := <-linkChangeSub.Events():
|
||||||
|
d.linkChanged(&cd)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
metricLinkChangeConnClosed = clientmetric.NewCounter("tsdial_linkchange_closes")
|
metricLinkChangeConnClosed = clientmetric.NewCounter("tsdial_linkchange_closes")
|
||||||
metricChangeDeltaNoDefaultRoute = clientmetric.NewCounter("tsdial_changedelta_no_default_route")
|
metricChangeDeltaNoDefaultRoute = clientmetric.NewCounter("tsdial_changedelta_no_default_route")
|
||||||
|
|||||||
@@ -592,6 +592,7 @@ func (s *Server) start() (reterr error) {
|
|||||||
closePool.add(s.netMon)
|
closePool.add(s.netMon)
|
||||||
|
|
||||||
s.dialer = &tsdial.Dialer{Logf: tsLogf} // mutated below (before used)
|
s.dialer = &tsdial.Dialer{Logf: tsLogf} // mutated below (before used)
|
||||||
|
s.dialer.SetBus(sys.Bus.Get())
|
||||||
eng, err := wgengine.NewUserspaceEngine(tsLogf, wgengine.Config{
|
eng, err := wgengine.NewUserspaceEngine(tsLogf, wgengine.Config{
|
||||||
EventBus: sys.Bus.Get(),
|
EventBus: sys.Bus.Get(),
|
||||||
ListenPort: s.Port,
|
ListenPort: s.Port,
|
||||||
@@ -767,6 +768,7 @@ func (s *Server) startLogger(closePool *closeOnErrorPool, health *health.Tracker
|
|||||||
Stderr: io.Discard, // log everything to Buffer
|
Stderr: io.Discard, // log everything to Buffer
|
||||||
Buffer: s.logbuffer,
|
Buffer: s.logbuffer,
|
||||||
CompressLogs: true,
|
CompressLogs: true,
|
||||||
|
Bus: s.sys.Bus.Get(),
|
||||||
HTTPC: &http.Client{Transport: logpolicy.NewLogtailTransport(logtail.DefaultHost, s.netMon, health, tsLogf)},
|
HTTPC: &http.Client{Transport: logpolicy.NewLogtailTransport(logtail.DefaultHost, s.netMon, health, tsLogf)},
|
||||||
MetricsDelta: clientmetric.EncodeLogTailMetricsDelta,
|
MetricsDelta: clientmetric.EncodeLogTailMetricsDelta,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import (
|
|||||||
"tailscale.com/tailcfg"
|
"tailscale.com/tailcfg"
|
||||||
"tailscale.com/types/logid"
|
"tailscale.com/types/logid"
|
||||||
"tailscale.com/types/netlogtype"
|
"tailscale.com/types/netlogtype"
|
||||||
|
"tailscale.com/util/eventbus"
|
||||||
"tailscale.com/wgengine/router"
|
"tailscale.com/wgengine/router"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -95,7 +96,7 @@ var testClient *http.Client
|
|||||||
// The IP protocol and source port are always zero.
|
// The IP protocol and source port are always zero.
|
||||||
// The sock is used to populated the PhysicalTraffic field in Message.
|
// The sock is used to populated the PhysicalTraffic field in Message.
|
||||||
// The netMon parameter is optional; if non-nil it's used to do faster interface lookups.
|
// The netMon parameter is optional; if non-nil it's used to do faster interface lookups.
|
||||||
func (nl *Logger) Startup(nodeID tailcfg.StableNodeID, nodeLogID, domainLogID logid.PrivateID, tun, sock Device, netMon *netmon.Monitor, health *health.Tracker, logExitFlowEnabledEnabled bool) error {
|
func (nl *Logger) Startup(nodeID tailcfg.StableNodeID, nodeLogID, domainLogID logid.PrivateID, tun, sock Device, netMon *netmon.Monitor, health *health.Tracker, bus *eventbus.Bus, logExitFlowEnabledEnabled bool) error {
|
||||||
nl.mu.Lock()
|
nl.mu.Lock()
|
||||||
defer nl.mu.Unlock()
|
defer nl.mu.Unlock()
|
||||||
if nl.logger != nil {
|
if nl.logger != nil {
|
||||||
@@ -112,6 +113,7 @@ func (nl *Logger) Startup(nodeID tailcfg.StableNodeID, nodeLogID, domainLogID lo
|
|||||||
Collection: "tailtraffic.log.tailscale.io",
|
Collection: "tailtraffic.log.tailscale.io",
|
||||||
PrivateID: nodeLogID,
|
PrivateID: nodeLogID,
|
||||||
CopyPrivateID: domainLogID,
|
CopyPrivateID: domainLogID,
|
||||||
|
Bus: bus,
|
||||||
Stderr: io.Discard,
|
Stderr: io.Discard,
|
||||||
CompressLogs: true,
|
CompressLogs: true,
|
||||||
HTTPC: httpc,
|
HTTPC: httpc,
|
||||||
|
|||||||
@@ -312,6 +312,9 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
|
|||||||
}
|
}
|
||||||
if conf.Dialer == nil {
|
if conf.Dialer == nil {
|
||||||
conf.Dialer = &tsdial.Dialer{Logf: logf}
|
conf.Dialer = &tsdial.Dialer{Logf: logf}
|
||||||
|
if conf.EventBus != nil {
|
||||||
|
conf.Dialer.SetBus(conf.EventBus)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var tsTUNDev *tstun.Wrapper
|
var tsTUNDev *tstun.Wrapper
|
||||||
@@ -379,6 +382,7 @@ func NewUserspaceEngine(logf logger.Logf, conf Config) (_ Engine, reterr error)
|
|||||||
tunName, _ := conf.Tun.Name()
|
tunName, _ := conf.Tun.Name()
|
||||||
conf.Dialer.SetTUNName(tunName)
|
conf.Dialer.SetTUNName(tunName)
|
||||||
conf.Dialer.SetNetMon(e.netMon)
|
conf.Dialer.SetNetMon(e.netMon)
|
||||||
|
conf.Dialer.SetBus(e.eventBus)
|
||||||
e.dns = dns.NewManager(logf, conf.DNS, e.health, conf.Dialer, fwdDNSLinkSelector{e, tunName}, conf.ControlKnobs, runtime.GOOS)
|
e.dns = dns.NewManager(logf, conf.DNS, e.health, conf.Dialer, fwdDNSLinkSelector{e, tunName}, conf.ControlKnobs, runtime.GOOS)
|
||||||
|
|
||||||
// TODO: there's probably a better place for this
|
// TODO: there's probably a better place for this
|
||||||
@@ -1035,7 +1039,7 @@ func (e *userspaceEngine) Reconfig(cfg *wgcfg.Config, routerCfg *router.Config,
|
|||||||
tid := cfg.NetworkLogging.DomainID
|
tid := cfg.NetworkLogging.DomainID
|
||||||
logExitFlowEnabled := cfg.NetworkLogging.LogExitFlowEnabled
|
logExitFlowEnabled := cfg.NetworkLogging.LogExitFlowEnabled
|
||||||
e.logf("wgengine: Reconfig: starting up network logger (node:%s tailnet:%s)", nid.Public(), tid.Public())
|
e.logf("wgengine: Reconfig: starting up network logger (node:%s tailnet:%s)", nid.Public(), tid.Public())
|
||||||
if err := e.networkLogger.Startup(cfg.NodeID, nid, tid, e.tundev, e.magicConn, e.netMon, e.health, logExitFlowEnabled); err != nil {
|
if err := e.networkLogger.Startup(cfg.NodeID, nid, tid, e.tundev, e.magicConn, e.netMon, e.health, e.eventBus, logExitFlowEnabled); err != nil {
|
||||||
e.logf("wgengine: Reconfig: error starting up network logger: %v", err)
|
e.logf("wgengine: Reconfig: error starting up network logger: %v", err)
|
||||||
}
|
}
|
||||||
e.networkLogger.ReconfigRoutes(routerCfg)
|
e.networkLogger.ReconfigRoutes(routerCfg)
|
||||||
|
|||||||
Reference in New Issue
Block a user