mdns

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 23, 2026 License: MIT Imports: 14 Imported by: 0

README

mdns — Go Multicast DNS (RFC 6762)

Go Reference Go Version Platforms License

A complete from-scratch implementation of Multicast DNS (RFC 6762) in Go. No third-party mDNS libraries — only the Go standard library.

Install

go get github.com/topcheer/mdns

Quick Start

Register a service
package main

import (
    "fmt"
    "github.com/topcheer/mdns"
)

func main() {
    srv, _ := mdns.NewServer(mdns.DefaultConfig())
    srv.Start()
    defer srv.Close()

    srv.RegisterService(&mdns.ServiceInstance{
        Name: "My Web Server",
        Type: "_http._tcp",
        Port: 8080,
        Text: []string{"path=/", "version=1.0"},
    })

    fmt.Println("Service registered. Press Ctrl-C to stop.")
    select {}
}
Browse for services
srv, _ := mdns.NewServer(mdns.DefaultConfig())
srv.Start()
defer srv.Close()

browser, _ := srv.Browse("_http._tcp")
events, _ := browser.Start()
defer browser.Stop()

for ev := range events {
    switch ev.Action {
    case mdns.EventAdd:
        fmt.Printf("Found: %s at %s:%d\n",
            ev.Instance.Name, ev.Instance.Host, ev.Instance.Port)
    case mdns.EventRemove:
        fmt.Printf("Lost: %s\n", ev.Instance.Name)
    }
}
Resolve a hostname
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

ips, _ := srv.ResolveHost(ctx, "myhost.local.")
for _, ip := range ips {
    fmt.Println(ip)
}
One-shot lookup (no persistent server)
// Resolve a hostname without managing a Server
ips, _ := mdns.LookupHost(ctx, "myhost.local.", 0)

// Discover services without managing a Server
instances, _ := mdns.LookupService(ctx, "_http._tcp", 0)

Configuration

config := mdns.Config{
    Port:       mdns.DefaultPort,  // 53533 (configurable)
    Domain:     "local.",          // mDNS domain suffix
    EnableIPv6: false,             // enable IPv6 multicast
    HostName:   "myhost",          // empty = system hostname
    LogFunc:    func(f string, a ...any) { log.Printf(f, a...) },
}

API Reference

Core Types
Type Description
Server Core mDNS engine. Create with NewServer().
Config Server configuration. Use DefaultConfig() for defaults.
ServiceInstance Service to register via Server.RegisterService().
Browser Service discovery via Server.Browse().
ServiceInstanceInfo Resolved service details (name, host, port, IPs, TXT).
ServiceEvent Event delivered to Browser subscribers.
Key Methods
Method Description
NewServer(Config) Create a new mDNS server
Server.Start() Begin listening and background tasks
Server.RegisterService(*ServiceInstance) Register + probe + announce a service
Server.UnregisterService(*ServiceInstance) Unregister + send goodbye
Server.Browse(serviceType) Create a service browser
Server.ResolveHost(ctx, host) Resolve hostname to IP addresses
Browser.Start() Begin browsing, returns event channel
Browser.Stop() Stop browsing
Browser.Instances() Get all currently known instances
Server.Cache() Access the record cache
Server.HostIPs() Get this host's IP addresses
LookupHost(ctx, host, port) One-shot hostname resolution
LookupService(ctx, type, port) One-shot service discovery

RFC 6762 Compliance

Feature Section Status
.local. domain, multicast addresses 224.0.0.251 / FF02::FB §3
One-Shot query with QU bit (unicast response) §5.1, §5.4
Exponential backoff browsing (1s → 2s → ... → 1h) §5.2
Cache maintenance queries at 80% TTL §5.2
Reverse address mapping (IPv4 .in-addr.arpa. + IPv6 .ip6.arpa.) §4
Unique record immediate response (<10ms) §6
Shared record random response delay (20–120ms) §6
NSEC negative responses §6.1
Additional records in PTR responses (SRV/TXT/A) §6.2
Multicast rate limiting (1s per record) §6
Legacy unicast query support §6.7
Known-Answer Suppression with TTL ≥50% check §7.1
TC bit multipacket known-answer §7.2
Probing (3 × 250ms + random delay) §8.1
Simultaneous probe tiebreaking (lexicographic rdata) §8.2
Hostname A/AAAA probing §8.1
Announcing (double-announce) §8.3
Conflict resolution with auto-rename §9
Goodbye (TTL=0) §10.1
Cache-flush bit §10.2
Passive observation of failures §10.5
Source address verification (local subnet) §11
Packet validation (opcode=0, rcode=0) §18.14
DNS-SD service enumeration (_services._dns-sd._udp) RFC 6763
Design Choices
  • IPv4 priority: Service advertisement always puts IPv4 addresses first.
  • Same-machine multi-instance: Each instance auto-generates a unique hostname.
  • Configurable port: Default 53533 (standard mDNS uses 5353).

