Updates for proposal 160 changes (WIP)
- Remove fast mode support - Add configurable lifetime TODO: Switch to Datagram2
This commit is contained in:
@ -5,6 +5,10 @@
|
|||||||
# minimum 900 (15 minutes), maximum 21600 (6 hours)
|
# minimum 900 (15 minutes), maximum 21600 (6 hours)
|
||||||
interval=1620
|
interval=1620
|
||||||
#
|
#
|
||||||
|
# UDP connection lifetime in seconds
|
||||||
|
# minimum 60 (1 minute), maximum 21600 (6 hours)
|
||||||
|
lifetime=1200
|
||||||
|
#
|
||||||
showfoooter=true
|
showfoooter=true
|
||||||
#footerText=your html text here
|
#footerText=your html text here
|
||||||
#
|
#
|
||||||
|
@ -33,15 +33,18 @@ public class Torrents extends ConcurrentHashMap<InfoHash, Peers> {
|
|||||||
private final SDSCache<InfoHash> _hashCache;
|
private final SDSCache<InfoHash> _hashCache;
|
||||||
private final SDSCache<PID> _pidCache;
|
private final SDSCache<PID> _pidCache;
|
||||||
private final Integer _interval;
|
private final Integer _interval;
|
||||||
|
private final int _udpLifetime;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param interval in seconds
|
* @param interval in seconds
|
||||||
|
* @param udpInterval in seconds
|
||||||
*/
|
*/
|
||||||
public Torrents(int interval) {
|
public Torrents(int interval, int udpLifetime) {
|
||||||
super();
|
super();
|
||||||
_hashCache = new SDSCache<InfoHash>(InfoHash.class, InfoHash.LENGTH, CACHE_SIZE);
|
_hashCache = new SDSCache<InfoHash>(InfoHash.class, InfoHash.LENGTH, CACHE_SIZE);
|
||||||
_pidCache = new SDSCache<PID>(PID.class, PID.LENGTH, CACHE_SIZE);
|
_pidCache = new SDSCache<PID>(PID.class, PID.LENGTH, CACHE_SIZE);
|
||||||
_interval = Integer.valueOf(interval);
|
_interval = Integer.valueOf(interval);
|
||||||
|
_udpLifetime = udpLifetime;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int countPeers() {
|
public int countPeers() {
|
||||||
@ -60,6 +63,14 @@ public class Torrents extends ConcurrentHashMap<InfoHash, Peers> {
|
|||||||
return _interval;
|
return _interval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return in seconds
|
||||||
|
* @since 0.20.0
|
||||||
|
*/
|
||||||
|
public int getUDPLifetime() {
|
||||||
|
return _udpLifetime;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pull from cache or return new
|
* Pull from cache or return new
|
||||||
*
|
*
|
||||||
|
@ -67,7 +67,7 @@ public class UDPHandler implements I2PSessionMuxedListener {
|
|||||||
private static final int EVENT_COMPLETED = 1;
|
private static final int EVENT_COMPLETED = 1;
|
||||||
private static final int EVENT_STARTED = 2;
|
private static final int EVENT_STARTED = 2;
|
||||||
private static final int EVENT_STOPPED = 3;
|
private static final int EVENT_STOPPED = 3;
|
||||||
private static final long CLEAN_TIME = 2*60*1000;
|
private final long CLEAN_TIME;
|
||||||
|
|
||||||
|
|
||||||
public UDPHandler(I2PAppContext ctx, I2PTunnel tunnel, ZzzOT zzzot) {
|
public UDPHandler(I2PAppContext ctx, I2PTunnel tunnel, ZzzOT zzzot) {
|
||||||
@ -77,6 +77,7 @@ public class UDPHandler implements I2PSessionMuxedListener {
|
|||||||
_zzzot = zzzot;
|
_zzzot = zzzot;
|
||||||
_diss = new I2PDatagramDissector();
|
_diss = new I2PDatagramDissector();
|
||||||
_connectCache = new ConcurrentHashMap<Long, DestAndTime>();
|
_connectCache = new ConcurrentHashMap<Long, DestAndTime>();
|
||||||
|
CLEAN_TIME = (zzzot.getTorrents().getUDPLifetime() + 60) * 1000;
|
||||||
_cleaner = new Cleaner();
|
_cleaner = new Cleaner();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,6 +95,7 @@ public class UDPHandler implements I2PSessionMuxedListener {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
I2PSession session = sessions.get(0);
|
I2PSession session = sessions.get(0);
|
||||||
|
// TODO switch to Datagram2
|
||||||
session.addMuxedSessionListener(UDPHandler.this, I2PSession.PROTO_DATAGRAM, PORT);
|
session.addMuxedSessionListener(UDPHandler.this, I2PSession.PROTO_DATAGRAM, PORT);
|
||||||
session.addMuxedSessionListener(UDPHandler.this, I2PSession.PROTO_DATAGRAM_RAW, PORT);
|
session.addMuxedSessionListener(UDPHandler.this, I2PSession.PROTO_DATAGRAM_RAW, PORT);
|
||||||
_cleaner.schedule(CLEAN_TIME);
|
_cleaner.schedule(CLEAN_TIME);
|
||||||
@ -119,6 +121,7 @@ public class UDPHandler implements I2PSessionMuxedListener {
|
|||||||
try {
|
try {
|
||||||
// receive message
|
// receive message
|
||||||
byte[] msg = session.receiveMessage(id);
|
byte[] msg = session.receiveMessage(id);
|
||||||
|
// TODO switch to Datagram2
|
||||||
if (proto == I2PSession.PROTO_DATAGRAM) {
|
if (proto == I2PSession.PROTO_DATAGRAM) {
|
||||||
// load datagram into it
|
// load datagram into it
|
||||||
_diss.loadI2PDatagram(msg);
|
_diss.loadI2PDatagram(msg);
|
||||||
@ -170,7 +173,12 @@ public class UDPHandler implements I2PSessionMuxedListener {
|
|||||||
}
|
}
|
||||||
handleConnect(session, from, fromPort, data);
|
handleConnect(session, from, fromPort, data);
|
||||||
} else if (action == ACTION_ANNOUNCE) {
|
} else if (action == ACTION_ANNOUNCE) {
|
||||||
handleAnnounce(session, connID, from, fromPort, data);
|
if (from != null) {
|
||||||
|
if (_log.shouldWarn())
|
||||||
|
_log.warn("dropping repliable announce");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
handleAnnounce(session, connID, fromPort, data);
|
||||||
} else if (action == ACTION_SCRAPE) {
|
} else if (action == ACTION_SCRAPE) {
|
||||||
if (_log.shouldWarn())
|
if (_log.shouldWarn())
|
||||||
_log.warn("got unsupported scrape");
|
_log.warn("got unsupported scrape");
|
||||||
@ -186,9 +194,11 @@ public class UDPHandler implements I2PSessionMuxedListener {
|
|||||||
private void handleConnect(I2PSession session, Destination from, int fromPort, byte[] data) {
|
private void handleConnect(I2PSession session, Destination from, int fromPort, byte[] data) {
|
||||||
int transID = (int) DataHelper.fromLong(data, 12, 4);
|
int transID = (int) DataHelper.fromLong(data, 12, 4);
|
||||||
long connID = _context.random().nextLong();
|
long connID = _context.random().nextLong();
|
||||||
byte[] resp = new byte[16];
|
byte[] resp = new byte[18];
|
||||||
DataHelper.toLong(resp, 4, 4, transID);
|
DataHelper.toLong(resp, 4, 4, transID);
|
||||||
DataHelper.toLong8(resp, 8, connID);
|
DataHelper.toLong8(resp, 8, connID);
|
||||||
|
// Addition to BEP 15
|
||||||
|
DataHelper.toLong(resp, 16, 2, _zzzot.getTorrents().getUDPLifetime());
|
||||||
try {
|
try {
|
||||||
session.sendMessage(from, resp, I2PSession.PROTO_DATAGRAM_RAW, PORT, fromPort);
|
session.sendMessage(from, resp, I2PSession.PROTO_DATAGRAM_RAW, PORT, fromPort);
|
||||||
if (_log.shouldDebug())
|
if (_log.shouldDebug())
|
||||||
@ -203,22 +213,20 @@ public class UDPHandler implements I2PSessionMuxedListener {
|
|||||||
/**
|
/**
|
||||||
* @param from may be null
|
* @param from may be null
|
||||||
*/
|
*/
|
||||||
private void handleAnnounce(I2PSession session, long connID, Destination from, int fromPort, byte[] data) {
|
private void handleAnnounce(I2PSession session, long connID, int fromPort, byte[] data) {
|
||||||
int sz = data.length;
|
int sz = data.length;
|
||||||
if (sz < 96) {
|
if (sz < 96) {
|
||||||
if (_log.shouldWarn())
|
if (_log.shouldWarn())
|
||||||
_log.warn("dropping short announce length " + sz);
|
_log.warn("dropping short announce length " + sz);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (from == null) {
|
DestAndTime dat = _connectCache.get(Long.valueOf(connID));
|
||||||
DestAndTime dat = _connectCache.get(Long.valueOf(connID));
|
if (dat == null) {
|
||||||
if (dat == null) {
|
if (_log.shouldWarn())
|
||||||
if (_log.shouldWarn())
|
_log.warn("no connID found " + connID);
|
||||||
_log.warn("no connID found " + connID);
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
from = dat.dest;
|
|
||||||
}
|
}
|
||||||
|
Destination from = dat.dest;
|
||||||
|
|
||||||
// parse packet
|
// parse packet
|
||||||
int transID = (int) DataHelper.fromLong(data, 12, 4);
|
int transID = (int) DataHelper.fromLong(data, 12, 4);
|
||||||
|
@ -35,11 +35,15 @@ class ZzzOT {
|
|||||||
private final long EXPIRE_TIME;
|
private final long EXPIRE_TIME;
|
||||||
|
|
||||||
private static final String PROP_INTERVAL = "interval";
|
private static final String PROP_INTERVAL = "interval";
|
||||||
|
private static final String PROP_UDP_LIFETIME = "lifetime";
|
||||||
private static final long CLEAN_TIME = 4*60*1000;
|
private static final long CLEAN_TIME = 4*60*1000;
|
||||||
private static final long DEST_CACHE_CLEAN_TIME = 3*60*60*1000;
|
private static final long DEST_CACHE_CLEAN_TIME = 3*60*60*1000;
|
||||||
private static final int DEFAULT_INTERVAL = 27*60;
|
private static final int DEFAULT_INTERVAL = 27*60;
|
||||||
|
private static final int DEFAULT_UDP_LIFETIME = 20*60;
|
||||||
private static final int MIN_INTERVAL = 15*60;
|
private static final int MIN_INTERVAL = 15*60;
|
||||||
private static final int MAX_INTERVAL = 6*60*60;
|
private static final int MAX_INTERVAL = 6*60*60;
|
||||||
|
private static final int MIN_UDP_LIFETIME = 60;
|
||||||
|
private static final int MAX_UDP_LIFETIME = 6*60*60;
|
||||||
|
|
||||||
ZzzOT(I2PAppContext ctx, Properties p) {
|
ZzzOT(I2PAppContext ctx, Properties p) {
|
||||||
String intv = p.getProperty(PROP_INTERVAL);
|
String intv = p.getProperty(PROP_INTERVAL);
|
||||||
@ -53,7 +57,18 @@ class ZzzOT {
|
|||||||
interval = MAX_INTERVAL;
|
interval = MAX_INTERVAL;
|
||||||
} catch (NumberFormatException nfe) {}
|
} catch (NumberFormatException nfe) {}
|
||||||
}
|
}
|
||||||
_torrents = new Torrents(interval);
|
intv = p.getProperty(PROP_UDP_LIFETIME);
|
||||||
|
int lifetime = DEFAULT_UDP_LIFETIME;
|
||||||
|
if (intv != null) {
|
||||||
|
try {
|
||||||
|
lifetime = Integer.parseInt(intv);
|
||||||
|
if (lifetime < MIN_UDP_LIFETIME)
|
||||||
|
interval = MIN_UDP_LIFETIME;
|
||||||
|
else if (interval > MAX_UDP_LIFETIME)
|
||||||
|
interval = MAX_UDP_LIFETIME;
|
||||||
|
} catch (NumberFormatException nfe) {}
|
||||||
|
}
|
||||||
|
_torrents = new Torrents(interval, lifetime);
|
||||||
EXPIRE_TIME = 1000 * (interval + interval / 2);
|
EXPIRE_TIME = 1000 * (interval + interval / 2);
|
||||||
_cleaner = new Cleaner(ctx);
|
_cleaner = new Cleaner(ctx);
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,10 @@
|
|||||||
<b>Torrents:</b> <%=torrents.size()%><br>
|
<b>Torrents:</b> <%=torrents.size()%><br>
|
||||||
<b>Peers:</b> <%=torrents.countPeers()%><br>
|
<b>Peers:</b> <%=torrents.countPeers()%><br>
|
||||||
<b>Announce Interval:</b> <%=torrents.getInterval() / 60%> minutes<br>
|
<b>Announce Interval:</b> <%=torrents.getInterval() / 60%> minutes<br>
|
||||||
|
<!--
|
||||||
|
<b>UDP Announce Support:</b> yes<br>
|
||||||
|
<b>UDP Connection Lifetime:</b> <%=torrents.getUDPLifetime() / 60%> minutes<br>
|
||||||
|
-->
|
||||||
</p>
|
</p>
|
||||||
<%
|
<%
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user