tracker

package
v0.0.0-...-e294334 Latest Latest
Warning

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

Go to latest
Published: Jan 13, 2024 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package tracker supplies some common type interfaces of the BT tracker protocol.

Index

Examples

Constants

View Source
const (
	None      uint32 = iota
	Completed        // The local peer just completed the torrent.
	Started          // The local peer has just resumed this torrent.
	Stopped          // The local peer is leaving the swarm.
)

Predefine some announce events.

BEP 3

Variables

View Source
var PeerAddress net.Addr

Force a peer address to be used

Functions

This section is empty.

Types

type AnnounceRequest

type AnnounceRequest struct {
	InfoHash metainfo.Hash // Required
	PeerID   metainfo.Hash // Required

	Uploaded   int64  // Required, but default: 0, which should be only used for test or first.
	Downloaded int64  // Required, but default: 0, which should be only used for test or first.
	Left       int64  // Required, but default: 0, which should be only used for test or last.
	Event      uint32 // Required, but default: 0

	IP      net.Addr // Optional
	Key     int32    // Optional
	NumWant int32    // Optional, BEP 15: -1 for default. But we use 0 as default.
	Port    uint16   // Optional
}

AnnounceRequest is the common Announce request.

BEP 3, 15

func (*AnnounceRequest) ToHTTPAnnounceRequest

func (ar *AnnounceRequest) ToHTTPAnnounceRequest() *httptracker.AnnounceRequest

ToHTTPAnnounceRequest creates a new httptracker.AnnounceRequest from itself.

func (*AnnounceRequest) ToUDPAnnounceRequest

func (ar *AnnounceRequest) ToUDPAnnounceRequest() *udptracker.AnnounceRequest

ToUDPAnnounceRequest creates a new udptracker.AnnounceRequest from itself.

type AnnounceResponse

type AnnounceResponse struct {
	Interval  uint32
	Leechers  uint32
	Seeders   uint32
	Addresses []metainfo.Address
}

AnnounceResponse is a common Announce response.

BEP 3, 15

func (*AnnounceResponse) FromHTTPAnnounceResponse

func (ar *AnnounceResponse) FromHTTPAnnounceResponse(r httptracker.AnnounceResponse)

FromHTTPAnnounceResponse sets itself from r.

func (*AnnounceResponse) FromUDPAnnounceResponse

func (ar *AnnounceResponse) FromUDPAnnounceResponse(r udptracker.AnnounceResponse)

FromUDPAnnounceResponse sets itself from r.

type Client

type Client interface {
	Announce(context.Context, AnnounceRequest) (AnnounceResponse, error)
	Scrape(context.Context, []metainfo.Hash) (ScrapeResponse, error)
	String() string
	Close() error
}

Client is the interface of BT tracker client.

Example
package main

import (
	"context"
	"errors"
	"fmt"
	"log"
	"net"
	"time"

	"github.com/eyedeekay/go-i2p-bt/metainfo"
	"github.com/eyedeekay/go-i2p-bt/tracker/udptracker"
)

type testHandler struct{}

func (testHandler) OnConnect(raddr net.Addr) (err error) { return }
func (testHandler) OnAnnounce(raddr net.Addr, req udptracker.AnnounceRequest) (
	r udptracker.AnnounceResponse, err error) {
	if req.Port != 80 {
		err = errors.New("port is not 80")
		return
	}

	if len(req.Exts) > 0 {
		for i, ext := range req.Exts {
			switch ext.Type {
			case udptracker.URLData:
				fmt.Printf("Extensions[%d]: URLData(%s)\n", i, string(ext.Data))
			default:
				fmt.Printf("Extensions[%d]: %s\n", i, ext.Type.String())
			}
		}
	}

	r = udptracker.AnnounceResponse{
		Interval:  1,
		Leechers:  2,
		Seeders:   3,
		Addresses: []metainfo.Address{{IP: &net.IPAddr{IP: net.ParseIP("127.0.0.1")}, Port: 8000}},
	}
	return
}
func (testHandler) OnScrap(raddr net.Addr, infohashes []metainfo.Hash) (
	rs []udptracker.ScrapeResponse, err error) {
	rs = make([]udptracker.ScrapeResponse, len(infohashes))
	for i := range infohashes {
		rs[i] = udptracker.ScrapeResponse{
			Seeders:   uint32(i)*10 + 1,
			Leechers:  uint32(i)*10 + 2,
			Completed: uint32(i)*10 + 3,
		}
	}
	return
}