Demo Application

The cmd/mdns-demo binary is a zero-config tool that registers a service and discovers peers:

# Build
go build -o mdns-demo ./cmd/mdns-demo

# Run (just works — registers + browses automatically)
./mdns-demo

# Custom service
./mdns-demo -service _http._tcp -port 8080 -name "My Server"

# Verbose logging
./mdns-demo -log

Run on multiple terminals or machines — they discover each other automatically.

Pre-built binaries for all platforms are in Releases.

Architecture

mdns/
├── doc.go                  # Package documentation
├── config.go               # Config, ServiceInstance, ServiceInstanceInfo
├── dns_name.go             # DNS name encoding/decoding (RFC 1035 compression)
├── dns_rr.go               # Resource records: A, AAAA, PTR, SRV, TXT, NSEC
├── dns_message.go          # DNS message pack/unpack
├── multicast.go            # Cross-platform multicast connection
├── multicast_unix.go       # macOS/Linux socket setup
├── multicast_windows.go    # Windows socket setup
├── sockopts_{darwin,linux,windows}.go  # Platform SO_REUSEPORT
├── cache.go                # Record cache with TTL + cache-flush
├── server.go               # Core engine: query/response/probe/conflict
├── service.go              # Registration: probing, announcing, goodbye
├── browser.go              # Discovery: browse, backoff, known-answer, maintenance
├── mdns.go                 # Public API: NewServer, LookupHost, LookupService
├── *_test.go               # Unit + integration tests (24 tests)
└── cmd/mdns-demo/          # Zero-config demo application

Testing

# Unit + integration tests with race detector
go test -race ./...

# Run with verbose output
go test -v -race ./...

All 24 tests pass with the -race flag enabled.

Cross-Platform Compilation

GOOS=darwin  GOARCH=arm64 go build -o mdns-demo-darwin-arm64  ./cmd/mdns-demo
GOOS=darwin  GOARCH=amd64 go build -o mdns-demo-darwin-amd64  ./cmd/mdns-demo
GOOS=linux   GOARCH=amd64 go build -o mdns-demo-linux-amd64   ./cmd/mdns-demo
GOOS=linux   GOARCH=arm64 go build -o mdns-demo-linux-arm64   ./cmd/mdns-demo
GOOS=windows GOARCH=amd64 go build -o mdns-demo-windows-amd64 ./cmd/mdns-demo
GOOS=windows GOARCH=arm64 go build -o mdns-demo-windows-arm64 ./cmd/mdns-demo

License

MIT

Documentation

Overview

Package mdns implements Multicast DNS (mDNS) as specified in RFC 6762, providing zero-configuration service discovery on local networks.

This is a from-scratch implementation with no third-party dependencies — only the Go standard library is used.

Quick Start

Register a service and discover peers:

srv, _ := mdns.NewServer(mdns.DefaultConfig())
srv.Start()
defer srv.Close()

// Advertise a service
srv.RegisterService(&mdns.ServiceInstance{
    Name: "My Printer",
    Type: "_ipp._tcp",
    Port: 631,
})

// Browse for services
browser, _ := srv.Browse("_ipp._tcp")
events, _ := browser.Start()
defer browser.Stop()

for ev := range events {
    if ev.Action == mdns.EventAdd {
        fmt.Printf("Found: %s on %s:%d\n",
            ev.Instance.Name, ev.Instance.Host, ev.Instance.Port)
    }
}

Key Types

RFC 6762 Compliance RFC 6762 Compliance" aria-label="Go to RFC 6762 Compliance">¶

