Multicast DNS library for Go

Introduction

This package allows Go processes to publish multicast DNS style records onto their local network segment. For more information about mDNS, and it's closely related cousin, Zeroconf, please visit http://www.multicastdns.org/.

Acknowledgements

Thanks to Brian Ketelsen and Miek Gieben for their feedback and suggestions. This package builds on Miek's fantastic godns library and would not have been possible without it.

Installation

This package can be installed using:

go get github.com/davecheney/mdns

For development, this package is developed with John Asmuths excellent gb utility.

Usage

Publishing mDNS records is simple

import "github.com/davecheney/mdns"

mdns.Publish("yourhost.local 60 IN A 192.168.1.100")

This places an A record into the internal zone file. Broadcast mDNS queries that match records in the internal zone file are responded to automatically. Other records types are supported, check the godoc for more information.

go doc github.com/davecheney/mdns

Tested Platforms

This package has been tested on the following platforms

  • linux/arm
  • linux/386
  • linux/amd64
  • darwin/386
  • darwin/amd64

gmx Instruments

Counters for zone queries and entries, as well as connector questions and responses are instrumented via gmx.

gmxc -p $(pgrep mdns-publisher) mdns | sort
mdns.connector.questions: 3
mdns.connector.responses: 3
mdns.zone.local.entries: 5
mdns.zone.local.queries: 12

Changelog

12/02/2012

  • Simplified mdns.Publish method, thanks to Miek Gieben for his quick work adding parsing support for SRV and PTR records.

07/02/2012

  • Updated LICENCE to a proper BSD 2 clause
  • Added gmx instrumentation
  • Updated to the Go 1 multicast API

14/10/2011 Initial Release