func main() {
	// Start the UDP tracker server
	sconn, err := net.ListenPacket("udp4", "127.0.0.1:8000")
	if err != nil {
		log.Fatal(err)
	}
	server := udptracker.NewServer(sconn, testHandler{})
	defer server.Close()
	go server.Run()

	// Wait for the server to be started
	time.Sleep(time.Second)

	// Create a client and dial to the UDP tracker server.
	client, err := NewClient("udp://127.0.0.1:8000/path?a=1&b=2")
	if err != nil {
		log.Fatal(err)
	}

	// Send the ANNOUNCE request to the UDP tracker server,
	// and get the ANNOUNCE response.
	req := AnnounceRequest{IP: &net.IPAddr{IP: net.ParseIP("127.0.0.1")}, Port: 80}
	resp, err := client.Announce(context.Background(), req)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Interval: %d\n", resp.Interval)
	fmt.Printf("Leechers: %d\n", resp.Leechers)
	fmt.Printf("Seeders: %d\n", resp.Seeders)
	for i, addr := range resp.Addresses {
		fmt.Printf("Address[%d].IP: %s\n", i, addr.IP.String())
		fmt.Printf("Address[%d].Port: %d\n", i, addr.Port)
	}

	// Send the SCRAPE request to the UDP tracker server,
	// and get the SCRAPE respsone.
	h1 := metainfo.Hash{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}
	h2 := metainfo.Hash{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2}
	rs, err := client.Scrape(context.Background(), []metainfo.Hash{h1, h2})
	if err != nil {
		log.Fatal(err)
	} else if len(rs) != 2 {
		log.Fatalf("%+v", rs)
	}

	for i, r := range rs {
		fmt.Printf("%s.Seeders: %d\n", i.HexString(), r.Seeders)
		fmt.Printf("%s.Leechers: %d\n", i.HexString(), r.Leechers)
		fmt.Printf("%s.Completed: %d\n", i.HexString(), r.Completed)
	}

}
Output:

Extensions[0]: URLData(/path?a=1&b=2)
Interval: 1
Leechers: 2
Seeders: 3
Address[0].IP: 127.0.0.1
Address[0].Port: 8000
0101010101010101010101010101010101010101.Seeders: 1
0101010101010101010101010101010101010101.Leechers: 2
0101010101010101010101010101010101010101.Completed: 3
0202020202020202020202020202020202020202.Seeders: 11
0202020202020202020202020202020202020202.Leechers: 12
0202020202020202020202020202020202020202.Completed: 13

func NewClient

func NewClient(connURL string, conf ...ClientConfig) (c Client, err error)

NewClient returns a new Client.

type ClientConfig

type ClientConfig struct {
	// The ID of the local client peer.
	ID metainfo.Hash

	// The http client used only the tracker client is based on HTTP.
	HTTPClient *http.Client
}

ClientConfig is used to configure the defalut client implementation.

type GetPeersResult

type GetPeersResult struct {
	Error   error // nil stands for success. Or, for failure.
	Tracker string
	Resp    AnnounceResponse
}

GetPeersResult represents the result of getting the peers from the tracker.

func GetPeers

func GetPeers(ctx context.Context, id, infohash metainfo.Hash, trackers []string) []GetPeersResult

GetPeers gets the peers from the trackers.

Notice: the returned chan will be closed when all the requests end.

type ScrapeResponse

type ScrapeResponse map[metainfo.Hash]ScrapeResponseResult

ScrapeResponse is a commont Scrape response.

func (ScrapeResponse) FromHTTPScrapeResponse

func (sr ScrapeResponse) FromHTTPScrapeResponse(r httptracker.ScrapeResponse)

FromHTTPScrapeResponse sets itself from r.

func (ScrapeResponse) FromUDPScrapeResponse

func (sr ScrapeResponse) FromUDPScrapeResponse(hs []metainfo.Hash,
	r []udptracker.ScrapeResponse)

FromUDPScrapeResponse sets itself from hs and r.

type ScrapeResponseResult

type ScrapeResponseResult struct {
	// Seeders is the number of active peers that have completed downloading.
	Seeders uint32 `bencode:"complete"` // BEP 15, 48

	// Leechers is the number of active peers that have not completed downloading.
	Leechers uint32 `bencode:"incomplete"` // BEP 15, 48

	// Completed is the total number of peers that have ever completed downloading.
	Completed uint32 `bencode:"downloaded"` // BEP 15, 48
}

ScrapeResponseResult is a commont Scrape response result.

func (*ScrapeResponseResult) DecodeFrom

func (r *ScrapeResponseResult) DecodeFrom(b []byte)

DecodeFrom decodes the response from b.

func (ScrapeResponseResult) EncodeTo

func (r ScrapeResponseResult) EncodeTo(buf *bytes.Buffer)

EncodeTo encodes the response to buf.

Directories

Path Synopsis
Package httptracker implements the tracker protocol based on HTTP/HTTPS.
Package httptracker implements the tracker protocol based on HTTP/HTTPS.
Package udptracker implements the tracker protocol based on UDP.
Package udptracker implements the tracker protocol based on UDP.

Jump to

Keyboard shortcuts

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