This implementation covers all core sections of RFC 6762:

  • Probing (§8.1) with simultaneous probe tiebreaking (§8.2)
  • Conflict resolution with auto-rename (§9)
  • Announcing — double-announce after probe (§8.3)
  • Goodbye — TTL=0 on shutdown (§10.1)
  • Cache-flush bit semantics (§10.2)
  • Known-Answer Suppression with TTL check (§7.1)
  • TC bit multipacket queries (§7.2)
  • Exponential backoff browsing (§5.2)
  • Cache maintenance queries at 80% TTL (§5.2)
  • One-shot queries with QU bit (§5.1, §5.4)
  • NSEC negative responses (§6.1)
  • Reverse address mapping IPv4+IPv6 (§4)
  • Passive observation of failures (§10.5)
  • Source address verification (§11)
  • Legacy unicast query support (§6.7)
  • Multicast rate limiting (§6)
  • Packet validation opcode/rcode (§18.14)
  • DNS-SD service enumeration (RFC 6763)

IPv4 addresses are prioritized for service advertisement. Multiple instances on the same machine are fully supported.

Cross-Platform Support

Builds for macOS (amd64/arm64), Linux (amd64/arm64), and Windows (amd64/arm64).

Index

Constants

View Source
const (
	EventAdd    = 1
	EventRemove = 2
)

EventAdd and EventRemove indicate whether a service appeared or disappeared.

View Source
const (
	DefaultHostTTL     = 120 * time.Second // A/AAAA/SRV records
	DefaultOtherTTL    = 75 * time.Second  // PTR/TXT records
	DefaultProbeWait   = 250 * time.Millisecond
	DefaultProbeCount  = 3
	DefaultAnnounceTTL = time.Second
)

DefaultTTL values from RFC 6762 §10.

View Source
const (
	TypeA     uint16 = 1   // IPv4 address
	TypeNS    uint16 = 2   // Name Server
	TypeCNAME uint16 = 5   // Canonical Name
	TypeSOA   uint16 = 6   // Start of Authority
	TypePTR   uint16 = 12  // Domain Name Pointer
	TypeTXT   uint16 = 16  // Text
	TypeAAAA  uint16 = 28  // IPv6 address
	TypeSRV   uint16 = 33  // Service
	TypeOPT   uint16 = 41  // EDNS0 option
	TypeNSEC  uint16 = 47  // Next Secure (Negative cache)
	TypeAny   uint16 = 255 // Any / all records
)

RR type constants (DNS record types).

View Source
const (
	ClassIN   uint16 = 1   // Internet
	ClassNone uint16 = 254 // None (RFC 4034)
	ClassAny  uint16 = 255 // Any
)

RR class constants.

View Source
const DefaultDomain = "local."

DefaultDomain is the default mDNS domain.

View Source
const DefaultPort = 53533

DefaultPort is the default mDNS port (RFC 6762 §6.1 uses 5353; configurable — the user requested 53533 as the default).

View Source
const PacketBufferSize = 9000

PacketBufferSize is the max mDNS packet size (RFC 6762 §17 allows up to 9000, but the classic MTU-safe limit is 9000 for jumbo frames; we use 9000).

Variables

View Source
var (
	ErrNameTooLong    = errors.New("mdns: domain name too long (>255 bytes)")
	ErrLabelTooLong   = errors.New("mdns: label too long (>63 bytes)")
	ErrInvalidPointer = errors.New("mdns: invalid compression pointer")
	ErrPointerLoop    = errors.New("mdns: compression pointer loop detected")
	ErrTruncatedName  = errors.New("mdns: domain name is truncated")
)

Errors.

View Source
var (
	IPv4MulticastAddr = net.IPv4(224, 0, 0, 251)
	IPv6MulticastAddr = net.ParseIP("ff02::fb")
)

Default IPv4 and IPv6 mDNS multicast addresses (RFC 6762 §3).

Functions

func LookupHost

func LookupHost(ctx context.Context, host string, port int) ([]net.IP, error)

LookupHost resolves a hostname (e.g. "myhost.local.") to IP addresses using a one-shot mDNS query. It blocks until at least one address is found or the context is cancelled.

This is a convenience method that creates a temporary Server if needed. For repeated queries, use a persistent Server instance.

func RRType

func RRType(t uint16) string

RRType returns a human-readable string for common record types.

Types

type Browser

type Browser struct {
	// contains filtered or unexported fields
}

Browser discovers service instances of a given type on the network. It sends periodic multicast queries and collects responses.

