diff --git a/net/dns/resolved.go b/net/dns/resolved.go index 76fe55967..9cd859e79 100644 --- a/net/dns/resolved.go +++ b/net/dns/resolved.go @@ -42,6 +42,28 @@ var resolvedListenAddr = netaddr.IPv4(127, 0, 0, 53) var errNotReady = errors.New("interface not ready") +// DBus entities we talk to. +// +// DBus is an RPC bus. In particular, the bus we're talking to is the +// system-wide bus (there is also a per-user session bus for +// user-specific applications). +// +// Daemons connect to the bus, and advertise themselves under a +// well-known object name. That object exposes paths, and each path +// implements one or more interfaces that contain methods, properties, +// and signals. +// +// Clients connect to the bus and walk that same hierarchy to invoke +// RPCs, get/set properties, or listen for signals. +const ( + dbusResolvedObject = "org.freedesktop.resolve1" + dbusResolvedPath dbus.ObjectPath = "/org/freedesktop/resolve1" + dbusResolvedInterface = "org.freedesktop.resolve1.Manager" + dbusPath dbus.ObjectPath = "/org/freedesktop/DBus" + dbusInterface = "org.freedesktop.DBus" + dbusOwnerSignal = "NameOwnerChanged" // broadcast when a well-known name's owning process changes. +) + type resolvedLinkNameserver struct { Family int32 Address []byte @@ -115,7 +137,7 @@ func newResolvedManager(logf logger.Logf, interfaceName string) (*resolvedManage ifidx: iface.Index, cancelSyncer: cancel, syncerDone: make(chan struct{}), - resolved: conn.Object("org.freedesktop.resolve1", dbus.ObjectPath("/org/freedesktop/resolve1")), + resolved: conn.Object(dbusResolvedObject, dbus.ObjectPath(dbusResolvedPath)), } signals := make(chan *dbus.Signal, 16) go ret.resync(ctx, signals) @@ -123,7 +145,7 @@ func newResolvedManager(logf logger.Logf, interfaceName string) (*resolvedManage // resolved restart. Failure to set filters isn't a fatal error, // we'll just receive all broadcast signals and have to ignore // them on our end. - if err := conn.AddMatchSignal(dbus.WithMatchObjectPath("/org/freedesktop/DBus"), dbus.WithMatchInterface("org.freedesktop.DBus"), dbus.WithMatchMember("NameOwnerChanged"), dbus.WithMatchArg(0, "org.freedesktop.resolve1")); err != nil { + if err := conn.AddMatchSignal(dbus.WithMatchObjectPath(dbusPath), dbus.WithMatchInterface(dbusInterface), dbus.WithMatchMember(dbusOwnerSignal), dbus.WithMatchArg(0, dbusResolvedObject)); err != nil { logf("[v1] Setting DBus signal filter failed: %v", err) } conn.Signal(signals) @@ -148,14 +170,14 @@ func (m *resolvedManager) resync(ctx context.Context, signals chan *dbus.Signal) // In theory the signal was filtered by DBus, but if // AddMatchSignal in the constructor failed, we may be // getting other spam. - if signal.Path != "/org/freedesktop/DBus" || signal.Name != "org.freedesktop.DBus.NameOwnerChanged" { + if signal.Path != dbusPath || signal.Name != dbusInterface+"."+dbusOwnerSignal { continue } // signal.Body is a []interface{} of 3 strings: bus name, previous owner, new owner. if len(signal.Body) != 3 { m.logf("[unexpectected] DBus NameOwnerChanged len(Body) = %d, want 3") } - if name, ok := signal.Body[0].(string); !ok || name != "org.freedesktop.resolve1" { + if name, ok := signal.Body[0].(string); !ok || name != dbusResolvedObject { continue } newOwner, ok := signal.Body[2].(string) @@ -205,7 +227,7 @@ func (m *resolvedManager) syncLocked(ctx context.Context) error { } err := m.resolved.CallWithContext( - ctx, "org.freedesktop.resolve1.Manager.SetLinkDNS", 0, + ctx, dbusResolvedInterface+".SetLinkDNS", 0, m.ifidx, linkNameservers, ).Store() if err != nil { @@ -246,14 +268,14 @@ func (m *resolvedManager) syncLocked(ctx context.Context) error { } err = m.resolved.CallWithContext( - ctx, "org.freedesktop.resolve1.Manager.SetLinkDomains", 0, + ctx, dbusResolvedInterface+".SetLinkDomains", 0, m.ifidx, linkDomains, ).Store() if err != nil && err.Error() == "Argument list too long" { // TODO: better error match // Issue 3188: older systemd-resolved had argument length limits. // Trim out the *.arpa. entries and try again. err = m.resolved.CallWithContext( - ctx, "org.freedesktop.resolve1.Manager.SetLinkDomains", 0, + ctx, dbusResolvedInterface+".SetLinkDomains", 0, m.ifidx, linkDomainsWithoutReverseDNS(linkDomains), ).Store() } @@ -261,7 +283,7 @@ func (m *resolvedManager) syncLocked(ctx context.Context) error { return fmt.Errorf("setLinkDomains: %w", err) } - if call := m.resolved.CallWithContext(ctx, "org.freedesktop.resolve1.Manager.SetLinkDefaultRoute", 0, m.ifidx, len(m.config.MatchDomains) == 0); call.Err != nil { + if call := m.resolved.CallWithContext(ctx, dbusResolvedInterface+".SetLinkDefaultRoute", 0, m.ifidx, len(m.config.MatchDomains) == 0); call.Err != nil { if dbusErr, ok := call.Err.(dbus.Error); ok && dbusErr.Name == dbus.ErrMsgUnknownMethod.Name { // on some older systems like Kubuntu 18.04.6 with systemd 237 method SetLinkDefaultRoute is absent, // but otherwise it's working good @@ -276,26 +298,26 @@ func (m *resolvedManager) syncLocked(ctx context.Context) error { // or something). // Disable LLMNR, we don't do multicast. - if call := m.resolved.CallWithContext(ctx, "org.freedesktop.resolve1.Manager.SetLinkLLMNR", 0, m.ifidx, "no"); call.Err != nil { + if call := m.resolved.CallWithContext(ctx, dbusResolvedInterface+".SetLinkLLMNR", 0, m.ifidx, "no"); call.Err != nil { m.logf("[v1] failed to disable LLMNR: %v", call.Err) } // Disable mdns. - if call := m.resolved.CallWithContext(ctx, "org.freedesktop.resolve1.Manager.SetLinkMulticastDNS", 0, m.ifidx, "no"); call.Err != nil { + if call := m.resolved.CallWithContext(ctx, dbusResolvedInterface+".SetLinkMulticastDNS", 0, m.ifidx, "no"); call.Err != nil { m.logf("[v1] failed to disable mdns: %v", call.Err) } // We don't support dnssec consistently right now, force it off to // avoid partial failures when we split DNS internally. - if call := m.resolved.CallWithContext(ctx, "org.freedesktop.resolve1.Manager.SetLinkDNSSEC", 0, m.ifidx, "no"); call.Err != nil { + if call := m.resolved.CallWithContext(ctx, dbusResolvedInterface+".SetLinkDNSSEC", 0, m.ifidx, "no"); call.Err != nil { m.logf("[v1] failed to disable DNSSEC: %v", call.Err) } - if call := m.resolved.CallWithContext(ctx, "org.freedesktop.resolve1.Manager.SetLinkDNSOverTLS", 0, m.ifidx, "no"); call.Err != nil { + if call := m.resolved.CallWithContext(ctx, dbusResolvedInterface+".SetLinkDNSOverTLS", 0, m.ifidx, "no"); call.Err != nil { m.logf("[v1] failed to disable DoT: %v", call.Err) } - if call := m.resolved.CallWithContext(ctx, "org.freedesktop.resolve1.Manager.FlushCaches", 0); call.Err != nil { + if call := m.resolved.CallWithContext(ctx, dbusResolvedInterface+".FlushCaches", 0); call.Err != nil { m.logf("failed to flush resolved DNS cache: %v", call.Err) } @@ -315,7 +337,7 @@ func (m *resolvedManager) Close() error { ctx, cancel := context.WithTimeout(context.Background(), reconfigTimeout) defer cancel() - if call := m.resolved.CallWithContext(ctx, "org.freedesktop.resolve1.Manager.RevertLink", 0, m.ifidx); call.Err != nil { + if call := m.resolved.CallWithContext(ctx, dbusResolvedInterface+".RevertLink", 0, m.ifidx); call.Err != nil { return fmt.Errorf("RevertLink: %w", call.Err) }