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

Add proxy options to allow proxying tracker and peer connections #874

Open
wants to merge 16 commits into
base: master
from
Open
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file or symbol
Failed to load files and symbols.

Always

Just for now

Next

Allow proxying tracker calls and peer connexions in node (TCP/UDP)

  • Loading branch information
yciabaud committed Jul 24, 2016
commit 10d816e95d1ba5554a0c62323754b20b933eefcc
@@ -16,6 +16,7 @@ var parseTorrent = require('parse-torrent')
var path = require('path')
var Peer = require('simple-peer')
var randombytes = require('randombytes')
var Socks = require('socks')
var speedometer = require('speedometer')
var zeroFill = require('zero-fill')

@@ -106,6 +107,26 @@ function WebTorrent (opts) {
if (global.WRTC && !self.tracker.wrtc) self.tracker.wrtc = global.WRTC
}

// Proxy
self.proxyOpts = opts.proxyOpts
if (self.proxyOpts) {
self.proxyOpts.proxyTrackerConnections = self.proxyOpts.proxyTrackerConnections !== false
self.proxyOpts.proxyPeerConnections = self.proxyOpts.proxyPeerConnections !== false

if (self.proxyOpts.socksProxy) {
if (!self.proxyOpts.socksProxy.proxy) self.proxyOpts.socksProxy.proxy = {}
if (!self.proxyOpts.socksProxy.proxy.type) self.proxyOpts.socksProxy.proxy.type = 5

// Create HTTP agents from socks proxy if needed
if (!self.proxyOpts.httpAgent) {
self.proxyOpts.httpAgent = new Socks.Agent(self.proxyOpts.socksProxy, false)
}
if (!self.proxyOpts.httpsAgent) {
self.proxyOpts.httpsAgent = new Socks.Agent(self.proxyOpts.socksProxy, true)
}
}
}

if (typeof TCPPool === 'function') {
self._tcpPool = new TCPPool(self)
} else {
@@ -26,6 +26,7 @@ var Piece = require('torrent-piece')
var pump = require('pump')
var randomIterate = require('random-iterate')
var sha1 = require('simple-sha1')
var Socks = require('socks')
var speedometer = require('speedometer')
var uniq = require('uniq')
var utMetadata = require('ut_metadata')
@@ -1658,38 +1659,56 @@ Torrent.prototype._drain = function () {
port: parts[1]
}

var conn = peer.conn = net.connect(opts)
if (self.client.proxyOpts && self.client.proxyOpts.socksProxy && self.client.proxyOpts.proxyPeerConnections) {
var proxyOpts = extend(self.client.proxyOpts.socksProxy, {
command: 'connect',
target: opts
})

conn.once('connect', function () { peer.onConnect() })
conn.once('error', function (err) { peer.destroy(err) })
peer.startConnectTimeout()
Socks.createConnection(proxyOpts, onGotSocket)
} else {
onGotSocket(null, net.connect(opts))
}

// When connection closes, attempt reconnect after timeout (with exponential backoff)
conn.on('close', function () {
if (self.destroyed) return
function onGotSocket (err, socket) {
if (err) return peer.destroy(err)

// TODO: If torrent is done, do not try to reconnect after a timeout
var conn = peer.conn = socket

if (peer.retries >= RECONNECT_WAIT.length) {
self._debug(
'conn %s closed: will not re-add (max %s attempts)',
peer.addr, RECONNECT_WAIT.length
)
return
if (self.client.proxyOpts && self.client.proxyOpts.proxyPeerConnections) {
peer.onConnect()
}
conn.once('connect', function () { peer.onConnect() })
conn.once('error', function (err) { peer.destroy(err) })
peer.startConnectTimeout()

var ms = RECONNECT_WAIT[peer.retries]
self._debug(
'conn %s closed: will re-add to queue in %sms (attempt %s)',
peer.addr, ms, peer.retries + 1
)
// When connection closes, attempt reconnect after timeout (with exponential backoff)
conn.on('close', function () {
if (self.destroyed) return

var reconnectTimeout = setTimeout(function reconnectTimeout () {
var newPeer = self._addPeer(peer.addr)
if (newPeer) newPeer.retries = peer.retries + 1
}, ms)
if (reconnectTimeout.unref) reconnectTimeout.unref()
})
// TODO: If torrent is done, do not try to reconnect after a timeout

if (peer.retries >= RECONNECT_WAIT.length) {
self._debug(
'conn %s closed: will not re-add (max %s attempts)',
peer.addr, RECONNECT_WAIT.length
)
return
}

var ms = RECONNECT_WAIT[peer.retries]
self._debug(
'conn %s closed: will re-add to queue in %sms (attempt %s)',
peer.addr, ms, peer.retries + 1
)

var reconnectTimeout = setTimeout(function reconnectTimeout () {
var newPeer = self._addPeer(peer.addr)
if (newPeer) newPeer.retries = peer.retries + 1
}, ms)
if (reconnectTimeout.unref) reconnectTimeout.unref()
})
}
}

/**
@@ -6,6 +6,7 @@ var debug = require('debug')('webtorrent:webconn')
var get = require('simple-get')
var inherits = require('inherits')
var sha1 = require('simple-sha1')
var url = require('url')
var Wire = require('bittorrent-protocol')

var VERSION = require('../package.json').version
@@ -109,20 +110,27 @@ WebConn.prototype.httpRequest = function (pieceIndex, offset, length, cb) {
}

requests.forEach(function (request) {
var url = request.url
var parsedUrl = url.parse(request.url)
var start = request.start
var end = request.end
debug(
'Requesting url=%s pieceIndex=%d offset=%d length=%d start=%d end=%d',
url, pieceIndex, offset, length, start, end
request.url, pieceIndex, offset, length, start, end
)

var agent
if (self._torrent.client.proxyOpts && self._torrent.client.proxyOpts.proxyPeerConnections) {
agent = parsedUrl.protocol === 'https:'
? self._torrent.client.proxyOpts.httpsAgent : self._torrent.client.proxyOpts.httpAgent
}
var opts = {
url: url,
url: parsedUrl,
method: 'GET',
headers: {
'user-agent': 'WebTorrent/' + VERSION + ' (https://webtorrent.io)',
range: 'bytes=' + start + '-' + end
}
},
agent: agent
}
get.concat(opts, function (err, res, data) {
if (hasError) return
@@ -15,6 +15,7 @@
"load-ip-set": false,
"net": false,
"os": false,
"socks": false,
"ut_pex": false
},
"browserify": {
@@ -56,6 +57,7 @@
"simple-get": "^2.2.1",
"simple-peer": "^6.0.4",
"simple-sha1": "^2.0.8",
"socks": "^1.1.9",
"speedometer": "^1.0.0",
"stream-to-blob": "^1.0.0",
"stream-to-blob-url": "^2.1.0",
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.