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.Core
import com.muwire.core.Persona
import groovy.json.JsonOutput
import groovy.json.JsonSlurper
import groovy.util.logging.Log
import net.i2p.client.I2PSession
import net.i2p.client.I2PSessionMuxedListener
import net.i2p.client.SendMessageOptions
import net.i2p.client.datagram.I2PDatagramDissector
import net.i2p.client.datagram.I2PDatagramMaker
import net.i2p.data.Base64
@ -89,7 +92,73 @@ class Pinger {
@Override
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.InfoHash
import com.muwire.core.Persona
import com.muwire.core.search.QueryEvent
import com.muwire.core.search.SearchEvent
import com.muwire.core.search.UIResultBatchEvent
@ -81,7 +82,7 @@ class SwarmManager {
List<HostAndIH> toPing = new ArrayList<>()
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++) {
Swarm s = swarmList.get(i)
@ -138,6 +139,14 @@ class SwarmManager {
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 {
final Host host
final InfoHash infoHash