mirror of
https://github.com/lukaszraczylo/kportal.git
synced 2026-10-19 05:18:50 +00:00
fix(mdns): answer hostname A queries after TTL (#96)
* fix(mdns): answer hostname A queries after TTL Zeroconf answers only service queries. The A record for <alias>.local expired from the OS cache after 120 seconds and lookups then failed. Vendor zeroconf v1.0.0 with one change: it now answers A and AAAA queries for the registered hostname. Fixes #95. * fix(deps): update golang.org/x/net to v0.60.0 govulncheck reports several x/net advisories fixed in v0.60.0. The Security Scan job fails on them.
This commit is contained in:
Vendored
+109
@@ -0,0 +1,109 @@
|
||||
package zeroconf
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// ServiceRecord contains the basic description of a service, which contains instance name, service type & domain
|
||||
type ServiceRecord struct {
|
||||
Instance string `json:"name"` // Instance name (e.g. "My web page")
|
||||
Service string `json:"type"` // Service name (e.g. _http._tcp.)
|
||||
Domain string `json:"domain"` // If blank, assumes "local"
|
||||
|
||||
// private variable populated on ServiceRecord creation
|
||||
serviceName string
|
||||
serviceInstanceName string
|
||||
serviceTypeName string
|
||||
}
|
||||
|
||||
// ServiceName returns a complete service name (e.g. _foobar._tcp.local.), which is composed
|
||||
// of a service name (also referred as service type) and a domain.
|
||||
func (s *ServiceRecord) ServiceName() string {
|
||||
return s.serviceName
|
||||
}
|
||||
|
||||
// ServiceInstanceName returns a complete service instance name (e.g. MyDemo\ Service._foobar._tcp.local.),
|
||||
// which is composed from service instance name, service name and a domain.
|
||||
func (s *ServiceRecord) ServiceInstanceName() string {
|
||||
return s.serviceInstanceName
|
||||
}
|
||||
|
||||
// ServiceTypeName returns the complete identifier for a DNS-SD query.
|
||||
func (s *ServiceRecord) ServiceTypeName() string {
|
||||
return s.serviceTypeName
|
||||
}
|
||||
|
||||
// NewServiceRecord constructs a ServiceRecord.
|
||||
func NewServiceRecord(instance, service, domain string) *ServiceRecord {
|
||||
s := &ServiceRecord{
|
||||
Instance: instance,
|
||||
Service: service,
|
||||
Domain: domain,
|
||||
serviceName: fmt.Sprintf("%s.%s.", trimDot(service), trimDot(domain)),
|
||||
}
|
||||
|
||||
// Cache service instance name
|
||||
if instance != "" {
|
||||
s.serviceInstanceName = fmt.Sprintf("%s.%s", trimDot(s.Instance), s.ServiceName())
|
||||
}
|
||||
|
||||
// Cache service type name domain
|
||||
typeNameDomain := "local"
|
||||
if len(s.Domain) > 0 {
|
||||
typeNameDomain = trimDot(s.Domain)
|
||||
}
|
||||
s.serviceTypeName = fmt.Sprintf("_services._dns-sd._udp.%s.", typeNameDomain)
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// LookupParams contains configurable properties to create a service discovery request
|
||||
type LookupParams struct {
|
||||
ServiceRecord
|
||||
Entries chan<- *ServiceEntry // Entries Channel
|
||||
|
||||
stopProbing chan struct{}
|
||||
once sync.Once
|
||||
}
|
||||
|
||||
// NewLookupParams constructs a LookupParams.
|
||||
func NewLookupParams(instance, service, domain string, entries chan<- *ServiceEntry) *LookupParams {
|
||||
return &LookupParams{
|
||||
ServiceRecord: *NewServiceRecord(instance, service, domain),
|
||||
Entries: entries,
|
||||
|
||||
stopProbing: make(chan struct{}),
|
||||
}
|
||||
}
|
||||
|
||||
// Notify subscriber that no more entries will arrive. Mostly caused
|
||||
// by an expired context.
|
||||
func (l *LookupParams) done() {
|
||||
close(l.Entries)
|
||||
}
|
||||
|
||||
func (l *LookupParams) disableProbing() {
|
||||
l.once.Do(func() { close(l.stopProbing) })
|
||||
}
|
||||
|
||||
// ServiceEntry represents a browse/lookup result for client API.
|
||||
// It is also used to configure service registration (server API), which is
|
||||
// used to answer multicast queries.
|
||||
type ServiceEntry struct {
|
||||
ServiceRecord
|
||||
HostName string `json:"hostname"` // Host machine DNS name
|
||||
Port int `json:"port"` // Service Port
|
||||
Text []string `json:"text"` // Service info served as a TXT record
|
||||
TTL uint32 `json:"ttl"` // TTL of the service record
|
||||
AddrIPv4 []net.IP `json:"-"` // Host machine IPv4 address
|
||||
AddrIPv6 []net.IP `json:"-"` // Host machine IPv6 address
|
||||
}
|
||||
|
||||
// NewServiceEntry constructs a ServiceEntry.
|
||||
func NewServiceEntry(instance, service, domain string) *ServiceEntry {
|
||||
return &ServiceEntry{
|
||||
ServiceRecord: *NewServiceRecord(instance, service, domain),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user