Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webtorrent support #393

Merged
merged 20 commits into from
Apr 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -461,12 +461,17 @@ func (cl *Client) acceptConnections(l net.Listener) {
}
}

func regularConnString(nc net.Conn) string {
return fmt.Sprintf("%s-%s", nc.LocalAddr(), nc.RemoteAddr())
}

func (cl *Client) incomingConnection(nc net.Conn) {
defer nc.Close()
if tc, ok := nc.(*net.TCPConn); ok {
tc.SetLinger(0)
}
c := cl.newConnection(nc, false, nc.RemoteAddr(), nc.RemoteAddr().Network())
c := cl.newConnection(nc, false, nc.RemoteAddr(), nc.RemoteAddr().Network(),
regularConnString(nc))
c.Discovery = PeerSourceIncoming
cl.runReceivedConn(c)
}
Expand Down Expand Up @@ -621,10 +626,12 @@ func (cl *Client) noLongerHalfOpen(t *Torrent, addr string) {
t.openNewConns()
}

// Performs initiator handshakes and returns a connection. Returns nil
// *connection if no connection for valid reasons.
func (cl *Client) handshakesConnection(ctx context.Context, nc net.Conn, t *Torrent, encryptHeader bool, remoteAddr net.Addr, network string) (c *PeerConn, err error) {
c = cl.newConnection(nc, true, remoteAddr, network)
// Performs initiator handshakes and returns a connection. Returns nil *connection if no connection
// for valid reasons.
func (cl *Client) handshakesConnection(ctx context.Context, nc net.Conn, t *Torrent, encryptHeader bool, remoteAddr net.Addr,
network, connString string,
) (c *PeerConn, err error) {
c = cl.newConnection(nc, true, remoteAddr, network, connString)
c.headerEncrypted = encryptHeader
ctx, cancel := context.WithTimeout(ctx, cl.config.HandshakesTimeout)
defer cancel()
Expand All @@ -640,8 +647,7 @@ func (cl *Client) handshakesConnection(ctx context.Context, nc net.Conn, t *Torr
return
}

// Returns nil connection and nil error if no connection could be established
// for valid reasons.
// Returns nil connection and nil error if no connection could be established for valid reasons.
func (cl *Client) establishOutgoingConnEx(t *Torrent, addr net.Addr, obfuscatedHeader bool) (*PeerConn, error) {
dialCtx, cancel := context.WithTimeout(context.Background(), func() time.Duration {
cl.rLock()
Expand All @@ -657,7 +663,7 @@ func (cl *Client) establishOutgoingConnEx(t *Torrent, addr net.Addr, obfuscatedH
}
return nil, errors.New("dial failed")
}
c, err := cl.handshakesConnection(context.Background(), nc, t, obfuscatedHeader, addr, dr.Network)
c, err := cl.handshakesConnection(context.Background(), nc, t, obfuscatedHeader, addr, dr.Network, regularConnString(nc))
if err != nil {
nc.Close()
}
Expand Down Expand Up @@ -850,6 +856,7 @@ func (cl *Client) runReceivedConn(c *PeerConn) {
cl.runHandshookConn(c, t)
}

// Client lock must be held before entering this.
func (cl *Client) runHandshookConn(c *PeerConn, t *Torrent) {
c.setTorrent(t)
if c.PeerID == cl.peerID {
Expand Down Expand Up @@ -1227,7 +1234,7 @@ func (cl *Client) banPeerIP(ip net.IP) {
cl.badPeerIPs[ip.String()] = struct{}{}
}

func (cl *Client) newConnection(nc net.Conn, outgoing bool, remoteAddr net.Addr, network string) (c *PeerConn) {
func (cl *Client) newConnection(nc net.Conn, outgoing bool, remoteAddr net.Addr, network, connString string) (c *PeerConn) {
c = &PeerConn{
conn: nc,
outgoing: outgoing,
Expand All @@ -1237,6 +1244,7 @@ func (cl *Client) newConnection(nc net.Conn, outgoing bool, remoteAddr net.Addr,
writeBuffer: new(bytes.Buffer),
remoteAddr: remoteAddr,
network: network,
connString: connString,
}
c.logger = cl.logger.WithValues(c,
log.Debug, // I want messages to default to debug, and can set it here as it's only used by new code
Expand Down
32 changes: 32 additions & 0 deletions cmd/torrent/announce.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package main

import (
"fmt"

"github.com/anacrolix/tagflag"
"github.com/davecgh/go-spew/spew"

"github.com/anacrolix/torrent"
"github.com/anacrolix/torrent/tracker"
)

func announceErr(args []string, parent *tagflag.Parser) error {
var flags struct {
tagflag.StartPos
Tracker string
InfoHash torrent.InfoHash
}
tagflag.ParseArgs(&flags, args, tagflag.Parent(parent))
response, err := tracker.Announce{
TrackerUrl: flags.Tracker,
Request: tracker.AnnounceRequest{
InfoHash: flags.InfoHash,
Port: uint16(torrent.NewDefaultClientConfig().ListenPort),
},
}.Do()
if err != nil {
return fmt.Errorf("doing announce: %w", err)
}
spew.Dump(response)
return nil
}
23 changes: 22 additions & 1 deletion cmd/torrent/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ var flags = struct {
PieceStates bool
Quiet bool `help:"discard client logging"`
Dht bool
TcpPeers bool
UtpPeers bool
tagflag.StartPos
Torrent []string `arity:"+" help:"torrent file path or magnet uri"`
}{
Expand Down Expand Up @@ -178,9 +180,28 @@ func main() {
}

func mainErr() error {
tagflag.Parse(&flags)
var flags struct {
tagflag.StartPos
Command string
Args tagflag.ExcessArgs
}
parser := tagflag.Parse(&flags, tagflag.ParseIntermixed(false))
switch flags.Command {
case "announce":
return announceErr(flags.Args, parser)
case "download":
return downloadErr(flags.Args, parser)
default:
return fmt.Errorf("unknown command %q", flags.Command)
}
}

func downloadErr(args []string, parent *tagflag.Parser) error {
tagflag.ParseArgs(&flags, args, tagflag.Parent(parent))
defer envpprof.Stop()
clientConfig := torrent.NewDefaultClientConfig()
clientConfig.DisableTCP = !flags.TcpPeers
clientConfig.DisableUTP = !flags.UtpPeers
clientConfig.DisableAcceptRateLimiting = true
clientConfig.NoDHT = !flags.Dht
clientConfig.Debug = flags.Debug
Expand Down
10 changes: 6 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ require (
github.com/anacrolix/missinggo v1.2.1
github.com/anacrolix/missinggo/perf v1.0.0
github.com/anacrolix/missinggo/v2 v2.4.1-0.20200227072623-f02f6484f997
github.com/anacrolix/multiless v0.0.0-20191223025854-070b7994e841
github.com/anacrolix/multiless v0.0.0-20200413040533-acfd16f65d5d
github.com/anacrolix/sync v0.2.0
github.com/anacrolix/tagflag v1.0.1
github.com/anacrolix/tagflag v1.1.1-0.20200411025953-9bb5209d56c2
github.com/anacrolix/upnp v0.1.1
github.com/anacrolix/utp v0.0.0-20180219060659-9e0e1d1d0572
github.com/bradfitz/iter v0.0.0-20191230175014-e8f45d346db8
Expand All @@ -22,13 +22,15 @@ require (
github.com/elliotchance/orderedmap v1.2.0
github.com/fsnotify/fsnotify v1.4.7
github.com/google/btree v1.0.0
github.com/gorilla/websocket v1.4.2
github.com/jessevdk/go-flags v1.4.0
github.com/mattn/go-sqlite3 v2.0.2+incompatible
github.com/pion/datachannel v1.4.16
github.com/pion/webrtc/v2 v2.2.4
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.4.0
github.com/stretchr/testify v1.5.1
github.com/tinylib/msgp v1.1.1 // indirect
go.etcd.io/bbolt v1.3.4
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa // indirect
golang.org/x/time v0.0.0-20191024005414-555d28b269f0
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543
)
Expand Down
Loading