forked from anacrolix/torrent
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathwstracker.go
92 lines (83 loc) · 2.64 KB
/
wstracker.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package torrent
import (
"context"
"fmt"
"net"
netHttp "net/http"
"net/url"
"sync"
"github.com/anacrolix/log"
"github.com/gorilla/websocket"
"github.com/pion/datachannel"
"github.com/anacrolix/torrent/tracker"
httpTracker "github.com/anacrolix/torrent/tracker/http"
"github.com/anacrolix/torrent/webtorrent"
)
type websocketTrackerStatus struct {
url url.URL
tc *webtorrent.TrackerClient
}
func (me websocketTrackerStatus) statusLine() string {
return fmt.Sprintf("%+v", me.tc.Stats())
}
func (me websocketTrackerStatus) URL() *url.URL {
return &me.url
}
type refCountedWebtorrentTrackerClient struct {
webtorrent.TrackerClient
refCount int
}
type websocketTrackers struct {
PeerId [20]byte
Logger log.Logger
GetAnnounceRequest func(event tracker.AnnounceEvent, infoHash [20]byte) (tracker.AnnounceRequest, error)
OnConn func(datachannel.ReadWriteCloser, webtorrent.DataChannelContext)
mu sync.Mutex
clients map[string]*refCountedWebtorrentTrackerClient
Proxy httpTracker.ProxyFunc
DialContext func(ctx context.Context, network, addr string) (net.Conn, error)
WebsocketTrackerHttpHeader func() netHttp.Header
ICEServers []string
}
func (me *websocketTrackers) Get(url string, infoHash [20]byte) (*webtorrent.TrackerClient, func()) {
me.mu.Lock()
defer me.mu.Unlock()
value, ok := me.clients[url]
if !ok {
dialer := &websocket.Dialer{Proxy: me.Proxy, NetDialContext: me.DialContext, HandshakeTimeout: websocket.DefaultDialer.HandshakeTimeout}
value = &refCountedWebtorrentTrackerClient{
TrackerClient: webtorrent.TrackerClient{
Dialer: dialer,
Url: url,
GetAnnounceRequest: me.GetAnnounceRequest,
PeerId: me.PeerId,
OnConn: me.OnConn,
Logger: me.Logger.WithText(func(m log.Msg) string {
return fmt.Sprintf("tracker client for %q: %v", url, m)
}),
WebsocketTrackerHttpHeader: me.WebsocketTrackerHttpHeader,
ICEServers: me.ICEServers,
},
}
value.TrackerClient.Start(func(err error) {
if err != nil {
me.Logger.Printf("error running tracker client for %q: %v", url, err)
}
})
if me.clients == nil {
me.clients = make(map[string]*refCountedWebtorrentTrackerClient)
}
me.clients[url] = value
}
value.refCount++
return &value.TrackerClient, func() {
me.mu.Lock()
defer me.mu.Unlock()
value.TrackerClient.CloseOffersForInfohash(infoHash)
value.refCount--
if value.refCount == 0 {
value.TrackerClient.Close()
delete(me.clients, url)
}
}
}