Comments
  • Doesnt install using go get (GO1)

    Doesnt install using go get (GO1)

    Trying to install the package with go get for Go1. I get the following response:

    $ sudo go get github.com/davecheney/mdns package dns: unrecognized import path "dns"

    Let me know if you want to run/try anything.

    Cheers!

    Ben

  • Update Pack and Unpack calls to match API changes in dns library

    Update Pack and Unpack calls to match API changes in dns library

    In miekg/dns@570bf8dc69 booleans were replaced with errors. After running go get github.com/davecheney/mdns on a fresh Go 1.0.3 install on 64 bit linux, running the publisher example yields the following error:

    # github.com/davecheney/mdns /usr/local/go/src/pkg/github.com/davecheney/mdns/mdns.go:258: non-bool ok (type error) used as if condition /usr/local/go/src/pkg/github.com/davecheney/mdns/mdns.go:271: non-bool msg.Unpack(buf[:read]) (type error) used as if condition

  • Update publisher.go

    Update publisher.go

    It looks like a typo, I couldn't get my own (non _ssh) service to register/show up on Bonjour browsers.. Your example probably works because the _ssh service already existed?

  • make README use the new go tool

    make README use the new go tool

    goinstall doesn't exist, and go install doesn't work (unless the package was already downloaded). go get is the way to download and install a package.

    also fix a typo in doc link, plus use go doc.

  • publisher.go can not working in macos

    publisher.go can not working in macos

    next is error:

    ➜  mdns ./publish
    2017/03/21 15:39:26 Failed to listen [ff02::fb]:5353: listen udp6 [ff02::fb]:5353: setsockopt: can't assign requested address
    2017/03/21 18:19:38 Could not read from &{{%!s(*net.netFD=&{{0 0 0} 5 2 2 false false udp4 0xc420076b10 <nil> <nil> {20725424}})}}: dns: bad rdata
    2017/03/21 18:19:38 Could not read from &{{%!s(*net.netFD=&{{0 0 0} 5 2 2 false false udp4 0xc420076b10 <nil> <nil> {20725424}})}}: dns: bad rdata
    2017/03/21 18:19:39 Could not read from &{{%!s(*net.netFD=&{{0 0 0} 5 2 2 false false udp4 0xc420076b10 <nil> <nil> {20725424}})}}: dns: bad rdata
    2017/03/21 18:34:28 Could not read from &{{%!s(*net.netFD=&{{0 0 0} 5 2 2 false false udp4 0xc420076b10 <nil> <nil> {20725424}})}}: dns: bad rdata
    2017/03/21 18:34:28 Could not read from &{{%!s(*net.netFD=&{{0 0 0} 5 2 2 false false udp4 0xc420076b10 <nil> <nil> {20725424}})}}: dns: bad rdata
    2017/03/21 18:34:29 Could not read from &{{%!s(*net.netFD=&{{0 0 0} 5 2 2 false false udp4 0xc420076b10 <nil> <nil> {20725424}})}}: dns: bad rdata
    2017/03/21 18:36:04 Could not read from &{{%!s(*net.netFD=&{{0 0 0} 5 2 2 false false udp4 0xc420076b10 <nil> <nil> {20725424}})}}: dns: bad rdata
    2017/03/21 18:36:04 Could not read from &{{%!s(*net.netFD=&{{0 0 0} 5 2 2 false false udp4 0xc420076b10 <nil> <nil> {20725424}})}}: dns: bad rdata
    2017/03/21 18:36:04 Could not read from &{{%!s(*net.netFD=&{{0 0 0} 5 2 2 false false udp4 0xc420076b10 <nil> <nil> {20725424}})}}: dns: bad rdata
    

    I have running a python mdns server, but i can not receive any info from it.

  • Implement using native system libraries and cgo.

    Implement using native system libraries and cgo.

    So following my offer to get involved an improve the library, I'm wondering if we should implement a sane golang wrapper around the native system stuff that already exist for this in C.

    (From O'Reilly Zeroconf Networking: The Definitive Guide) (or man (3) DNSServiceRegister)

    DNSServiceErrorType DNSServiceRegister(
             DNSServiceRef *sdRef,
             DNSServiceFlags flags,
             uint32_t interfaceIndex,
             const char *name,
             const char *regtype,
             const char *domain,
             const char *host,
             uint16_t port,
             uint16_t txtLen,
             const void *txtRecord,
             DNSServiceRegisterReply callBack,
             void *context);
    

    It's a callback driven API designed to be used with function pointers and an epoll/select loop around the underlying pseudo file descriptors returned by some of the other methods in the API.

    Deferring to the C API might have some positive effects, such as completeness of the implementation, and robustness through having already made it into Linux, and supposedly having been tested and audited along the way.

    The natural cons are that it's not supported in any way on Windows this way, where a native multicast DNS server (the likes of which you already have partially implemented) might be more portable.

  • You weren't wrong!

    You weren't wrong!

    HI Dave, you weren't wrong in IRC today when you told me that it was kindof broken. I'd love to help you pick this library up, as I'm a big fan of Multicast DNS. If I can help, I'd love to.

    I think Some interface such as mdns.AdvertiseService("192.168.150.40", 22, "My Awesome Service") (ignoring for now, how we'd specify what kind of service it is) would be amazing.

    I've forked the repository, and will try and diagnose, and cure my present failure, which is:

    $ GOPATH=$(pwd) go run main.go
    Success.. listening: 0.0.0.0:49434
    Published MDNS: stora.local. 60 IN A 192.168.1.200
    Published MDNS: 200.1.168.192.in-addr.arpa. 60 IN PTR stora.local.
    Published MDNS: _ssh._tcp.local. 60 IN PTR stora._ssh._tcp.local.
    Published MDNS: stora._ssh._tcp.local. 60 IN SRV 0 0 22 stora.local.
    Published MDNS: stora._ssh._tcp.local. 60 IN TXT ""
    Published MDNS: _service._dns-sd._udp.local. 60 IN PTR _ssh._tcp.local.
    2013/07/17 19:46:40 Cannot send: write udp6: no route to host
    exit status 1
    

    (more or less a verbatim copy from your example, except in a perfect world my service is a pure line-wise TCP socket service, so _ssh is unsuitable, and I'm on a random port every time I start)

    When I come up with something useful, I'll send you a pull request.

  • dns: buffer size too small

    dns: buffer size too small

    a coworker is sporadically seeing this on his VM (upon Publish):

    2013/01/10 16:20:40 Cound not read from &{%!s(*net.netFD=&{{0 0} 0 false 8 10 2 false 0xf840080280 0xf84008a240 0xf84008a2a0 udp6 0xf84006cce0 <nil> 0 {0 0} 0 {0 0} 0 0})}: dns: buffer size too small
    panic: runtime error: invalid memory address or nil pointer dereference
    [signal 0xb code=0x1 addr=0x28 pc=0x429d2e]
    
    goroutine 9 [running]:
    github.com/davecheney/mdns.(*connector).readloop(0xf84006cd40, 0xf8400ce000, 0x0, 0x0)
        /s/go/src/github.com/davecheney/mdns/mdns.go:190 +0x12f
    created by github.com/davecheney/mdns.(*connector).mainloop
        /s/go/src/github.com/davecheney/mdns/mdns.go:199 +0x5f
    

    this was against an older version of mikeg/dns ... but we're now testing against latest revision of that repo (will report on that later).

  • compile error against latest miekg/dns -- undefined: dns.RR_ANY

    compile error against latest miekg/dns -- undefined: dns.RR_ANY

    on ubuntu 12.04 and its golang package:

    go get -v github.com/davecheney/mdns
    github.com/davecheney/mdns (download)
    github.com/davecheney/gmx (download)
    github.com/miekg/dns (download)
    github.com/miekg/radix (download)
    github.com/davecheney/gmx
    github.com/miekg/radix
    github.com/miekg/dns
    github.com/davecheney/mdns
    # github.com/davecheney/mdns
    /s/go/src/github.com/davecheney/mdns/mdns.go:127: undefined: dns.RR_ANY
    /s/go/src/github.com/davecheney/mdns/mdns.go:130: undefined: dns.RR_ANY
    /s/go/src/github.com/davecheney/mdns/mdns.go:230: undefined: dns.RR_PTR
    /s/go/src/github.com/davecheney/mdns/mdns.go:232: rr.Ptr undefined (type dns.RR has no field or method Ptr)
    /s/go/src/github.com/davecheney/mdns/mdns.go:236: undefined: dns.RR_SRV
    /s/go/src/github.com/davecheney/mdns/mdns.go:238: rr.Target undefined (type dns.RR has no field or method Target)
    
    $ go version
    go version go1
    $ uname -a
    Linux stackato-ha3p 3.2.0-27-virtual #43-Ubuntu SMP Fri Jul 6 14:45:58 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
    $ cat /etc/*release
    DISTRIB_ID=Ubuntu
    DISTRIB_RELEASE=12.04
    DISTRIB_CODENAME=precise
    DISTRIB_DESCRIPTION="Ubuntu 12.04.1 LTS"
    NAME="Ubuntu"
    VERSION="12.04.1 LTS, Precise Pangolin"
    ID=ubuntu
    ID_LIKE=debian
    PRETTY_NAME="Ubuntu precise (12.04.1 LTS)"
    VERSION_ID="12.04"
    $ 
    
Related tags
A DNS client in Go that supports Google DNS over HTTPS

dingo A DNS client (stub resolver) implemented in Go for the Google DNS-over-HTTPS. It effectively encrypts all your DNS traffic. It also supports Ope

Nov 9, 2022
dnscrypt-proxy 2 - A flexible DNS proxy, with support for encrypted DNS protocols.
dnscrypt-proxy 2 - A flexible DNS proxy, with support for encrypted DNS protocols.

Overview A flexible DNS proxy, with support for modern encrypted DNS protocols such as DNSCrypt v2, DNS-over-HTTPS and Anonymized DNSCrypt. dnscrypt-p

Jan 3, 2023
A smol DNS server (<100 loc) that's configured with a static JSON file. Useful for split-dns.

A smol DNS server (<100 loc) that's configured with a static JSON file. Useful for split-dns.

Jul 27, 2022
DNS library in Go

Alternative (more granular) approach to a DNS library Less is more. Complete and usable DNS library. All Resource Records are supported, including the

Dec 26, 2022
DNS over HTTPS [mirror]

dnss dnss is a daemon for using DNS over HTTPS. It can act as a proxy, receiving DNS requests and resolving them using DNS-over-HTTPs (DoH). This can

Dec 26, 2022
DNS server with per-client targeted responses

GeoDNS servers This is the DNS server powering the NTP Pool system and other similar services. Questions or suggestions? For bug reports or feature re

Dec 15, 2022
GRONG is a DNS (Domain Name System) authoritative name server.It is more a research project than a production-ready program.

GRONG (Gross and ROugh Nameserver written in Go) is a DNS (Domain Name System) authoritative name server. It is intended as a research project and is

Oct 17, 2020
Resolver (DNS) cache daemon.
Resolver (DNS) cache daemon.

RESCACHED(1) Manual Page NAME rescached - DNS resolver cache daemon. Table of Contents SYNOPSIS OPTIONS DESCRIPTION FEATURES BEHIND THE DNS HOW CACHE

Nov 17, 2022
CUP - Cloudflare (DNS) Updater Program

CUP The Cloudflare (DNS) Updater CUP is a tool to turn CloudFlare DNS into a Dynamic DNS service. Documentation Documentation can be found in the docs

Jun 6, 2022
🐶 Command-line DNS Client for Humans. Written in Golang
🐶 Command-line DNS Client for Humans. Written in Golang

doggo ?? Command-line DNS client for humans doggo is a modern command-line DNS client (like dig) written in Golang. It outputs information in a neat c

Dec 29, 2022
CoreDNS is a DNS server that chains plugins
CoreDNS is a DNS server that chains plugins

CoreDNS is a DNS server/forwarder, written in Go, that chains plugins. Each plugin performs a (DNS) function. CoreDNS is a Cloud Native Computing Foun

Jan 3, 2023
Fast and lightweight DNS proxy as ad-blocker for local network with many features

Blocky Blocky is a DNS proxy and ad-blocker for the local network written in Go with following features: Features Blocking - Blocking of DNS queries w

Jan 1, 2023
Are you forwarding DNS traffic to another server for some reason, but want to make sure only queries for certain names are passed? Say no more.

DNSFWD Redirect DNS traffic to an upstream. Get Latest: wget https://github.com/C-Sto/dnsfwd/releases/latest/download/dnsfwd_linux (replace linux with

Dec 16, 2022
Fast DNS implementation for Go

Fast DNS implementation for Go Features 0 Dependency Similar Interface with net/http Fast DoH Server Co-create with fasthttp Fast DNS Client with rich

Dec 27, 2022
Gotator is a tool to generate DNS wordlists through permutations.
Gotator is a tool to generate DNS wordlists through permutations.

Gotator is a tool to generate DNS wordlists through permutations.

Dec 28, 2022
DNS lookup using Go
DNS lookup using Go

DNS lookup using Go

Dec 30, 2022
DNSTake — A fast tool to check missing hosted DNS zones that can lead to subdomain takeover
DNSTake — A fast tool to check missing hosted DNS zones that can lead to subdomain takeover

DNSTake — A fast tool to check missing hosted DNS zones that can lead to subdomain takeover

Dec 28, 2022
A tool to solve DNS pollution of GitHub website. Query the real IP address of domain names such as github.com, and refresh the domain name setting of the system hosts file.

githubDNS Target A tool to solve DNS pollution of GitHub website. Query the real IP address of domain names such as github.com, and refresh the domain

Oct 14, 2021
forward - facilitates proxying DNS messages to upstream resolvers.

forward Name forward - facilitates proxying DNS messages to upstream resolvers. Description The forward plugin re-uses already opened sockets to the u

Oct 16, 2021