Opened 14 years ago

Closed 14 years ago

Last modified 14 years ago

#1394 closed Enhancement (invalid)

Zeroconf Peer Advertising and Discovery

Reported by: Waldorf Owned by: charles
Priority: Low Milestone: None Set
Component: libtransmission Version: 1.34
Severity: Normal Keywords:



Zeroconf is a collection of protocols including ipv4 link local networking, mDNS, and DNS service-discovery. This document aims to outline an extension for BitTorrent? clients to allow them to find peers on a local-link network using the zeroconf DNS service-discovery system. It was written in the hope that clients could standardise the way in which they found peers on the local-link in order to maximize the functionality of the BitTorrent? protocol.


In order to facilitate the BitTorrent? Zeroconf Peer Advertising and Discovery Extension each host is going to be required to run a zeroconf service discovery daemon. This is relatively trivial as there are many available for free but two particularly good zeroconf implementations are:

  1. Apple's Bonjour for Mac OS X (included by default), Windows and POSIX systems
  2. Avahi recommended for Linux and BSD clients and already available in many Linux and BSD distributions.

Note that you can only run one zeroconf instance per host due to it binding to specific ports on your network interfaces, so it is not recommended to build the whole zeroconf daemon/server into your client. It is much better plug into a system wide service using the API's: it cuts down your code and allows other services e.g. http, ftp to advertise themselves using the same daemon.

Attachments (1)

zeroconf.diff (23.8 KB) - added by tiennou 14 years ago.
patch v2

Download all attachments as: .zip

Change History (15)

comment:1 Changed 14 years ago by Waldorf

Forgot to add the link to the BEP:

comment:2 Changed 14 years ago by tiennou

  • Keywords patch added

Heh, patch for this. I'm using the DNSService API, and as Avahi provides a compatible (but incomplete) wrapper, I'd thought I'd concentrate on DNSService (which has a portmapping API too (see DNSServiceNATPortMappingCreate ;-)). This patch is preliminary, and needs reviewing. It looks like I'm deadlocking the libevent thread due to the blocking nature of DNSServiceProcessResult, but I haven't been able to find out how...

comment:3 Changed 14 years ago by charles

One thing that jumps out at me as I skim the patch, is that the license is a dealbeaker.

comment:4 Changed 14 years ago by charles

tiennou: I'm not really interested in doing this, so here is a brain dump of some things I notice in the patch that you might consider for your next revision..

  • It looks like it won't link on anything but OS X.
  • dnsResolveReply() is non-functional
  • I don't understand why the more-portable evutil_vsnprintf() was replaced with the less-portable vsnprintf()
  • I don't understand why this is tied into the peer manager, rather than, say, tr_sessionInitFull() and tr_sessionClose()
  • The ##fmt macro is no longer used in libtransmission due to portability issues. :) Please refer to a trunk build to see how the macros behave now.
  • Other parts of libtransmission use #ifdef SYS_DARWIN. Is that equivalent to the #ifdef APPLE here? If not, how do they differ?
  • Mixing code blocks and variable declarations isn't strict C, though maybe that doesn't matter since it's platform-specific code :)
  • for deriving peer_id and hash in dnsBrowseReply(), please use tr_strndup() instead of tr_new0()+strcpy(). strcpy() gives most code analyzers fits because of its broken-by-design security problems.
  • peer_id' and hash' are leaked in dnsBrowseReply()
  • Do not use C++-style comments; they are not portable
  • Do the OS X level commands like DNSServiceResolve() block the libtransmission thread?
  • I don't understand why createService() is forward declared, instead of just being defined before dnsResolveReply().
  • tr_strdup_printf() would be clearer than the tr_new0()+snprintf() combos used.
  • tr_new0()ed memory needs to be freed with tr_free() rather than free()
  • In dnsBrowseReply(), fullname is leaked on line 112

comment:5 Changed 14 years ago by tiennou

