Skip to content

Commit

Permalink
Docs: Update README, LICENSE and doc.go
Browse files Browse the repository at this point in the history
  • Loading branch information
betamos committed Aug 28, 2023
1 parent 9fe4b84 commit 30f038e
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 96 deletions.
5 changes: 1 addition & 4 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
The MIT License (MIT)

Copyright (c) 2023 Didrik Nordström
Copyright (c) 2016 Stefan Smarzly
Copyright (c) 2014 Oleksandr Lobunets

Note: Copyright for portions of project zeroconf.sd are held by Oleksandr
Lobunets, 2014, as part of project bonjour. All other copyright for
project zeroconf.sd are held by Stefan Smarzly, 2016.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
Expand Down
163 changes: 82 additions & 81 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,110 +1,111 @@
ZeroConf: Service Discovery with mDNS
=====================================
Zeroconf Service Discovery
==========================
[![GoDoc](https://godoc.org/github.com/betamos/zeroconf?status.svg)](https://godoc.org/github.com/betamos/zeroconf)
[![Tests](https://github.com/betamos/zeroconf/actions/workflows/go-test.yml/badge.svg)](https://github.com/libp2p/zeroconf/actions/workflows/go-test.yml)

NOTE: This is just a fork with some added features and fixes due to upstreaming difficulty.
Zeroconf is a pure Golang library for discovering and publishing services on the local network.

ZeroConf is a pure Golang library that employs Multicast DNS-SD for
It is tested on Windows, macOS and Linux and is compatible with [Avahi](http://avahi.org/),
[Bonjour](https://developer.apple.com/bonjour/), etc. It implements:

* browsing and resolving services in your network
* registering own services
- [RFC 6762](https://tools.ietf.org/html/rfc6762): Multicast DNS (mDNS)
- [RFC 6763](https://tools.ietf.org/html/rfc6763): DNS Service Discovery (DNS-SD)

in the local network.
## Usage

It basically implements aspects of the standards
[RFC 6762](https://tools.ietf.org/html/rfc6762) (mDNS) and
[RFC 6763](https://tools.ietf.org/html/rfc6763) (DNS-SD).
Though it does not support all requirements yet, the aim is to provide a compliant solution in the long-term with the community.
First, let's install the library:

By now, it should be compatible to [Avahi](http://avahi.org/) (tested) and Apple's Bonjour (untested).
Target environments: private LAN/Wifi, small or isolated networks.
```bash
$ go get -u github.com/betamos/zeroconf
```

[![GoDoc](https://godoc.org/github.com/libp2p/zeroconf?status.svg)](https://godoc.org/github.com/libp2p/zeroconf)
[![Go Report Card](https://goreportcard.com/badge/github.com/libp2p/zeroconf)](https://goreportcard.com/report/github.com/libp2p/zeroconf)
[![Tests](https://github.com/libp2p/zeroconf/actions/workflows/go-test.yml/badge.svg)](https://github.com/libp2p/zeroconf/actions/workflows/go-test.yml)
Then, let's import the library and define a service type:

## Install
Nothing is as easy as that:
```bash
$ go get -u github.com/libp2p/zeroconf/v2
```go
import "github.com/betamos/zeroconf"

var chat = zeroconf.NewType("_chat._tcp")
```

## Browse for services in your local network
Now, let's announce our own presence and find others we can chat with:

```go
instances := make(chan *zeroconf.Instance)
go func(results <-chan *zeroconf.Instance) {
for instance := range results {
log.Println(instance)
}
log.Println("No more instances.")
}(instances)

ctx, cancel := context.WithTimeout(context.Background(), time.Second*15)
defer cancel()
// Discover all services on the network (e.g. _workstation._tcp)
err = zeroconf.Browse(ctx, "_workstation._tcp", "local.", instances)
// This is the chat service running on this machine
self := zeroconf.NewService(chat, "Jennifer", 8080)

client, err := zeroconf.New().
Publish(self).
Browse(chat, func(e zeroconf.Event) {
// Prints e.g. `[+] Bryan`, but this would be a good time to connect to the peer!
log.Println(e.Op, e.Name)
})
.Open()
if err != nil {
log.Fatalln("Failed to browse:", err.Error())
return err
}

<-ctx.Done()
defer client.Close() // Don't forget to close, to notify others that we're going away
```
A subtype may added to service name to narrow the set of results. E.g. to browse `_workstation._tcp` with subtype `_windows`, use`_workstation._tcp,_windows`.

See https://github.com/libp2p/zeroconf/blob/master/examples/resolv/client.go.
## CLI

## Lookup a specific service instance
The package contains a CLI which can both browse and publish:

```go
// Example filled soon.
```bash
# Browse and publish at the same time (run on two different machines)
go run ./cmd -b -p "Computer A"
go run ./cmd -b -p "Computer B"

# Or why not find some Apple devices?
go run ./cmd -b -type _rdlink._tcp
```

## Register a service
You should see services coming and going, like so:

```go
server, err := zeroconf.Register("GoZeroconf", "_workstation._tcp", "local.", 42424, []string{"txtv=0", "lo=1", "la=2"}, nil)
if err != nil {
panic(err)
}
defer server.Shutdown()

// Clean exit.
sig := make(chan os.Signal, 1)
signal.Notify(sig, os.Interrupt, syscall.SIGTERM)
select {
case <-sig:
// Exit by user
case <-time.After(time.Second * 120):
// Exit by timeout
}

log.Println("Shutting down.")
```
Multiple subtypes may be added to service name, separated by commas. E.g `_workstation._tcp,_windows` has subtype `_windows`.
01:23:45 [+] Someone's iPhone ...
01:23:47 [+] Some Macbook ...
01:26:45 [-] Someone's iPhone ...
```

## Features

See https://github.com/libp2p/zeroconf/blob/master/examples/register/server.go.
* [x] Publish and browse on the same UDP port
* [x] Monitors for updates, expiry and unannouncements of services
* [x] Handles IPv4 and IPv6 on multiple network interfaces
* [x] Minimal network traffic
* [x] Hot-reload after network changes or sleeping (see below)
* [x] Uses modern Go 1.21 with `slog`, `netip`, etc

## Hot-reloading

Some devices, like laptops, move around a lot. Whenever a device connects to a new network,
or wakes up after sleep, the zeroconf client needs to be aware of these changes for both
browsing and publishing to work correctly:

```go
// Reloads network interfaces and resets periodic timers
client.Reload()
```

## Features and ToDo's
This list gives a quick impression about the state of this library.
See what needs to be done and submit a pull request :)
Monitoring for changes is out of scope for this project. You could use a ticker and reload
every N minutes.

* [x] Browse / Lookup / Register services
* [x] Multiple IPv6 / IPv4 addresses support
* [x] Send multiple probes (exp. back-off) if no service answers (*)
* [x] Timestamp instances for TTL checks
* [ ] Compare new multicasts with already received services
## Missing features

_Notes:_
- **Conflict resolution** is not implemented, so it's important to pick a unique service name to
avoid name collisions. If you don't have a unique persistent identifier, you could add randomized
suffix, e.g "Jennifer [3298]".
- **One-shot queries** (lookup) is currently not supported. As a workaround, you can browse
and filter out the instance yourself.
- **Meta-queries** are also not supported.

(*) The denoted features might not be perfectly standards compliant, but shouldn't cause any problems.
Some tests showed improvements in overall robustness and performance with the features enabled.
## About

## Credits
Great thanks to [hashicorp](https://github.com/hashicorp/mdns) and to [oleksandr](https://github.com/oleksandr/bonjour) and all contributing authors for the code this projects bases upon.
Large parts of the code are still the same.
This project is a near-complete rewrite by Didrik Nordström in 2023.
However, archeologists will find a long lineage:

However, there are several reasons why I decided to create a fork of the original project:
The previous project seems to be unmaintained. There are several useful pull requests waiting. I merged most of them in this project.
Still, the implementation has some bugs and lacks some other features that make it quite unreliable in real LAN environments when running continously.
Last but not least, the aim for this project is to build a solution that targets standard conformance in the long term with the support of the community.
Though, resiliency should remain a top goal.
- [hashicorp/mdns](https://github.com/hashicorp/mdns)
- [oleksandr/bonjour](https://github.com/oleksandr/bonjour)
- [grandcat/zeroconf](https://github.com/grandcat/zeroconf)
- [libp2p/zeroconf](https://github.com/libp2p/zeroconf)
- [betamos/zeroconf](https://github.com/betamos/zeroconf) <- You are here
16 changes: 5 additions & 11 deletions doc.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
// Package zeroconf is a pure Golang library that employs Multicast DNS-SD for
// browsing and resolving services in your network and registering own services
// in the local network.
// Zeroconf is a pure Golang library for discovering and publishing services on the local network.
//
// It basically implements aspects of the standards
// RFC 6762 (mDNS) and
// RFC 6763 (DNS-SD).
// Though it does not support all requirements yet, the aim is to provide a
// complient solution in the long-term with the community.
// It is tested on Windows, macOS and Linux and is compatible with Avahi, Bonjour, etc.
// It implements:
//
// By now, it should be compatible to [Avahi](http://avahi.org/) (tested) and
// Apple's Bonjour (untested). Should work in the most office, home and private
// environments.
// - RFC 6762: Multicast DNS (mDNS)
// - RFC 6763: DNS Service Discovery (DNS-SD)
package zeroconf

0 comments on commit 30f038e

Please sign in to comment.