فهرست منبع

tailcfg, ipn/ipnlocal: advertise a Service when exit node DNS proxy available

Updates #1713

Change-Id: I20c8e2ad1062d82ef17363414e372133f4c7181e
Signed-off-by: Brad Fitzpatrick <[email protected]>
Brad Fitzpatrick 4 سال پیش
والد
کامیت
b811a316bc
2فایلهای تغییر یافته به همراه51 افزوده شده و 10 حذف شده
  1. 14 4
      ipn/ipnlocal/local.go
  2. 37 6
      tailcfg/tailcfg.go

+ 14 - 4
ipn/ipnlocal/local.go

@@ -1753,15 +1753,25 @@ func (b *LocalBackend) getPeerAPIPortForTSMPPing(ip netaddr.IP) (port uint16, ok
 
 func (b *LocalBackend) peerAPIServicesLocked() (ret []tailcfg.Service) {
 	for _, pln := range b.peerAPIListeners {
-		proto := tailcfg.ServiceProto("peerapi4")
+		proto := tailcfg.PeerAPI4
 		if pln.ip.Is6() {
-			proto = "peerapi6"
+			proto = tailcfg.PeerAPI6
 		}
 		ret = append(ret, tailcfg.Service{
 			Proto: proto,
 			Port:  uint16(pln.port),
 		})
 	}
+	switch runtime.GOOS {
+	case "linux", "freebsd", "openbsd", "illumos", "darwin":
+		// These are the platforms currently supported by
+		// net/dns/resolver/tsdns.go:Resolver.HandleExitNodeDNSQuery.
+		// TODO(bradfitz): add windows once it's done there.
+		ret = append(ret, tailcfg.Service{
+			Proto: tailcfg.PeerAPIDNS,
+			Port:  1, // version
+		})
+	}
 	return ret
 }
 
@@ -2880,9 +2890,9 @@ func peerAPIBase(nm *netmap.NetworkMap, peer *tailcfg.Node) string {
 	var p4, p6 uint16
 	for _, s := range peer.Hostinfo.Services {
 		switch s.Proto {
-		case "peerapi4":
+		case tailcfg.PeerAPI4:
 			p4 = s.Port
-		case "peerapi6":
+		case tailcfg.PeerAPI6:
 			p6 = s.Port
 		}
 	}

+ 37 - 6
tailcfg/tailcfg.go

@@ -379,18 +379,49 @@ func (h *Hostinfo) CheckRequestTags() error {
 	return nil
 }
 
+// ServiceProto is a service type. It's usually
+// TCP ("tcp") or UDP ("udp"), but it can also have
+// meta service values as defined in Service.Proto.
 type ServiceProto string
 
 const (
-	TCP = ServiceProto("tcp")
-	UDP = ServiceProto("udp")
+	TCP        = ServiceProto("tcp")
+	UDP        = ServiceProto("udp")
+	PeerAPI4   = ServiceProto("peerapi4")
+	PeerAPI6   = ServiceProto("peerapi6")
+	PeerAPIDNS = ServiceProto("peerapi-dns-proxy")
 )
 
+// Service represents a service running on a node.
 type Service struct {
-	_           structs.Incomparable
-	Proto       ServiceProto // TCP or UDP
-	Port        uint16       // port number service is listening on
-	Description string       `json:",omitempty"` // text description of service
+	_ structs.Incomparable
+
+	// Proto is the type of service. It's usually the constant TCP
+	// or UDP ("tcp" or "udp"), but it can also be one of the
+	// following meta service values:
+	//
+	//     * "peerapi4": peerapi is available on IPv4; Port is the
+	//        port number that the peerapi is running on the
+	//        node's Tailscale IPv4 address.
+	//     * "peerapi6": peerapi is available on IPv6; Port is the
+	//        port number that the peerapi is running on the
+	//        node's Tailscale IPv6 address.
+	//     * "peerapi-dns": the local peerapi service supports
+	//        being a DNS proxy (when the node is an exit
+	//        node). For this service, the Port number is really
+	//        the version number of the service.
+	Proto ServiceProto
+
+	// Port is the port number.
+	//
+	// For Proto "peerapi-dns", it's the version number of the DNS proxy,
+	// currently 1.
+	Port uint16
+
+	// Description is the textual description of the service,
+	// usually the process name that's running.
+	Description string `json:",omitempty"`
+
 	// TODO(apenwarr): allow advertising services on subnet IPs?
 	// TODO(apenwarr): add "tags" here for each service?
 }