func (*Browser) Instances

func (b *Browser) Instances() []*ServiceInstanceInfo

Instances returns all currently known service instances.

func (*Browser) Start

func (b *Browser) Start() (<-chan ServiceEvent, error)

Start begins the browsing loop.

func (*Browser) Stop

func (b *Browser) Stop()

Stop stops browsing and unregisters from the server.

type Cache

type Cache struct {
	// contains filtered or unexported fields
}

Cache is a thread-safe DNS record cache with TTL-based expiry. It implements the caching behaviour described in RFC 6762 §5.2 and §10.

func NewCache

func NewCache() *Cache

NewCache creates a new empty cache.

func (*Cache) AllRecords

func (c *Cache) AllRecords() []*ResourceRecord

AllRecords returns all non-expired records in the cache (for debugging).

func (*Cache) Expire

func (c *Cache) Expire() int

Expire purges all expired records from the cache.

func (*Cache) HasValidRecord

func (c *Cache) HasValidRecord(key CacheKey) bool

HasValidRecord returns true if the cache has a non-expired record for the key.

func (*Cache) KnownAnswers

func (c *Cache) KnownAnswers(name string, rrType uint16) []*ResourceRecord

KnownAnswers returns all cached records matching name+type whose remaining TTL is more than half of their original TTL. Used for Known-Answer Suppression (RFC 6762 §7.1).

func (*Cache) Lookup

func (c *Cache) Lookup(key CacheKey) []*ResourceRecord

Lookup returns all non-expired records matching the key.

func (*Cache) LookupName

func (c *Cache) LookupName(name string) []*ResourceRecord

LookupName returns all non-expired records for a given name (any type).

func (*Cache) RecordOriginalTTL

func (c *Cache) RecordOriginalTTL(key CacheKey) uint32

RecordOriginalTTL returns the original TTL of the first non-expired record matching the key.

func (*Cache) RecordRemainingTTL

func (c *Cache) RecordRemainingTTL(key CacheKey) uint32

RecordRemainingTTL returns the remaining TTL (in seconds) for the first non-expired record matching the key, or 0 if no record exists. Used by Browser to determine if a cached record needs refresh (RFC 6762 §5.2).

func (*Cache) Remove

func (c *Cache) Remove(key CacheKey)

Remove deletes all records matching the key.

func (*Cache) RemoveName

func (c *Cache) RemoveName(name string)

RemoveName removes all records for a given name.

func (*Cache) Upsert

func (c *Cache) Upsert(rr *ResourceRecord, from net.IP) bool

Upsert adds or updates a record in the cache. If cacheFlush is set (mDNS cache-flush bit), all existing records for the same name/type from a different source are removed (RFC 6762 §10.2). Returns true if the cache was modified.

type CacheKey

type CacheKey struct {
	Name string // lowercase
	Type uint16
}

CacheKey uniquely identifies a cached record by name + type.

type Config

type Config struct {
	// Port is the UDP port to listen on. Default: 53533.
	Port int

	// Domain is the mDNS domain suffix. Default: "local.".
	Domain string

	// EnableIPv6 enables IPv6 multicast. Default: false.
	EnableIPv6 bool

	// HostName is the host name to advertise (e.g. "myhost").
	// If empty, the system hostname is used.
	HostName string

	// LogFunc is called for debug logging. If nil, no logging is done.
	LogFunc func(format string, args ...any)

	// Interfaces restricts which network interfaces to use.
	// If empty, all active multicast interfaces are used.
	Interfaces []string
}

Config holds mDNS server configuration.

func DefaultConfig

func DefaultConfig() Config

DefaultConfig returns a Config with sensible defaults.

type Header struct {
	ID      uint16
	Flags   uint16
	QDCount uint16 // number of questions
	ANCount uint16 // number of answer records
	NSCount uint16 // number of authority records
	ARCount uint16 // number of additional records
}

Header is the 12-byte DNS message header (RFC 1035 §4.1.1).

type Message

type Message struct {
	Header
	Questions   []*Question
	Answers     []*ResourceRecord
	Authorities []*ResourceRecord
	Additionals []*ResourceRecord
}

Message is a complete DNS message (header + sections).

func UnpackMessage

func UnpackMessage(data []byte) (*Message, error)

UnpackMessage parses a DNS message from wire format.