charles: 'mkay ! BTW, this is really development code. I'm having some threading issues, so I've been trying to find what I'm doing wrong, but I'll try to keep it as simple as possible.

  • Sorry about the wierd changes (evutil_vsnprintf -> I'm linking against libevent trunk, and it's no more public, so I fallback to Darwin's one, APPLE -> a macro that gets set by the apple-gcc compiler, so it's always set on a Darwin machine).
  • It looks like Avahi has an API wrapper for the DNSService API. I'll investigate that it's working on a linux box, and if not, will try to do the code the Avahi-way (using preprocessor defines).
  • About the tie to the peermgr : I don't like that too ;-), but I needed to now when a torrent state changes, since we need to start/stop advertising/discovery with the torrent. If there's some API to get a torrent state, I can change to this.
  • About the DNSServiceResolve() blocking the libtransmission thread : This is exactly the problem I'm having ;-), but not when I use the calls. Quick explanation : The DNSService API is socket-based. You create a Service, then get it's file descriptor, use some select magic on it (this is code around scheduleService), and parse the DNS Responder answer with DNSServiceProcessResult. As we're using libevent, I thought I could plug this socket in libevent and expect to get my updates, but sometimes the DNSServiceProcessResult call blocks, and thus kills all Transmission events (it happens even if I make the socket non-blocking, but pretty sure I shouldn't do this ;-)).

Thanks for the advice ! I surely will cleanup this !

Changed 14 years ago by tiennou

patch v2

comment:6 follow-up: Changed 14 years ago by tiennou

Fixed the license, and almost all the little things you told me about (tr_strdup_printf is nice) ;-).

Registration works correctly (I can see my Transmission instance and its torrents when I browse to _bittorrent._tcp), but I'm not seeing any of my callbacks called. This means that browsing doesn't work (since I rely on the callback to add PEXes to the discovered torrent).

Strangely I can see dhtCallback being called (but failing) if I explicitly break in createService, and step until event_add is called, but it doesn't seem to happen when I'm not under the debugger...

comment:7 in reply to: ↑ 6 Changed 14 years ago by Waldorf

It may be interesting to allow either more general service registry or directly support the announcing of the web ui (_http._tcp) and/or even the rpc interface. (to replace the currently mac-only #1395 implementation)

comment:8 Changed 14 years ago by turbo

On Linux, running avahi, I'm using the following config (without any changes to T):

  <name replace-wildcards="yes">Torrents on %h</name>

comment:9 Changed 14 years ago by charles

#1968 has been marked as a duplicate of this ticket.

It looks like the patch here is an implementation of Apple's zeroconf, while #1968 is more about getting avahi working, but both are working toward the same goal. (The avahi interface looks a lot simpler though...)

comment:10 Changed 14 years ago by charles

  • Keywords volunteersneeded added; patch removed

comment:11 Changed 14 years ago by charles

  • Keywords patch-needed added; volunteersneeded removed

#2056 has been closed as a duplicate of this bug.

comment:12 Changed 14 years ago by charles

Here, the "patch-needed" keyword means this feature might be nice, but IMO wouldn't be used by enough people to be worth the time it takes to write, test, debug, and maintain. If someone feels the itch strongly enough to write a clean and simple patch, it would stand a good chance of being added to Transmission.

comment:13 Changed 14 years ago by charles

  • Keywords patch-needed removed
  • Resolution set to invalid
  • Status changed from new to closed

Thanks to Waldorf for setting me straight about this ticket, which I had confused with #1968.

Now I'm even less optimistic about this ticket: there are other competing methods of local peer discovery which have a much higher adoption rate: Deluge and uTorrent both use LSD, and Azureus' uses a simple multicast. The 8472 went further, describing BEP 26 as "excessively complex".

Since draft BEP 26 appears to be just sitting there going nowhere, IMO we wouldn't find many peers with this service except for other Transmission peers. Instead of going it alone we'd be better off using LSD.

comment:14 Changed 14 years ago by charles

(note on the previous comment, since I omitted the context: The 8472 a good developer who works on Azureus)

Note: See TracTickets for help on using tickets.