handle tracker pongs

This commit is contained in:
Zlatin Balevsky
2020-04-29 11:24:58 +01:00
parent 356d7fe2ff
commit 028a8d5044
2 changed files with 80 additions and 2 deletions

View File

@ -10,12 +10,15 @@ import org.springframework.stereotype.Component
import com.muwire.core.Constants import com.muwire.core.Constants
import com.muwire.core.Core import com.muwire.core.Core
import com.muwire.core.Persona
import groovy.json.JsonOutput import groovy.json.JsonOutput
import groovy.json.JsonSlurper
import groovy.util.logging.Log import groovy.util.logging.Log
import net.i2p.client.I2PSession import net.i2p.client.I2PSession
import net.i2p.client.I2PSessionMuxedListener import net.i2p.client.I2PSessionMuxedListener
import net.i2p.client.SendMessageOptions import net.i2p.client.SendMessageOptions
import net.i2p.client.datagram.I2PDatagramDissector
import net.i2p.client.datagram.I2PDatagramMaker import net.i2p.client.datagram.I2PDatagramMaker
import net.i2p.data.Base64 import net.i2p.data.Base64
@ -89,7 +92,73 @@ class Pinger {
@Override @Override
public void messageAvailable(I2PSession session, int msgId, long size, int proto, int fromport, int toport) { public void messageAvailable(I2PSession session, int msgId, long size, int proto, int fromport, int toport) {
// TODO Auto-generated method stub if (proto != I2PSession.PROTO_DATAGRAM) {
log.warning("received unexpected protocol $proto")
return
}
byte [] payload = session.receiveMessage(msgId)
def dissector = new I2PDatagramDissector()
try {
dissector.loadI2PDatagram(payload)
def sender = dissector.getSender()
log.info("got a response from ${sender.toBase32()}")
payload = dissector.getPayload()
def slurper = new JsonSlurper()
def json = slurper.parse(payload)
if (json.type != "TrackerPong") {
log.warning("unknown type ${json.type}")
return
}
if (json.me == null) {
log.warning("sender persona missing")
return
}
Persona senderPersona = new Persona(new ByteArrayInputStream(Base64.decode(json.me)))
if (sender != senderPersona.getDestination()) {
log.warning("persona in payload does not match sender ${senderPersona.getHumanReadableName()}")
return
}
if (json.uuid == null) {
log.warning("uuid missing")
return
}
UUID uuid = UUID.fromString(json.uuid)
def ping = inFlight.remove(uuid)
if (ping == null) {
log.warning("no ping in progress for $uuid")
return
}
if (json.code == null) {
log.warning("no code")
return
}
int code = json.code
if (json.xHave != null)
ping.target.host.xHave = json.xHave
Set<Persona> altlocs = new HashSet<>()
json.altlocs?.collect(altlocs,{ new Persona(new ByteArrayInputStream(Base64.decode(it))) })
log.info("For ${ping.target.infoHash} received code $code and altlocs ${altlocs.size()}")
swarmManager.handleResponse(ping.target, code, altlocs)
} catch (Exception e) {
log.log(Level.WARNING,"invalid datagram",e)
}
} }

View File

@ -10,6 +10,7 @@ import org.springframework.stereotype.Component
import com.muwire.core.Core import com.muwire.core.Core
import com.muwire.core.InfoHash import com.muwire.core.InfoHash
import com.muwire.core.Persona
import com.muwire.core.search.QueryEvent import com.muwire.core.search.QueryEvent
import com.muwire.core.search.SearchEvent import com.muwire.core.search.SearchEvent
import com.muwire.core.search.UIResultBatchEvent import com.muwire.core.search.UIResultBatchEvent
@ -81,7 +82,7 @@ class SwarmManager {
List<HostAndIH> toPing = new ArrayList<>() List<HostAndIH> toPing = new ArrayList<>()
final int amount = trackerProperties.getSwarmParameters().getPingParallel() final int amount = trackerProperties.getSwarmParameters().getPingParallel()
final int pingCutoff = now - trackerProperties.getSwarmParameters().getPingInterval() * 60 * 1000L final long pingCutoff = now - trackerProperties.getSwarmParameters().getPingInterval() * 60 * 1000L
for(int i = 0; i < swarmList.size() && toPing.size() < amount; i++) { for(int i = 0; i < swarmList.size() && toPing.size() < amount; i++) {
Swarm s = swarmList.get(i) Swarm s = swarmList.get(i)
@ -138,6 +139,14 @@ class SwarmManager {
swarms.get(target.infoHash)?.fail(target.host) swarms.get(target.infoHash)?.fail(target.host)
} }
void handleResponse(HostAndIH target, int code, Set<Persona> altlocs) {
Swarm swarm = swarms.get(target.infoHash)
swarm?.handleResponse(target.host, code)
altlocs.each {
swarm?.add(it)
}
}
public static class HostAndIH { public static class HostAndIH {
final Host host final Host host
final InfoHash infoHash final InfoHash infoHash