func (*Message) IsProbe

func (m *Message) IsProbe() bool

IsProbe returns true if this query is a probe (has authority section records). Per RFC 6762 §8.2, a probe query contains proposed records in the Authority Section that answer the question in the Question Section.

func (*Message) IsQuery

func (m *Message) IsQuery() bool

IsQuery returns true if the message is a query (QR=0).

func (*Message) IsResponse

func (m *Message) IsResponse() bool

IsResponse returns true if the message is a response (QR=1).

func (*Message) IsTruncated

func (m *Message) IsTruncated() bool

IsTruncated returns true if the TC bit is set (RFC 6762 §7.2).

func (*Message) IsValidmDNS

func (m *Message) IsValidmDNS() bool

IsValidmDNS checks basic mDNS compliance (RFC 6762 §18):

  • opcode MUST be 0 (QUERY)
  • RCode MUST be 0 (NOERROR)
  • responses MUST NOT have a non-zero RCode

func (*Message) Opcode

func (m *Message) Opcode() uint16

Opcode returns the 4-bit opcode field from the flags.

func (*Message) Pack

func (m *Message) Pack() ([]byte, error)

Pack serializes the message to wire format.

func (*Message) RCode

func (m *Message) RCode() uint16

RCode returns the 4-bit response code from the flags.

type MulticastConn

type MulticastConn struct {
	// contains filtered or unexported fields
}

MulticastConn wraps a pair of UDP sockets (IPv4 and optionally IPv6) for sending and receiving mDNS multicast traffic.

func NewMulticastConn

func NewMulticastConn(port int, enableIPv6 bool) (*MulticastConn, error)

NewMulticastConn creates a multicast connection listening on the given port. It creates an IPv4 socket and optionally an IPv6 socket.

func (*MulticastConn) Close

func (mc *MulticastConn) Close() error

Close shuts down all sockets and goroutines.

func (*MulticastConn) Packets

func (mc *MulticastConn) Packets() <-chan ReceivedPacket

Packets returns the channel for received packets.

func (*MulticastConn) Port

func (mc *MulticastConn) Port() int

Port returns the configured mDNS port.

func (*MulticastConn) WriteMulticast

func (mc *MulticastConn) WriteMulticast(data []byte) error

WriteMulticast sends to all enabled multicast groups.

func (*MulticastConn) WriteMulticastV4

func (mc *MulticastConn) WriteMulticastV4(data []byte) (int, error)

WriteMulticastV4 sends data to the IPv4 multicast group.

func (*MulticastConn) WriteMulticastV6

func (mc *MulticastConn) WriteMulticastV6(data []byte) (int, error)

WriteMulticastV6 sends data to the IPv6 multicast group.

func (*MulticastConn) WriteTo

func (mc *MulticastConn) WriteTo(data []byte, addr *net.UDPAddr) (int, error)

WriteTo sends data to a specific unicast address.

type Question

type Question struct {
	Name  string // e.g. "_http._tcp.local."
	Type  uint16
	Class uint16 // without cache-flush bit (always 0 in questions)
}

Question is a DNS question entry.

type ReceivedPacket

type ReceivedPacket struct {
	Data []byte
	From *net.UDPAddr
}

ReceivedPacket holds a received UDP packet with its source address.

type ResourceRecord

type ResourceRecord struct {
	Name       string
	Type       uint16
	Class      uint16 // stored without cache-flush bit
	TTL        uint32
	CacheFlush bool // whether the cache-flush bit is set (for mDNS)

	// Type-specific data — only the relevant fields are populated.
	IP          net.IP   // A / AAAA
	Target      string   // PTR / CNAME / NS  (target domain name)
	Priority    uint16   // SRV
	Weight      uint16   // SRV
	Port        uint16   // SRV
	Text        []string // TXT
	NextDomain  string   // NSEC
	TypeBitMaps []uint16 // NSEC
	RawData     []byte   // for unrecognised types
}

ResourceRecord is a DNS resource record with type-specific RDATA.

func (*ResourceRecord) String

func (rr *ResourceRecord) String() string

String returns a human-readable representation of the RR.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is the core mDNS engine. It handles receiving and sending mDNS packets, responding to queries, probing for unique names, announcing services, and maintaining a record cache.

func NewServer

func NewServer(config Config) (*Server, error)

