Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

bittorrent-relay

Package Overview
Dependencies
Maintainers
1
Versions
142
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

bittorrent-relay - npm Package Compare versions

Comparing version 12.0.5 to 12.0.6

10

bin/cmd.js

@@ -19,3 +19,4 @@ #!/usr/bin/env node

'version',
'ev'
'ev',
'status'
],

@@ -30,3 +31,4 @@ string: [

'pub',
'priv'
'priv',
'server'
],

@@ -47,3 +49,5 @@ default: {

'limit': {},
'ev': false
'ev': false,
'status': true,
'server': '0.0.0.0'
}

@@ -50,0 +54,0 @@ })

{
"name": "bittorrent-relay",
"description": "Uses the mainline dht to relay requests to other trackers in a swarm",
"version": "12.0.5",
"version": "12.0.6",
"bin": {

@@ -6,0 +6,0 @@ "bittorrent-relay": "./bin/cmd.js"

@@ -87,8 +87,12 @@ import Debug from 'debug'

this.timer.active = this.timer.active || 5 * 60 * 1000
this.host = opts.host || '0.0.0.0'
this.server = opts.server || '0.0.0.0'
if(!opts.host){
throw new Error('must have host')
}
this.host = opts.host
this.port = opts.port || 10509
this.address = `${this.host}:${this.port}`
this._trustProxy = Boolean(opts.trustProxy)
this.web = `${this.domain}:${this.port}`
this.hash = crypto.createHash('sha1').update(this.web).digest('hex')
this.web = `${this.domain || this.host}:${this.port}`
this.id = crypto.createHash('sha1').update(this.address).digest('hex')
this.sockets = new Map()

@@ -161,3 +165,3 @@ this.triedAlready = new Map()

// if(socket.readyState === 1){
// socket.send(JSON.stringify({action: 'web', domain: self.domain, host: self.host, port: self.port, web: self.web, hash: self.hash}))
// socket.send(JSON.stringify({action: 'web', domain: self.domain, host: self.host, port: self.port, web: self.web, id: self.id}))
// }

@@ -187,8 +191,18 @@ // }

for(const test in this.sockets.values()){
if(!test.relays.length){
if(!test.active){
test.terminate()
continue
} else {
test.close()
continue
}
}
if(!test.active){
test.terminate()
continue
} else {
test.active = false
test.send(JSON.stringify({action: 'ping'}))
}
test.active = false
test.send(JSON.stringify({action: 'ping'}))
}

@@ -257,33 +271,7 @@ }, this.timer.inactive)

