forked from I2P_Developers/i2p.i2p
i2ptunnel: Fixes and cleanups for command line testing;
catch IAE from getInstance() if i2ptunnel.config isn't found in app context; log tweaks; config command tweaks Unit tests: Fix several NPEs in LocalClientManager, implement HostLookup
This commit is contained in:
@ -1328,25 +1328,30 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
* @param l logger to receive events and output
|
||||
*/
|
||||
private void runConfig(String args[], Logging l) {
|
||||
if (args.length >= 2) {
|
||||
if (args.length >= 1) {
|
||||
int i = 0;
|
||||
if (args[0].equals("-s")) {
|
||||
boolean ssl = args[0].equals("-s");
|
||||
if (ssl) {
|
||||
_clientOptions.setProperty("i2cp.SSL", "true");
|
||||
i++;
|
||||
} else {
|
||||
_clientOptions.remove("i2cp.SSL");
|
||||
}
|
||||
host = args[i++];
|
||||
listenHost = host;
|
||||
port = args[i];
|
||||
if (i < args.length) {
|
||||
host = args[i++];
|
||||
listenHost = host;
|
||||
}
|
||||
if (i < args.length)
|
||||
port = args[i];
|
||||
l.log("New setting: " + host + ' ' + port + (ssl ? " SSL" : " non-SSL"));
|
||||
notifyEvent("configResult", "ok");
|
||||
} else {
|
||||
boolean ssl = Boolean.parseBoolean(_clientOptions.getProperty("i2cp.SSL"));
|
||||
l.log("Usage:\n" +
|
||||
" config [-s] <i2phost> <i2pport>\n" +
|
||||
" sets the connection to the i2p router.\n" +
|
||||
"Current setting:\n" +
|
||||
" " + host + ' ' + port + (ssl ? " SSL" : ""));
|
||||
" config [-s] [<i2phost>] [<i2pport>]\n" +
|
||||
" Sets the address and port of the I2P router.\n" +
|
||||
" Use -s for SSL.\n" +
|
||||
"Current setting: " + host + ' ' + port + (ssl ? " SSL" : " non-SSL"));
|
||||
notifyEvent("configResult", "error");
|
||||
}
|
||||
}
|
||||
@ -1750,8 +1755,8 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
*/
|
||||
public void log(String s) {
|
||||
System.out.println(s);
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info(getPrefix() + "Display: " + s);
|
||||
//if (_log.shouldLog(Log.INFO))
|
||||
// _log.info(getPrefix() + "Display: " + s);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1769,8 +1774,7 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
l.log("Generating new keys...");
|
||||
I2PClient client = I2PClientFactory.createClient();
|
||||
Destination d = client.createDestination(writeTo);
|
||||
l.log("Secret key saved.\n" +
|
||||
"Public key: " + d.toBase64());
|
||||
l.log("New destination: " + d.toBase32());
|
||||
writeTo.flush();
|
||||
writeTo.close();
|
||||
writePubKey(d, pubDest, l);
|
||||
@ -1793,7 +1797,7 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
try {
|
||||
Destination d = new Destination();
|
||||
d.readBytes(readFrom);
|
||||
l.log("Public key: " + d.toBase64());
|
||||
l.log("Destination: " + d.toBase32());
|
||||
readFrom.close();
|
||||
writePubKey(d, pubDest, l);
|
||||
} catch (I2PException ex) {
|
||||
@ -1808,7 +1812,7 @@ public class I2PTunnel extends EventDispatcherImpl implements Logging {
|
||||
* Deprecated - only used by CLI
|
||||
*
|
||||
* @param d Destination to write
|
||||
* @param o stream to write the destination to
|
||||
* @param o stream to write the destination to, or null for noop
|
||||
* @param l logger to send messages to
|
||||
*/
|
||||
private static void writePubKey(Destination d, OutputStream o, Logging l) throws I2PException, IOException {
|
||||
|
@ -102,6 +102,7 @@ public class TunnelControllerGroup implements ClientApp {
|
||||
* @param mgr may be null
|
||||
* @param args one arg, the config file, if not absolute will be relative to the context's config dir,
|
||||
* if empty or null, the default is i2ptunnel.config
|
||||
* @throws IllegalArgumentException if too many args
|
||||
* @since 0.9.4
|
||||
*/
|
||||
public TunnelControllerGroup(I2PAppContext context, ClientAppManager mgr, String[] args) {
|
||||
@ -149,7 +150,19 @@ public class TunnelControllerGroup implements ClientApp {
|
||||
* @since 0.9.4
|
||||
*/
|
||||
public void startup() {
|
||||
loadControllers(_configFile);
|
||||
try {
|
||||
loadControllers(_configFile);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
if (DEFAULT_CONFIG_FILE.equals(_configFile) && !_context.isRouterContext()) {
|
||||
// for i2ptunnel command line
|
||||
synchronized (_controllersLoadedLock) {
|
||||
_controllersLoaded = true;
|
||||
}
|
||||
_log.logAlways(Log.WARN, "Not in router context and no preconfigured tunnels");
|
||||
} else {
|
||||
throw iae;
|
||||
}
|
||||
}
|
||||
startControllers();
|
||||
if (_mgr != null)
|
||||
_mgr.register(this);
|
||||
@ -274,8 +287,12 @@ public class TunnelControllerGroup implements ClientApp {
|
||||
synchronized (_controllersLoadedLock) {
|
||||
_controllersLoaded = true;
|
||||
}
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info(i + " controllers loaded from " + configFile);
|
||||
if (i > 0) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info(i + " controllers loaded from " + configFile);
|
||||
} else {
|
||||
_log.logAlways(Log.WARN, "No i2ptunnel configurations found in " + configFile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -294,6 +311,10 @@ public class TunnelControllerGroup implements ClientApp {
|
||||
synchronized(TunnelControllerGroup.this) {
|
||||
_controllersLock.readLock().lock();
|
||||
try {
|
||||
if (_controllers.size() <= 0) {
|
||||
_log.logAlways(Log.WARN, "No configured tunnels to start");
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < _controllers.size(); i++) {
|
||||
TunnelController controller = _controllers.get(i);
|
||||
if (controller.getStartOnLoad())
|
||||
|
@ -165,7 +165,9 @@ class ClientConnectionRunner {
|
||||
*/
|
||||
public synchronized void stopRunning() {
|
||||
if (_dead) return;
|
||||
if (_context.router().isAlive() && _log.shouldLog(Log.WARN))
|
||||
// router may be null in unit tests
|
||||
if ((_context.router() == null || _context.router().isAlive()) &&
|
||||
_log.shouldWarn())
|
||||
_log.warn("Stop the I2CP connection! current leaseSet: "
|
||||
+ _currentLeaseSet, new Exception("Stop client connection"));
|
||||
_dead = true;
|
||||
|
@ -15,6 +15,7 @@ import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
|
||||
import net.i2p.client.I2PClient;
|
||||
import net.i2p.router.Router;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
@ -101,17 +102,17 @@ class ClientListenerRunner implements Runnable {
|
||||
} catch (IOException ioe) {}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
if (_context.router().isAlive())
|
||||
if (isAlive())
|
||||
_log.error("Server error accepting", ioe);
|
||||
} catch (Throwable t) {
|
||||
if (_context.router().isAlive())
|
||||
if (isAlive())
|
||||
_log.error("Fatal error running client listener - killing the thread!", t);
|
||||
_listening = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
if (_context.router().isAlive())
|
||||
if (isAlive())
|
||||
_log.error("Error listening on port " + _port, ioe);
|
||||
}
|
||||
|
||||
@ -121,7 +122,7 @@ class ClientListenerRunner implements Runnable {
|
||||
_socket = null;
|
||||
}
|
||||
|
||||
if (!_context.router().isAlive()) break;
|
||||
if (!isAlive()) break;
|
||||
|
||||
if (curDelay < 60*1000)
|
||||
_log.error("Error listening, waiting " + (curDelay/1000) + "s before we try again");
|
||||
@ -131,11 +132,20 @@ class ClientListenerRunner implements Runnable {
|
||||
curDelay = Math.min(curDelay*3, 60*1000);
|
||||
}
|
||||
|
||||
if (_context.router().isAlive())
|
||||
if (isAlive())
|
||||
_log.error("CANCELING I2CP LISTEN", new Exception("I2CP Listen cancelled!!!"));
|
||||
_running = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Just so unit tests don't NPE, where router could be null.
|
||||
* @since 0.9.20
|
||||
*/
|
||||
private boolean isAlive() {
|
||||
Router r = _context.router();
|
||||
return r == null || r.isAlive();
|
||||
}
|
||||
|
||||
/** give the i2cp client 5 seconds to show that they're really i2cp clients */
|
||||
protected final static int CONNECT_TIMEOUT = 5*1000;
|
||||
private final static int LOOP_DELAY = 250;
|
||||
|
@ -8,6 +8,8 @@ import net.i2p.data.Lease;
|
||||
import net.i2p.data.LeaseSet;
|
||||
import net.i2p.data.i2cp.I2CPMessageException;
|
||||
import net.i2p.data.i2cp.I2CPMessageReader;
|
||||
import net.i2p.data.i2cp.MessageId;
|
||||
import net.i2p.data.i2cp.MessageStatusMessage;
|
||||
import net.i2p.data.i2cp.RequestVariableLeaseSetMessage;
|
||||
import net.i2p.router.Job;
|
||||
import net.i2p.router.RouterContext;
|
||||
@ -54,6 +56,27 @@ class LocalClientConnectionRunner extends ClientConnectionRunner {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* No job queue, so super NPEs
|
||||
*/
|
||||
@Override
|
||||
void updateMessageDeliveryStatus(MessageId id, long messageNonce, int status) {
|
||||
if (messageNonce <= 0)
|
||||
return;
|
||||
MessageStatusMessage msg = new MessageStatusMessage();
|
||||
msg.setMessageId(id.getMessageId());
|
||||
msg.setSessionId(getSessionId().getSessionId());
|
||||
// has to be >= 0, it is initialized to -1
|
||||
msg.setNonce(messageNonce);
|
||||
msg.setSize(0);
|
||||
msg.setStatus(status);
|
||||
try {
|
||||
doSend(msg);
|
||||
} catch (I2CPMessageException ime) {
|
||||
_log.warn("Error updating the status for " + id, ime);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* So LocalClientMessageEventListener can lookup other local dests
|
||||
*/
|
||||
|
@ -73,7 +73,7 @@ class LocalClientManager extends ClientManager {
|
||||
ClientManager mgr = new LocalClientManager(ctx, port);
|
||||
mgr.start();
|
||||
System.out.println("Listening on port " + port);
|
||||
try { Thread.sleep(5*60*1000); } catch (InterruptedException ie) {}
|
||||
try { Thread.sleep(60*60*1000); } catch (InterruptedException ie) {}
|
||||
System.out.println("Done listening on port " + port);
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,9 @@ package net.i2p.router.client;
|
||||
*/
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
|
||||
import net.i2p.data.Base32;
|
||||
import net.i2p.data.Destination;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.Lease;
|
||||
@ -20,7 +22,10 @@ import net.i2p.data.i2cp.CreateLeaseSetMessage;
|
||||
import net.i2p.data.i2cp.DestLookupMessage;
|
||||
import net.i2p.data.i2cp.DestReplyMessage;
|
||||
import net.i2p.data.i2cp.GetBandwidthLimitsMessage;
|
||||
import net.i2p.data.i2cp.HostLookupMessage;
|
||||
import net.i2p.data.i2cp.HostReplyMessage;
|
||||
import net.i2p.data.i2cp.I2CPMessageException;
|
||||
import net.i2p.data.i2cp.SessionId;
|
||||
import net.i2p.router.RouterContext;
|
||||
|
||||
/**
|
||||
@ -78,6 +83,40 @@ class LocalClientMessageEventListener extends ClientMessageEventListener {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Look only in current local dests
|
||||
*/
|
||||
@Override
|
||||
protected void handleHostLookup(HostLookupMessage message) {
|
||||
Hash h = message.getHash();
|
||||
String name = message.getHostname();
|
||||
long reqID = message.getReqID();
|
||||
SessionId sessID = message.getSessionId();
|
||||
if (h == null && name != null && name.length() == 60) {
|
||||
// convert a b32 lookup to a hash lookup
|
||||
String nlc = name.toLowerCase(Locale.US);
|
||||
if (nlc.endsWith(".b32.i2p")) {
|
||||
byte[] b = Base32.decode(nlc.substring(0, 52));
|
||||
if (b != null && b.length == Hash.HASH_LENGTH) {
|
||||
h = Hash.create(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
Destination d = null;
|
||||
if (h != null)
|
||||
d = ((LocalClientConnectionRunner)_runner).localLookup(h);
|
||||
HostReplyMessage msg;
|
||||
if (d != null)
|
||||
msg = new HostReplyMessage(sessID, d, reqID);
|
||||
else
|
||||
msg = new HostReplyMessage(sessID, HostReplyMessage.RESULT_FAILURE, reqID);
|
||||
try {
|
||||
_runner.doSend(msg);
|
||||
} catch (I2CPMessageException ime) {
|
||||
ime.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send dummy limits
|
||||
*/
|
||||
|
Reference in New Issue
Block a user