NewServer creates a new mDNS server with the given configuration.

func (*Server) Browse

func (s *Server) Browse(serviceType string) (*Browser, error)

Browse creates and starts a browser for the given service type. serviceType should be like "_http._tcp" or "_http._tcp.local.". The returned channel receives service events (add/remove). Call browser.Stop() to stop browsing.

func (*Server) Cache

func (s *Server) Cache() *Cache

Cache returns the server's record cache (for debugging/inspection).

func (*Server) Close

func (s *Server) Close() error

Close shuts down the server, sending goodbye packets for all registered services.

func (*Server) Config

func (s *Server) Config() Config

Config returns the server configuration.

func (*Server) HostIPs

func (s *Server) HostIPs() []net.IP

HostIPs returns the local IP addresses being advertised.

func (*Server) HostName

func (s *Server) HostName() string

HostName returns the hostname being advertised.

func (*Server) RegisterService

func (s *Server) RegisterService(svc *ServiceInstance) error

RegisterService registers a service instance with the mDNS server. The service will be probed for uniqueness, then announced on the network. Returns an error if a service with the same instance name is already registered.

func (*Server) ResolveHost

func (s *Server) ResolveHost(ctx context.Context, host string) ([]net.IP, error)

ResolveHost resolves a hostname using the running server's cache and network. IPv4 addresses are returned first, then IPv6 (if enabled).

func (*Server) Services

func (s *Server) Services() []*ServiceInstance

Services returns information about all registered services.

func (*Server) Start

func (s *Server) Start() error

Start begins listening for mDNS packets and starts all background tasks.

func (*Server) String

func (s *Server) String() string

String returns a debug string for the server state.

func (*Server) UnregisterService

func (s *Server) UnregisterService(svc *ServiceInstance) error

UnregisterService removes a previously registered service and sends goodbye.

type ServiceEvent

type ServiceEvent struct {
	Action   int                  // EventAdd or EventRemove
	Instance *ServiceInstanceInfo // the discovered service
}

ServiceEvent is sent to Browser subscribers when a service is found or lost.

type ServiceInstance

type ServiceInstance struct {
	// Type is the service type, e.g. "_http._tcp".
	Type string

	// Name is the instance name, e.g. "My Web Server".
	Name string

	// Domain is the domain, e.g. "local.".
	Domain string

	// Host is the hostname, e.g. "myhost.local.".
	// If empty, the server's hostname is used.
	Host string

	// Port is the service port.
	Port uint16

	// IPs is the list of IP addresses for the service.
	// If empty, the server's local addresses are used.
	IPs []net.IP

	// Text is the TXT record data.
	Text []string

	// Priority is the SRV priority.
	Priority uint16

	// Weight is the SRV weight.
	Weight uint16

	// TTL override (0 = use defaults).
	TTL uint32
}

ServiceInstance describes a service to be registered or discovered.

func (*ServiceInstance) InstanceName

func (s *ServiceInstance) InstanceName() string

InstanceName returns the full instance name, e.g. "My Web Server._http._tcp.local.".

func (*ServiceInstance) ServiceType

func (s *ServiceInstance) ServiceType() string

ServiceType returns the full service type domain, e.g. "_http._tcp.local.".

type ServiceInstanceInfo

type ServiceInstanceInfo struct {
	Name     string   // instance name (e.g. "My Web Server")
	Type     string   // service type (e.g. "_http._tcp.local.")
	Domain   string   // domain (e.g. "local.")
	Host     string   // hostname (e.g. "myhost.local.")
	Port     uint16   // service port
	IPs      []net.IP // IP addresses
	Text     []string // TXT record data
	Priority uint16   // SRV priority
	Weight   uint16   // SRV weight
}

ServiceInstanceInfo contains discovered service instance details.

func LookupService

func LookupService(ctx context.Context, serviceType string, port int) ([]*ServiceInstanceInfo, error)

LookupService discovers service instances of the given type. It blocks until the context is cancelled or the timeout expires.

func (*ServiceInstanceInfo) String

func (s *ServiceInstanceInfo) String() string

String returns a human-readable description of the service instance.

Directories

Path Synopsis
cmd
mdns-demo command
mdns-demo: Zero-config mDNS service announcer and discovery monitor.
mdns-demo: Zero-config mDNS service announcer and discovery monitor.
mdns-example command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL