diff --git a/bittorrent/bittorrent.go b/bittorrent/bittorrent.go index 0d87ebf..035dcbe 100644 --- a/bittorrent/bittorrent.go +++ b/bittorrent/bittorrent.go @@ -12,6 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Package bittorrent implements all of the abstractions used to decouple the +// protocol of a BitTorrent tracker from the logic of handling Announces and +// Scrapes. package bittorrent import ( diff --git a/bittorrent/http/tracker.go b/bittorrent/http/tracker.go index 76d9b17..00d0f0b 100644 --- a/bittorrent/http/tracker.go +++ b/bittorrent/http/tracker.go @@ -12,8 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Package http implements a BitTorrent tracker via the HTTP protocol as +// described in BEP 3 and BEP 23. package http +// Config represents all of the configurable options for an HTTP BitTorrent +// Tracker. type Config struct { Addr string ReadTimeout time.Duration @@ -23,6 +27,7 @@ type Config struct { RealIPHeader string } +// Tracker holds the state of an HTTP BitTorrent Tracker. type Tracker struct { grace *graceful.Server @@ -30,6 +35,7 @@ type Tracker struct { Config } +// NewTracker allocates a new instance of a Tracker. func NewTracker(funcs bittorrent.TrackerFuncs, cfg Config) { return &Server{ TrackerFuncs: funcs, @@ -37,6 +43,7 @@ func NewTracker(funcs bittorrent.TrackerFuncs, cfg Config) { } } +// Stop provides a thread-safe way to shutdown a currently running Tracker. func (t *Tracker) Stop() { t.grace.Stop(t.grace.Timeout) <-t.grace.StopChan() @@ -49,6 +56,8 @@ func (t *Tracker) handler() { return server } +// ListenAndServe listens on the TCP network address t.Addr and blocks serving +// BitTorrent requests until t.Stop() is called or an error is returned. func (t *Tracker) ListenAndServe() error { t.grace = &graceful.Server{ Server: &http.Server{ @@ -87,6 +96,7 @@ func (t *Tracker) ListenAndServe() error { } } +// announceRoute parses and responds to an Announce by using t.TrackerFuncs. func (t *Tracker) announceRoute(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { req, err := ParseAnnounce(r, t.RealIPHeader, t.AllowIPSpoofing) if err != nil { @@ -111,6 +121,7 @@ func (t *Tracker) announceRoute(w http.ResponseWriter, r *http.Request, _ httpro } } +// scrapeRoute parses and responds to a Scrape by using t.TrackerFuncs. func (t *Tracker) scrapeRoute(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { req, err := ParseScrape(r) if err != nil { diff --git a/bittorrent/udp/tracker.go b/bittorrent/udp/tracker.go index b21dd05..53c1525 100644 --- a/bittorrent/udp/tracker.go +++ b/bittorrent/udp/tracker.go @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Package udp implements a BitTorrent tracker via the UDP protocol as +// described in BEP 15. package udp import ( @@ -38,6 +40,7 @@ type Config struct { AllowIPSpoofing bool } +// Tracker holds the state of a UDP BitTorrent Tracker. type Tracker struct { sock *net.UDPConn closing chan struct{} @@ -47,6 +50,7 @@ type Tracker struct { Config } +// NewTracker allocates a new instance of a Tracker. func NewTracker(funcs bittorrent.TrackerFuncs, cfg Config) { return &Tracker{ closing: make(chan struct{}), @@ -55,12 +59,15 @@ func NewTracker(funcs bittorrent.TrackerFuncs, cfg Config) { } } +// Stop provides a thread-safe way to shutdown a currently running Tracker. func (t *Tracker) Stop() { close(t.closing) t.sock.SetReadDeadline(time.Now()) t.wg.Wait() } +// ListenAndServe listens on the UDP network address t.Addr and blocks serving +// BitTorrent requests until t.Stop() is called or an error is returned. func (t *Tracker) ListenAndServe() error { udpAddr, err := net.ResolveUDPAddr("udp", t.Addr) if err != nil { @@ -126,22 +133,27 @@ func (t *Tracker) ListenAndServe() error { } } +// Request represents a UDP payload received by a Tracker. type Request struct { Packet []byte IP net.IP } +// ResponseWriter implements the ability to respond to a Request via the +// io.Writer interface. type ResponseWriter struct { socket net.UDPConn addr net.UDPAddr } +// Write implements the io.Writer interface for a ResponseWriter. func (w *ResponseWriter) Write(b []byte) (int, error) { w.socket.WriteToUDP(b, w.addr) return len(b), nil } -func (t *Tracker) handlePacket(r *Request, w *ResponseWriter) (response []byte, actionName string, err error) { +// handleRequest parses and responds to a UDP Request. +func (t *Tracker) handleRequest(r *Request, w *ResponseWriter) (response []byte, actionName string, err error) { if len(r.packet) < 16 { // Malformed, no client packets are less than 16 bytes. // We explicitly return nothing in case this is a DoS attempt.