2005-11-30 jrandom

* Don't let the TCP transport alone shitlist a peer, since other
      transports may be working.  Also display whether TCP connections are
      inbound or outbound on the peers page.
    * Fixed some substantial bugs in the SSU introducers where we wouldn't
      talk to anyone who didn't expose an IP (even if they had introducers),
      among other goofy things.
    * When dealing with SSU introducers, send them all a packet at 3s/6s/9s,
      rather than sending one a packet at 3s, then another a packet at 6s,
      and a third a packet at 9s.
    * Fixed Syndie attachments (oops)
This commit is contained in:
jrandom
2005-11-30 20:48:25 +00:00
committed by zzz
parent 3d18bf870b
commit f62a6d3ce6
15 changed files with 133 additions and 46 deletions

View File

@ -172,6 +172,7 @@ public class PostBean {
private static final int MAX_SIZE = 256*1024; private static final int MAX_SIZE = 256*1024;
private void cacheAttachments() throws IOException { private void cacheAttachments() throws IOException {
if (_user == null) throw new IOException("User not specified");
File postCacheDir = new File(BlogManager.instance().getTempDir(), _user.getBlog().toBase64()); File postCacheDir = new File(BlogManager.instance().getTempDir(), _user.getBlog().toBase64());
if (!postCacheDir.exists()) if (!postCacheDir.exists())
postCacheDir.mkdirs(); postCacheDir.mkdirs();

View File

@ -49,6 +49,8 @@ public class PostServlet extends BaseServlet {
String action = req.getParameter(PARAM_ACTION); String action = req.getParameter(PARAM_ACTION);
if (!empty(action) && ACTION_CONFIRM.equals(action)) { if (!empty(action) && ACTION_CONFIRM.equals(action)) {
postEntry(user, req, archive, post, out); postEntry(user, req, archive, post, out);
post.reinitialize();
post.setUser(user);
} else { } else {
String contentType = req.getContentType(); String contentType = req.getContentType();
if (!empty(contentType) && (contentType.indexOf("boundary=") != -1)) { if (!empty(contentType) && (contentType.indexOf("boundary=") != -1)) {
@ -73,8 +75,8 @@ public class PostServlet extends BaseServlet {
out.write("<tr><td colspan=\"3\">"); out.write("<tr><td colspan=\"3\">");
post.reinitialize(); //post.reinitialize();
post.setUser(user); //post.setUser(user);
boolean inNewThread = getInNewThread(req.getString(PARAM_IN_NEW_THREAD)); boolean inNewThread = getInNewThread(req.getString(PARAM_IN_NEW_THREAD));
boolean refuseReplies = getRefuseReplies(req.getString(PARAM_REFUSE_REPLIES)); boolean refuseReplies = getRefuseReplies(req.getString(PARAM_REFUSE_REPLIES));
@ -343,6 +345,7 @@ public class PostServlet extends BaseServlet {
bean = new PostBean(); bean = new PostBean();
req.getSession().setAttribute(ATTR_POST_BEAN, bean); req.getSession().setAttribute(ATTR_POST_BEAN, bean);
} }
bean.setUser(user);
return bean; return bean;
} }

View File

@ -1,4 +1,16 @@
$Id: history.txt,v 1.337 2005/11/29 11:58:01 jrandom Exp $ $Id: history.txt,v 1.338 2005/11/29 12:56:03 jrandom Exp $
2005-11-30 jrandom
* Don't let the TCP transport alone shitlist a peer, since other
transports may be working. Also display whether TCP connections are
inbound or outbound on the peers page.
* Fixed some substantial bugs in the SSU introducers where we wouldn't
talk to anyone who didn't expose an IP (even if they had introducers),
among other goofy things.
* When dealing with SSU introducers, send them all a packet at 3s/6s/9s,
rather than sending one a packet at 3s, then another a packet at 6s,
and a third a packet at 9s.
* Fixed Syndie attachments (oops)
2005-11-29 zzz 2005-11-29 zzz
* Added a link to orion's jump page on the 'key not found' error page. * Added a link to orion's jump page on the 'key not found' error page.

View File

@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
* *
*/ */
public class RouterVersion { public class RouterVersion {
public final static String ID = "$Revision: 1.304 $ $Date: 2005/11/29 11:58:02 $"; public final static String ID = "$Revision: 1.305 $ $Date: 2005/11/29 12:56:02 $";
public final static String VERSION = "0.6.1.6"; public final static String VERSION = "0.6.1.6";
public final static long BUILD = 4; public final static long BUILD = 5;
public static void main(String args[]) { public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION + "-" + BUILD); System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
System.out.println("Router ID: " + RouterVersion.ID); System.out.println("Router ID: " + RouterVersion.ID);

View File

@ -68,8 +68,8 @@ class FloodfillPeerSelector extends PeerSelector {
} }
public List getFloodfillParticipants() { return _floodfillMatches; } public List getFloodfillParticipants() { return _floodfillMatches; }
public void add(Hash entry) { public void add(Hash entry) {
if (_context.profileOrganizer().isFailing(entry)) //if (_context.profileOrganizer().isFailing(entry))
return; // return;
if ( (_toIgnore != null) && (_toIgnore.contains(entry)) ) if ( (_toIgnore != null) && (_toIgnore.contains(entry)) )
return; return;
if (entry.equals(_context.routerHash())) if (entry.equals(_context.routerHash()))

View File

@ -657,8 +657,8 @@ public class KademliaNetworkDatabaseFacade extends NetworkDatabaseFacade {
} }
} else if (routerInfo.getPublished() > now + Router.CLOCK_FUDGE_FACTOR) { } else if (routerInfo.getPublished() > now + Router.CLOCK_FUDGE_FACTOR) {
long age = routerInfo.getPublished() - _context.clock().now(); long age = routerInfo.getPublished() - _context.clock().now();
if (_log.shouldLog(Log.WARN)) if (_log.shouldLog(Log.INFO))
_log.warn("Peer " + key.toBase64() + " published their routerInfo in the future?! [" _log.info("Peer " + key.toBase64() + " published their routerInfo in the future?! ["
+ new Date(routerInfo.getPublished()) + "]", new Exception("Rejecting store")); + new Date(routerInfo.getPublished()) + "]", new Exception("Rejecting store"));
return "Peer " + key.toBase64() + " published " + DataHelper.formatDuration(age) + " in the future?!"; return "Peer " + key.toBase64() + " published " + DataHelper.formatDuration(age) + " in the future?!";
} else if (_enforceNetId && (routerInfo.getNetworkId() != Router.NETWORK_ID) ){ } else if (_enforceNetId && (routerInfo.getNetworkId() != Router.NETWORK_ID) ){

View File

@ -169,6 +169,7 @@ public class ConnectionHandler {
if (_error == null) { if (_error == null) {
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))
_log.info("Establishment successful! returning the con"); _log.info("Establishment successful! returning the con");
con.setIsOutbound(false);
return con; return con;
} else { } else {
if (_log.shouldLog(Log.INFO)) if (_log.shouldLog(Log.INFO))

View File

@ -43,6 +43,7 @@ public class TCPConnection {
private long _lastRead; private long _lastRead;
private long _lastWrite; private long _lastWrite;
private long _offsetReceived; private long _offsetReceived;
private boolean _isOutbound;
public TCPConnection(RouterContext ctx) { public TCPConnection(RouterContext ctx) {
_context = ctx; _context = ctx;
@ -60,6 +61,7 @@ public class TCPConnection {
_lastRead = 0; _lastRead = 0;
_lastWrite = 0; _lastWrite = 0;
_offsetReceived = 0; _offsetReceived = 0;
_isOutbound = false;
_runner = new ConnectionRunner(_context, this); _runner = new ConnectionRunner(_context, this);
_context.statManager().createRateStat("tcp.probabalisticDropQueueSize", "How many bytes were queued to be sent when a message as dropped probabalistically?", "TCP", new long[] { 60*1000l, 10*60*1000l, 60*60*1000l, 24*60*60*1000l } ); _context.statManager().createRateStat("tcp.probabalisticDropQueueSize", "How many bytes were queued to be sent when a message as dropped probabalistically?", "TCP", new long[] { 60*1000l, 10*60*1000l, 60*60*1000l, 24*60*60*1000l } );
_context.statManager().createRateStat("tcp.queueSize", "How many bytes were queued on a connection?", "TCP", new long[] { 60*1000l, 10*60*1000l, 60*60*1000l, 24*60*60*1000l } ); _context.statManager().createRateStat("tcp.queueSize", "How many bytes were queued on a connection?", "TCP", new long[] { 60*1000l, 10*60*1000l, 60*60*1000l, 24*60*60*1000l } );
@ -86,6 +88,8 @@ public class TCPConnection {
public long getOffsetReceived() { return _offsetReceived; } public long getOffsetReceived() { return _offsetReceived; }
public void setOffsetReceived(long ms) { _offsetReceived = ms; } public void setOffsetReceived(long ms) { _offsetReceived = ms; }
public TCPTransport getTransport() { return _transport; } public TCPTransport getTransport() { return _transport; }
public boolean getIsOutbound() { return _isOutbound; }
public void setIsOutbound(boolean outbound) { _isOutbound = outbound; }
/** /**
* Actually start processing the messages on the connection (and reading * Actually start processing the messages on the connection (and reading

View File

@ -47,14 +47,17 @@ public class TCPConnectionEstablisher implements Runnable {
+ info.getIdentity().getHash().toBase64(), e); + info.getIdentity().getHash().toBase64(), e);
} }
if (con != null) { if (con != null) {
con.setIsOutbound(true);
_transport.connectionEstablished(con); _transport.connectionEstablished(con);
} else { } else {
if (!_context.router().isAlive()) return; if (!_context.router().isAlive()) return;
_transport.addConnectionErrorMessage(cb.getError()); _transport.addConnectionErrorMessage(cb.getError());
Hash peer = info.getIdentity().getHash(); Hash peer = info.getIdentity().getHash();
_context.profileManager().commErrorOccurred(peer); _context.profileManager().commErrorOccurred(peer);
_context.shitlist().shitlistRouter(peer, "Unable to contact"); // disabling in preparation for dropping tcp, since other transports may work, and
_context.netDb().fail(peer); // hence shitlisting is not appropriate
//_context.shitlist().shitlistRouter(peer, "Unable to contact");
//_context.netDb().fail(peer);
} }
// this removes the _pending block on the address and // this removes the _pending block on the address and

View File

@ -783,12 +783,21 @@ public class TCPTransport extends TransportImpl {
/** Make this stuff pretty (only used in the old console) */ /** Make this stuff pretty (only used in the old console) */
public void renderStatusHTML(Writer out) throws IOException { public void renderStatusHTML(Writer out) throws IOException {
StringBuffer buf = new StringBuffer(1024); StringBuffer buf = new StringBuffer(1024);
int outbound = 0;
int inbound = 0;
synchronized (_connectionLock) { synchronized (_connectionLock) {
long offsetTotal = 0; long offsetTotal = 0;
buf.append("<b>Connections (").append(_connectionsByIdent.size()).append("):</b><ul>\n"); buf.append("<b>Connections (").append(_connectionsByIdent.size()).append("):</b><ul>\n");
for (Iterator iter = _connectionsByIdent.values().iterator(); iter.hasNext(); ) { for (Iterator iter = _connectionsByIdent.values().iterator(); iter.hasNext(); ) {
TCPConnection con = (TCPConnection)iter.next(); TCPConnection con = (TCPConnection)iter.next();
buf.append("<li>"); buf.append("<li>");
if (con.getIsOutbound()) {
outbound++;
buf.append("Outbound to ");
} else {
inbound++;
buf.append("Inbound from ");
}
buf.append(con.getRemoteRouterIdentity().getHash().toBase64().substring(0,6)); buf.append(con.getRemoteRouterIdentity().getHash().toBase64().substring(0,6));
buf.append(": up for ").append(DataHelper.formatDuration(con.getLifetime())); buf.append(": up for ").append(DataHelper.formatDuration(con.getLifetime()));
buf.append(" transferring at "); buf.append(" transferring at ");
@ -817,6 +826,7 @@ public class TCPTransport extends TransportImpl {
buf.append("</li>\n"); buf.append("</li>\n");
} }
buf.append("</ul>\n"); buf.append("</ul>\n");
buf.append("<b>Inbound: ").append(inbound).append(", Outbound: ").append(outbound).append("</b><br />\n");
} }
buf.append("<b>Most recent connection errors:</b><ul>"); buf.append("<b>Most recent connection errors:</b><ul>");

View File

@ -126,9 +126,11 @@ public class EstablishmentManager {
return; return;
} }
UDPAddress addr = new UDPAddress(ra); UDPAddress addr = new UDPAddress(ra);
RemoteHostId to = null;
InetAddress remAddr = addr.getHostAddress(); InetAddress remAddr = addr.getHostAddress();
int port = addr.getPort(); int port = addr.getPort();
RemoteHostId to = new RemoteHostId(remAddr.getAddress(), port); if ( (remAddr != null) && (port > 0) ) {
to = new RemoteHostId(remAddr.getAddress(), port);
if (!_transport.isValid(to.getIP())) { if (!_transport.isValid(to.getIP())) {
_transport.failed(msg); _transport.failed(msg);
@ -137,7 +139,12 @@ public class EstablishmentManager {
} }
if (_log.shouldLog(Log.DEBUG)) if (_log.shouldLog(Log.DEBUG))
_log.debug("Add outobund establish state to: " + to); _log.debug("Add outbound establish state to: " + to);
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Add indirect outbound establish state to: " + addr);
to = new RemoteHostId(msg.getTarget().getIdentity().calculateHash().getData());
}
OutboundEstablishState state = null; OutboundEstablishState state = null;
int deferred = 0; int deferred = 0;
@ -465,12 +472,18 @@ public class EstablishmentManager {
long now = _context.clock().now(); long now = _context.clock().now();
if (_log.shouldLog(Log.DEBUG)) if (_log.shouldLog(Log.DEBUG))
_log.debug("Send request to: " + state.getRemoteHostId().toString()); _log.debug("Send request to: " + state.getRemoteHostId().toString());
_transport.send(_builder.buildSessionRequestPacket(state)); UDPPacket packet = _builder.buildSessionRequestPacket(state);
if (packet != null) {
_transport.send(packet);
} else {
if (_log.shouldLog(Log.WARN))
_log.warn("Unable to build a session request packet for " + state.getRemoteHostId());
}
state.requestSent(); state.requestSent();
} }
private static final long MAX_NONCE = 0xFFFFFFFFl; private static final long MAX_NONCE = 0xFFFFFFFFl;
/** if we don't get a relayResponse in 3 seconds, try again with another intro peer */ /** if we don't get a relayResponse in 3 seconds, try again */
private static final int INTRO_ATTEMPT_TIMEOUT = 3*1000; private static final int INTRO_ATTEMPT_TIMEOUT = 3*1000;
private void handlePendingIntro(OutboundEstablishState state) { private void handlePendingIntro(OutboundEstablishState state) {
@ -488,7 +501,11 @@ public class EstablishmentManager {
SimpleTimer.getInstance().addEvent(new FailIntroduction(state, nonce), INTRO_ATTEMPT_TIMEOUT); SimpleTimer.getInstance().addEvent(new FailIntroduction(state, nonce), INTRO_ATTEMPT_TIMEOUT);
state.setIntroNonce(nonce); state.setIntroNonce(nonce);
_context.statManager().addRateData("udp.sendIntroRelayRequest", 1, 0); _context.statManager().addRateData("udp.sendIntroRelayRequest", 1, 0);
_transport.send(_builder.buildRelayRequest(_transport, state, _transport.getIntroKey())); UDPPacket requests[] = _builder.buildRelayRequest(_transport, state, _transport.getIntroKey());
for (int i = 0; i < requests.length; i++) {
if (requests[i] != null)
_transport.send(requests[i]);
}
if (_log.shouldLog(Log.DEBUG)) if (_log.shouldLog(Log.DEBUG))
_log.debug("Send intro for " + state.getRemoteHostId().toString() + " with our intro key as " + _transport.getIntroKey().toBase64()); _log.debug("Send intro for " + state.getRemoteHostId().toString() + " with our intro key as " + _transport.getIntroKey().toBase64());
state.introSent(); state.introSent();
@ -542,7 +559,15 @@ public class EstablishmentManager {
} }
_context.statManager().addRateData("udp.receiveIntroRelayResponse", state.getLifetime(), 0); _context.statManager().addRateData("udp.receiveIntroRelayResponse", state.getLifetime(), 0);
int port = reader.getRelayResponseReader().readCharliePort(); int port = reader.getRelayResponseReader().readCharliePort();
if (_log.shouldLog(Log.INFO))
_log.info("Received relay intro for " + state.getRemoteIdentity().calculateHash().toBase64() + " - they are on "
+ addr.toString() + ":" + port + " (according to " + bob.toString(true) + ")");
RemoteHostId oldId = state.getRemoteHostId();
state.introduced(addr, ip, port); state.introduced(addr, ip, port);
synchronized (_outboundStates) {
_outboundStates.remove(oldId);
_outboundStates.put(state.getRemoteHostId(), state);
}
notifyActivity(); notifyActivity();
} }

View File

@ -77,9 +77,15 @@ public class OutboundEstablishState {
RouterIdentity remotePeer, SessionKey introKey, UDPAddress addr) { RouterIdentity remotePeer, SessionKey introKey, UDPAddress addr) {
_context = ctx; _context = ctx;
_log = ctx.logManager().getLog(OutboundEstablishState.class); _log = ctx.logManager().getLog(OutboundEstablishState.class);
_bobIP = (remoteHost != null ? remoteHost.getAddress() : null); if ( (remoteHost != null) && (remotePort > 0) ) {
_bobIP = remoteHost.getAddress();
_bobPort = remotePort; _bobPort = remotePort;
_remoteHostId = new RemoteHostId(_bobIP, _bobPort); _remoteHostId = new RemoteHostId(_bobIP, _bobPort);
} else {
_bobIP = null;
_bobPort = -1;
_remoteHostId = new RemoteHostId(remotePeer.calculateHash().getData());
}
_remotePeer = remotePeer; _remotePeer = remotePeer;
_introKey = introKey; _introKey = introKey;
_keyBuilder = null; _keyBuilder = null;
@ -387,6 +393,8 @@ public class OutboundEstablishState {
_bobIP = bobIP; _bobIP = bobIP;
_bobPort = bobPort; _bobPort = bobPort;
_remoteHostId = new RemoteHostId(bobIP, bobPort); _remoteHostId = new RemoteHostId(bobIP, bobPort);
if (_log.shouldLog(Log.INFO))
_log.info("Introduced to " + _remoteHostId + ", now lets get on with establishing");
} }
/** how long have we been trying to establish this session? */ /** how long have we been trying to establish this session? */

View File

@ -746,28 +746,28 @@ public class PacketBuilder {
private byte[] getOurExplicitIP() { return null; } private byte[] getOurExplicitIP() { return null; }
private int getOurExplicitPort() { return 0; } private int getOurExplicitPort() { return 0; }
public UDPPacket buildRelayRequest(UDPTransport transport, OutboundEstablishState state, SessionKey ourIntroKey) { /** build intro packets for each of the published introducers */
public UDPPacket[] buildRelayRequest(UDPTransport transport, OutboundEstablishState state, SessionKey ourIntroKey) {
UDPAddress addr = state.getRemoteAddress(); UDPAddress addr = state.getRemoteAddress();
int count = addr.getIntroducerCount(); int count = addr.getIntroducerCount();
if (count <= 0) if (count <= 0)
return null; return new UDPPacket[0];
int index = _context.random().nextInt(count); UDPPacket rv[] = new UDPPacket[count];
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
int cur = (i + index) % count; InetAddress iaddr = addr.getIntroducerHost(i);
InetAddress iaddr = addr.getIntroducerHost(cur); int iport = addr.getIntroducerPort(i);
int iport = addr.getIntroducerPort(cur); byte ikey[] = addr.getIntroducerKey(i);
byte ikey[] = addr.getIntroducerKey(cur); long tag = addr.getIntroducerTag(i);
long tag = addr.getIntroducerTag(cur);
if ( (ikey == null) || (iport <= 0) || (iaddr == null) || (tag <= 0) ) { if ( (ikey == null) || (iport <= 0) || (iaddr == null) || (tag <= 0) ) {
if (_log.shouldLog(_log.WARN)) if (_log.shouldLog(_log.WARN))
_log.warn("Cannot build a relay request to " + state.getRemoteIdentity().calculateHash().toBase64() _log.warn("Cannot build a relay request to " + state.getRemoteIdentity().calculateHash().toBase64()
+ ", as their UDP address is invalid: addr=" + addr + " index=" + cur); + ", as their UDP address is invalid: addr=" + addr + " index=" + i);
continue; continue;
} }
if (transport.isValid(iaddr.getAddress())) if (transport.isValid(iaddr.getAddress()))
return buildRelayRequest(iaddr, iport, ikey, tag, ourIntroKey, state.getIntroNonce(), true); rv[i] = buildRelayRequest(iaddr, iport, ikey, tag, ourIntroKey, state.getIntroNonce(), true);
} }
return null; return rv;
} }
public UDPPacket buildRelayRequest(InetAddress introHost, int introPort, byte introKey[], long introTag, SessionKey ourIntroKey, long introNonce, boolean encrypt) { public UDPPacket buildRelayRequest(InetAddress introHost, int introPort, byte introKey[], long introTag, SessionKey ourIntroKey, long introNonce, boolean encrypt) {

View File

@ -1,28 +1,37 @@
package net.i2p.router.transport.udp; package net.i2p.router.transport.udp;
import net.i2p.data.Base64;
import net.i2p.data.DataHelper; import net.i2p.data.DataHelper;
/** /**
* Unique ID for a peer - its IP + port, all bundled into a tidy obj. * Unique ID for a peer - its IP + port, all bundled into a tidy obj.
* Aint it cute? * If the remote peer is not reachabe through an IP+port, this contains
* the hash of their identity.
* *
*/ */
final class RemoteHostId { final class RemoteHostId {
private byte _ip[]; private byte _ip[];
private int _port; private int _port;
private byte _peerHash[];
public RemoteHostId(byte ip[], int port) { public RemoteHostId(byte ip[], int port) {
_ip = ip; _ip = ip;
_port = port; _port = port;
} }
public RemoteHostId(byte peerHash[]) {
_peerHash = peerHash;
}
public byte[] getIP() { return _ip; } public byte[] getIP() { return _ip; }
public int getPort() { return _port; } public int getPort() { return _port; }
public byte[] getPeerHash() { return _peerHash; }
public int hashCode() { public int hashCode() {
int rv = 0; int rv = 0;
for (int i = 0; i < _ip.length; i++) for (int i = 0; _ip != null && i < _ip.length; i++)
rv += _ip[i] << i; rv += _ip[i] << i;
for (int i = 0; _peerHash != null && i < _peerHash.length; i++)
rv += _peerHash[i] << i;
rv += _port; rv += _port;
return rv; return rv;
} }
@ -33,15 +42,19 @@ final class RemoteHostId {
if (!(obj instanceof RemoteHostId)) if (!(obj instanceof RemoteHostId))
throw new ClassCastException("obj is a " + obj.getClass().getName()); throw new ClassCastException("obj is a " + obj.getClass().getName());
RemoteHostId id = (RemoteHostId)obj; RemoteHostId id = (RemoteHostId)obj;
return (_port == id.getPort()) && DataHelper.eq(_ip, id.getIP()); return (_port == id.getPort()) && DataHelper.eq(_ip, id.getIP()) && DataHelper.eq(_peerHash, id.getPeerHash());
} }
public String toString() { return toString(true); } public String toString() { return toString(true); }
public String toString(boolean includePort) { public String toString(boolean includePort) {
if (_ip != null) {
if (includePort) if (includePort)
return toString(_ip) + ':' + _port; return toString(_ip) + ':' + _port;
else else
return toString(_ip); return toString(_ip);
} else {
return Base64.encode(_peerHash);
}
} }
public static String toString(byte ip[]) { public static String toString(byte ip[]) {
StringBuffer buf = new StringBuffer(ip.length+5); StringBuffer buf = new StringBuffer(ip.length+5);

View File

@ -97,6 +97,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
/** do we require introducers, regardless of our status? */ /** do we require introducers, regardless of our status? */
public static final String PROP_FORCE_INTRODUCERS = "i2np.udp.forceIntroducers"; public static final String PROP_FORCE_INTRODUCERS = "i2np.udp.forceIntroducers";
/** do we allow direct SSU connections, sans introducers? */
public static final String PROP_ALLOW_DIRECT = "i2np.udp.allowDirect";
/** how many relays offered to us will we use at a time? */ /** how many relays offered to us will we use at a time? */
public static final int PUBLIC_RELAY_COUNT = 3; public static final int PUBLIC_RELAY_COUNT = 3;
@ -798,7 +800,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
_introducersSelectedOn = _context.clock().now(); _introducersSelectedOn = _context.clock().now();
} }
} }
if ( (_externalListenPort > 0) && (_externalListenHost != null) && (isValid(_externalListenHost.getAddress())) ) { if ( allowDirectUDP() && (_externalListenPort > 0) && (_externalListenHost != null) && (isValid(_externalListenHost.getAddress())) ) {
options.setProperty(UDPAddress.PROP_PORT, String.valueOf(_externalListenPort)); options.setProperty(UDPAddress.PROP_PORT, String.valueOf(_externalListenPort));
options.setProperty(UDPAddress.PROP_HOST, _externalListenHost.getHostAddress()); options.setProperty(UDPAddress.PROP_HOST, _externalListenHost.getHostAddress());
// if we have explicit external addresses, they had better be reachable // if we have explicit external addresses, they had better be reachable
@ -866,6 +868,11 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
} }
} }
private boolean allowDirectUDP() {
String allowDirect = _context.getProperty(PROP_ALLOW_DIRECT);
return ( (allowDirect == null) || (Boolean.valueOf(allowDirect).booleanValue()) );
}
String getPacketHandlerStatus() { String getPacketHandlerStatus() {
PacketHandler handler = _handler; PacketHandler handler = _handler;
if (handler != null) if (handler != null)