try {
if(req.url.startsWith('/announce/')){
const useInfoHash = req.url.slice(0, req.url.indexOf('?')).replace('/announce/', '')
if(!this.hashes.has(useInfoHash)){
return res.end(bencode.encode({'failure reason': 'infohash is not supported'}))
}
// const useQueryString = req.url.replace('/announce/', '').slice(0, req.url.indexOf('?'))
// if(!this.hashes.has(useQueryString)){}
return this.onHttpRequest(req, res)
} else if(req.url.startsWith('/relay/')){
const useRelayHash = req.url.slice(0, req.url.indexOf('?')).replace('/relay/', '')
const para = new URLSearchParams(req.url.slice(req.url.indexOf('?')))
if(!this.relays.has(useRelayHash)){
return res.end(bencode.encode({'failure reason': 'relayhash is not supported'}))
}
let size
if(para.has('size')){
if(JSON.parse(para.get('size'))){
size = this.limit.serverConnections
}
}
let keys
if(para.has('keys')){
if(JSON.parse(para.get('keys'))){
keys = this.relays.get(useRelayHash).map((data) => {return data.key})
}
}
// const rh = req.url.replace('/relay/', '').replace(para, '')
// const useQueryString = req.url.replace('/relay/', '').slice(0, req.url.indexOf('?'))
// if(!this.relays.has(useQueryString)){}
res.setHeader('Content-Type', 'text/plain; charset=UTF-8')
return res.end(bencode.encode({size, keys}))
if(req.url.startsWith('/announce?')){
this.onHttpRequest(req, res)
} else if(req.url.startsWith('/relay?')){
const useParams = new URLSearchParams(req.url.slice(req.url.indexOf('?')))
this.onHttpRelay(req, res, useParams)
} else if(req.method === 'HEAD' && req.url === '/'){

@@ -395,8 +383,8 @@ res.statusCode = 200

res.end(JSON.stringify(Array.from(this.hashes)))
} else if(req.method === 'GET' && req.url === '/hash.html'){
} else if(req.method === 'GET' && req.url === '/id.html'){
res.setHeader('Content-Type', 'text/html')
res.end(`<html><head><title>Relay</title></head><body>${(() => {const arr = [];this.sockets.forEach((data) => {arr.push(data.hash)});return arr;})().join('\n')}</body></html>`)
} else if(req.method === 'GET' && req.url === '/hash.json'){
res.end(`<html><head><title>Relay</title></head><body>${(() => {const arr = [];this.sockets.forEach((data) => {arr.push(data.id)});return arr;})().join('\n')}</body></html>`)
} else if(req.method === 'GET' && req.url === '/id.json'){
res.setHeader('Content-Type', 'application/json')
res.end(JSON.stringify((() => {const arr = [];this.sockets.forEach((data) => {arr.push(data.hash)});return arr;})()))
res.end(JSON.stringify((() => {const arr = [];this.sockets.forEach((data) => {arr.push(data.id)});return arr;})()))
} else if(req.method === 'GET' && req.url === '/key.html'){

@@ -633,39 +621,42 @@ res.setHeader('Content-Type', 'text/html')

// else handle websockets as usual
if(req.url.startsWith('/announce/')){
const useTest = req.url.replace('/announce/', '')
// const useTest = crypto.createHash('sha1').update(req.url.slice(req.url.lastIndexOf('/')).slice(1)).digest('hex')
if(!this.hashes.has(useTest)){
socket.send(JSON.stringify({action: 'failure reason', error: 'infohash is not supported'}))
if(req.url === '/announce'){
socket.upgradeReq = req
self.onWebSocketConnection(socket)
} else if(req.url.startsWith('/relay?')){
const params = new URLSearchParams(req.url.slice(req.url.indexOf('?')))
const getRelayHash = params.has('relay_hash') ? params.get('relay_hash') : null
const checkRelayHash = getRelayHash && typeof(getRelayHash) === 'string' || getRelayHash.length === 20
const getId = params.has('id') ? params.get('id') : null
const checkId = getId && typeof(getId) === 'string' && getId.length === 20
const checkHasSocket = getId ? this.sockets.has(getId) : null
const checkHasRelay = getRelayHash ? this.relays.has(getRelayHash) : null
if(!checkRelayHash || !checkId || checkHasSocket || !checkHasRelay){
socket.send(JSON.stringify({action: 'failure reason', error: 'there was a error, check the other properties of this object', relay_hash: checkRelayHash, id: checkId, socket: checkHasSocket, relay: checkHasRelay}))
socket.close()
return
}
socket.upgradeReq = req
self.onWebSocketConnection(socket)
} else if(req.url.startsWith('/relay/')){
// have id and relay in the url routes
// have different functions to handle connections and extras
const useTest = req.url.replace('/relay/', '')
// const useTest = crypto.createHash('sha1').update(req.url.slice(req.url.lastIndexOf('/')).slice(1)).digest('hex')
if(!this.relays.has(useTest)){
socket.send(JSON.stringify({action: 'failure reason', error: 'relay is not supported'}))
socket.close()
return
}
if(this.limit.serverConnections){
if(this.relays.get(useTest).length < this.limit.serverConnections){
socket.hash = null
if(this.relays.get(getRelayHash).length < this.limit.serverConnections){
socket.id = getId
socket.server = true
socket.active = true
socket.relay = getRelayHash
socket.relays = []
socket.proc = false
// socket.relay = useTest
this.sockets.set(socket.id, socket)
this.onRelaySocketConnection(socket)
}
} else {
socket.hash = null
socket.id = getId
socket.server = true
socket.relay = getRelayHash
socket.relays = []
socket.active = true
socket.proc = false
// socket.relay = useTest
this.sockets.set(socket.id, socket)
this.onRelaySocketConnection(socket)

@@ -710,9 +701,9 @@ }

const hash = crypto.createHash('sha1').update(peer.host + ':' + peer.port).digest('hex')
if(self.hash === hash){
const id = crypto.createHash('sha1').update(peer.host + ':' + peer.port).digest('hex')
if(self.id === id){
return
}
if(this.triedAlready.has(hash)){
const check = this.triedAlready.get(hash)
if(this.triedAlready.has(id)){
const check = this.triedAlready.get(id)
const checkStamp = (Date.now() - check.stamp) / 1000

@@ -724,6 +715,6 @@ if(check.wait >= checkStamp){

// if(this.sockets.has(hash)){
// const checkTracker = this.sockets.get(hash)
// if(this.sockets.has(id)){
// const checkTracker = this.sockets.get(id)
// const checkRelay = this.relays.get(ih)
// if(checkRelay.every((data) => {return checkTracker.hash !== data.hash})){
// if(checkRelay.every((data) => {return checkTracker.id !== data.id})){
// // checkRelay.push(checkTracker)

@@ -738,6 +729,6 @@ // // if(!checkTracker.relays.includes(ih)){

if(this.sockets.has(hash)){
const checkTracker = this.sockets.get(hash)
if(this.sockets.has(id)){
const checkTracker = this.sockets.get(id)
const checkRelay = this.relays.get(ih)
if(checkRelay.every((data) => {return checkTracker.hash !== data.hash})){
if(checkRelay.every((data) => {return checkTracker.id !== data.id})){
// checkRelay.push(checkTracker)

@@ -754,12 +745,11 @@ // if(!checkTracker.relays.includes(ih)){

if(this.relays.get(ih).length < this.limit.serverConnections){
const relay = `ws://${peer.host}:${peer.port}/relay/${ih}`
const relay = `ws://${peer.host}:${peer.port}/relay?relay_hash=${ih}&id=${this.id}`
const con = new WebSocket(relay)
con.server = false
con.active = true
con.relay = ih
con.relays = []
con.relay = ih
con.proc = false
con.hash = ih
this.sockets.set(con.hash, con)
// con.hash = hash
con.id = id
this.sockets.set(con.id, con)
self.onRelaySocketConnection(con)

@@ -769,12 +759,11 @@ return

} else {
const relay = `ws://${peer.host}:${peer.port}/relay/${ih}`
const relay = `ws://${peer.host}:${peer.port}/relay?relay_hash=${ih}&id=${this.id}`
const con = new WebSocket(relay)
con.server = false
con.active = true
con.relay = ih
con.relays = []
con.relay = ih
con.proc = false
con.hash = ih
this.sockets.set(con.hash, con)
// con.hash = hash
con.id = id
this.sockets.set(con.id, con)
self.onRelaySocketConnection(con)

@@ -792,7 +781,7 @@ return

turnOnHTTP(){
this.http.listen(this.port, this.host)
this.http.listen(this.port, this.server)
}
turnOnDHT(){
this.relay.listen(this.port, this.host)
this.relay.listen(this.port, this.server)
}

@@ -835,11 +824,6 @@

_filter(infoHash, params, cb){
// const hashes = (() => {if(!opts.hashes){throw new Error('must have hashes')}return Array.isArray(opts.hashes) ? opts.hashes : opts.hashes.split(',')})()
if(this.status){
if(this.hashes.has(infoHash)){
cb(null)
} else {
cb(new Error('disallowed torrent'))
}
if(this.hashes.has(infoHash)){
cb(null)
} else {
cb(null)
cb(new Error('disallowed torrent'))
}

@@ -932,2 +916,3 @@ }

this.hashes.clear()
this.triedAlready.clear()
if(cb){

@@ -962,10 +947,10 @@ cb()

// send the right messages
// self.sockets[socket.hash] = socket
if(socket.hash){
if(self.triedAlready.has(socket.hash)){
self.triedAlready.delete(socket.hash)
// self.sockets[socket.id] = socket
if(socket.id){
if(self.triedAlready.has(socket.id)){
self.triedAlready.delete(socket.id)
}
}
if(!socket.server){
socket.send(JSON.stringify({hash: self.hash, key: self.key, address: self.address, web: self.web, host: self.host, port: self.port, domain: self.domain, relay: socket.relay, status: self.status, sig: self.sig, action: 'session', reply: true}))
socket.send(JSON.stringify({id: self.id, key: self.key, address: self.address, web: self.web, host: self.host, port: self.port, domain: self.domain, relay: socket.relay, status: self.status, sig: self.sig, action: 'session', reply: true}))
delete socket.relay

@@ -976,10 +961,10 @@ }

let useSocket
if(socket.hash){
useSocket = socket.hash
if(self.triedAlready.has(socket.hash)){
const check = self.triedAlready.get(socket.hash)
if(socket.id){
useSocket = socket.id
if(self.triedAlready.has(socket.id)){
const check = self.triedAlready.get(socket.id)
check.stamp = Date.now()
check.wait = check.wait * 2
} else {
self.triedAlready.set(socket.hash, {stamp: Date.now(), wait: 1})
self.triedAlready.set(socket.id, {stamp: Date.now(), wait: 1})
}

@@ -999,3 +984,3 @@ } else {

if(message.action === 'session'){
if(!message.sig || !ed.verify(message.sig, self.test, message.key) || self.sockets.has(message.hash)){
if(socket.relay !== message.relay || message.id !== crypto.createHash('sha1').update(message.address).digest('hex') || !ed.verify(message.sig, self.test, message.key) || self.sockets.has(message.id)){
socket.close()

@@ -1008,7 +993,6 @@ return

// message.relays = [useRelay]
const useRelay = message.relay
delete message.relay
for(const m in message){
if(!socket[m]){
socket[m] = message[m]
}
socket[m] = message[m]
}

@@ -1021,7 +1005,6 @@ for(const r of socket.relays){

socket.session = true
// self.sockets.set(socket.hash, socket)
if(socket.server){
self.sockets.set(socket.hash, socket)
socket.send(JSON.stringify({hash: self.hash, key: self.key, address: self.address, web: self.web, host: self.host, port: self.port, domain: self.domain, relay: useRelay, status: self.status, sig: self.sig, action: 'session', reply: false}))
socket.send(JSON.stringify({id: self.id, key: self.key, address: self.address, web: self.web, host: self.host, port: self.port, domain: self.domain, relay: useRelay, status: self.status, sig: self.sig, action: 'session', reply: false}))
}
delete socket.relay
}

@@ -1034,3 +1017,3 @@ if(message.action === 'add'){

const checkRelay = self.relays.get(message.relay)
const i = checkRelay.findIndex((data) => {return socket.hash === data.hash})
const i = checkRelay.findIndex((data) => {return socket.id === data.id})
if(i === -1){

@@ -1054,3 +1037,3 @@ checkRelay.push(socket)

const checkRelay = self.relays.get(message.relay)
const i = checkRelay.findIndex((data) => {return socket.hash === data.hash})
const i = checkRelay.findIndex((data) => {return socket.id === data.id})
if(i !== -1){

@@ -1074,3 +1057,3 @@ checkRelay.splice(i, 1)

const checkRelay = self.relays.get(r)
const i = checkRelay.find((soc) => {return socket.hash === soc.hash})
const i = checkRelay.find((soc) => {return socket.id === soc.id})
if(i){

@@ -1086,3 +1069,3 @@ i.session = true

const checkRelay = self.relays.get(r)
const i = checkRelay.find((soc) => {return socket.hash === soc.hash})
const i = checkRelay.find((soc) => {return socket.id === soc.id})
if(i){

@@ -1095,3 +1078,3 @@ i.session = false

} catch (error) {
self.emit('ev', socket.hash || 'socket' + ' had an error, will wait and try to connect later, ' + error.message)
self.emit('ev', socket.id || 'socket' + ' had an error, will wait and try to connect later, ' + error.message)
socket.close()

@@ -1108,3 +1091,3 @@ }

const checkRelay = self.relays.get(soc)
const i = checkRelay.findIndex((data) => {return socket.hash === data.hash})
const i = checkRelay.findIndex((data) => {return socket.id === data.id})
if(i !== -1){

@@ -1117,5 +1100,5 @@ checkRelay.splice(i, 1)

if(socket.hash){
if(self.sockets.has(socket.hash)){
self.sockets.delete(socket.hash)
if(socket.id){
if(self.sockets.has(socket.id)){
self.sockets.delete(socket.id)
}

@@ -1175,2 +1158,21 @@ }

onHttpRelay(req, res, par){
// const useRelayHash = req.url.slice(0, req.url.indexOf('?')).replace('/relay/', '')
const getRelayHash = par.has('relay_hash') ? par.get('relay_hash') : null
const checkRelayHash = getRelayHash && typeof(getRelayHash) === 'string' && getRelayHash.length === 20
const getId = par.has('id') ? par.get('id') : null
const checkId = getId && typeof(getId) === 'string' && getId.length === 20
if(!checkRelayHash && !checkId){
res.end(bencode.encode({'failure reason': 'must have relay-hash or id'}))
}
const check = {}
if(checkRelayHash){
check.relay_hash = this.relays.has(par.relay_hash)
}
if(checkId){
check.id = this.sockets.has(par.id)
}
res.end(bencode.encode(check))
}
onWebSocketConnection (socket, opts = {}) {

@@ -1370,3 +1372,3 @@ this.clientCount = this.clientCount + 1

const checkGet = this.relays.get(relay).filter((data) => {return data.session})
params.relay = checkGet.length ? `${params.type}://${checkGet[Math.floor(Math.random() * checkGet.length)].web}/announce/${params.info_hash}` : ''
params.relay = checkGet.length ? `${params.type}://${checkGet[Math.floor(Math.random() * checkGet.length)].web}/announce` : ''
} else {

@@ -1378,7 +1380,7 @@ params.relay = ''

} else if(this.limit.clientConnections && this.clientCount >= this.limit.clientConnections){
const relay = crypto.createHash('sha1').update(hash).digest('hex')
const relay = crypto.createHash('sha1').update(params.info_hash).digest('hex')
const checkHas = this.relays.has(relay)
if(checkHas){
const checkGet = this.relays.get(relay).filter((data) => {return data.session})
params.relay = checkGet.length ? `${params.type}://${checkGet[Math.floor(Math.random() * checkGet.length)].web}/announce/${params.info_hash}` : ''
params.relay = checkGet.length ? `${params.type}://${checkGet[Math.floor(Math.random() * checkGet.length)].web}/announce` : ''
} else {

@@ -1402,7 +1404,19 @@ params.relay = ''

getOrCreateSwarm((err, swarm) => {
if (err) return cb(err)
announce(swarm)
})
if (this.status) {
this._filter(params.info_hash, params, err => {
// Presence of `err` means that this announce request is disallowed
if (err) return cb(err)
getOrCreateSwarm((err, swarm) => {
if (err) return cb(err)
announce(swarm)
})
})
} else {
getOrCreateSwarm((err, swarm) => {
if (err) return cb(err)
announce(swarm)
})
}
// Get existing swarm, or create one if one does not exist

@@ -1409,0 +1423,0 @@ function getOrCreateSwarm (cb) {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc