make persistent client dests work

This commit is contained in:
zzz
2009-03-01 23:14:38 +00:00
parent c455fa6309
commit 8f5257d5dc
6 changed files with 80 additions and 25 deletions

View File

@ -552,14 +552,14 @@ public class I2PTunnel implements Logging, EventDispatcher {
* Integer port number if the client is listening
* sharedClient parameter is a String "true" or "false"
*
* @param args {portNumber, destinationBase64 or "file:filename"[, sharedClient]}
* @param args {portNumber, destinationBase64 or "file:filename"[, sharedClient [, privKeyFile]]}
* @param l logger to receive events and output
*/
public void runClient(String args[], Logging l) {
boolean isShared = true;
if (args.length == 3)
if (args.length >= 3)
isShared = Boolean.valueOf(args[2].trim()).booleanValue();
if ( (args.length == 2) || (args.length == 3) ) {
if (args.length >= 2) {
int portNum = -1;
try {
portNum = Integer.parseInt(args[0]);
@ -572,7 +572,10 @@ public class I2PTunnel implements Logging, EventDispatcher {
I2PTunnelTask task;
ownDest = !isShared;
try {
task = new I2PTunnelClient(portNum, args[1], l, ownDest, (EventDispatcher) this, this);
String privateKeyFile = null;
if (args.length >= 4)
privateKeyFile = args[3];
task = new I2PTunnelClient(portNum, args[1], l, ownDest, (EventDispatcher) this, this, privateKeyFile);
addtask(task);
notifyEvent("clientTaskId", Integer.valueOf(task.getId()));
} catch (IllegalArgumentException iae) {
@ -581,7 +584,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
notifyEvent("clientTaskId", Integer.valueOf(-1));
}
} else {
l.log("client <port> <pubkey>[,<pubkey>]|file:<pubkeyfile>[ <sharedClient>]");
l.log("client <port> <pubkey>[,<pubkey>]|file:<pubkeyfile>[ <sharedClient>] [<privKeyFile>]");
l.log(" creates a client that forwards port to the pubkey.\n"
+ " use 0 as port to get a free port assigned. If you specify\n"
+ " a comma delimited list of pubkeys, it will rotate among them\n"
@ -720,11 +723,11 @@ public class I2PTunnel implements Logging, EventDispatcher {
* Also sets "ircclientStatus" = "ok" or "error" after the client tunnel has started.
* parameter sharedClient is a String, either "true" or "false"
*
* @param args {portNumber,destinationBase64 or "file:filename" [, sharedClient]}
* @param args {portNumber,destinationBase64 or "file:filename" [, sharedClient [, privKeyFile]]}
* @param l logger to receive events and output
*/
public void runIrcClient(String args[], Logging l) {
if (args.length >= 2 && args.length <= 3) {
if (args.length >= 2) {
int port = -1;
try {
port = Integer.parseInt(args[0]);
@ -751,7 +754,10 @@ public class I2PTunnel implements Logging, EventDispatcher {
I2PTunnelTask task;
ownDest = !isShared;
try {
task = new I2PTunnelIRCClient(port, args[1],l, ownDest, (EventDispatcher) this, this);
String privateKeyFile = null;
if (args.length >= 4)
privateKeyFile = args[3];
task = new I2PTunnelIRCClient(port, args[1], l, ownDest, (EventDispatcher) this, this, privateKeyFile);
addtask(task);
notifyEvent("ircclientTaskId", Integer.valueOf(task.getId()));
} catch (IllegalArgumentException iae) {
@ -760,7 +766,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
notifyEvent("ircclientTaskId", Integer.valueOf(-1));
}
} else {
l.log("ircclient <port> [<sharedClient>]");
l.log("ircclient <port> [<sharedClient> [<privKeyFile>]]");
l.log(" creates a client that filter IRC protocol.");
l.log(" <sharedClient> (optional) indicates if this client shares tunnels with other clients (true of false)");
notifyEvent("ircclientTaskId", Integer.valueOf(-1));

View File

@ -31,8 +31,8 @@ public class I2PTunnelClient extends I2PTunnelClientBase {
*/
public I2PTunnelClient(int localPort, String destinations, Logging l,
boolean ownDest, EventDispatcher notifyThis,
I2PTunnel tunnel) throws IllegalArgumentException {
super(localPort, ownDest, l, notifyThis, "SynSender", tunnel);
I2PTunnel tunnel, String pkf) throws IllegalArgumentException {
super(localPort, ownDest, l, notifyThis, "SynSender", tunnel, pkf);
if (waitEventValue("openBaseClientResult").equals("error")) {
notifyEvent("openClientResult", "error");

View File

@ -3,6 +3,7 @@
*/
package net.i2p.i2ptunnel;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.ConnectException;
@ -59,6 +60,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
private byte[] pubkey;
private String handlerName;
private String privKeyFile;
private Object conLock = new Object();
@ -91,18 +93,28 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
// I2PTunnelClientBase(localPort, ownDest, l, (EventDispatcher)null);
//}
public I2PTunnelClientBase(int localPort, boolean ownDest, Logging l,
EventDispatcher notifyThis, String handlerName,
I2PTunnel tunnel) throws IllegalArgumentException {
this(localPort, ownDest, l, notifyThis, handlerName, tunnel, null);
}
/**
* @param privKeyFile null to generate a transient key
*
* @throws IllegalArgumentException if the I2CP configuration is b0rked so
* badly that we cant create a socketManager
*/
public I2PTunnelClientBase(int localPort, boolean ownDest, Logging l,
EventDispatcher notifyThis, String handlerName,
I2PTunnel tunnel) throws IllegalArgumentException{
I2PTunnel tunnel, String pkf) throws IllegalArgumentException{
super(localPort + " (uninitialized)", notifyThis, tunnel);
_clientId = ++__clientId;
this.localPort = localPort;
this.l = l;
this.handlerName = handlerName + _clientId;
this.privKeyFile = pkf;
_context = tunnel.getContext();
_context.statManager().createRateStat("i2ptunnel.client.closeBacklog", "How many pending sockets remain when we close one due to backlog?", "I2PTunnel", new long[] { 60*1000, 10*60*1000, 60*60*1000 });
@ -195,28 +207,34 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
private static I2PSocketManager socketManager;
protected synchronized I2PSocketManager getSocketManager() {
return getSocketManager(getTunnel());
return getSocketManager(getTunnel(), this.privKeyFile);
}
protected static synchronized I2PSocketManager getSocketManager(I2PTunnel tunnel) {
return getSocketManager(tunnel, null);
}
protected static synchronized I2PSocketManager getSocketManager(I2PTunnel tunnel, String pkf) {
if (socketManager != null) {
I2PSession s = socketManager.getSession();
if ( (s == null) || (s.isClosed()) ) {
_log.info("Building a new socket manager since the old one closed [s=" + s + "]");
socketManager = buildSocketManager(tunnel);
socketManager = buildSocketManager(tunnel, pkf);
} else {
_log.info("Not building a new socket manager since the old one is open [s=" + s + "]");
}
} else {
_log.info("Building a new socket manager since there is no other one");
socketManager = buildSocketManager(tunnel);
socketManager = buildSocketManager(tunnel, pkf);
}
return socketManager;
}
protected I2PSocketManager buildSocketManager() {
return buildSocketManager(getTunnel());
return buildSocketManager(getTunnel(), this.privKeyFile);
}
protected static I2PSocketManager buildSocketManager(I2PTunnel tunnel) {
return buildSocketManager(tunnel, null);
}
protected static I2PSocketManager buildSocketManager(I2PTunnel tunnel, String pkf) {
Properties props = new Properties();
props.putAll(tunnel.getClientOptions());
int portNum = 7654;
@ -230,10 +248,22 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
I2PSocketManager sockManager = null;
while (sockManager == null) {
// if persistent dest
// sockManager = I2PSocketManagerFactory.createManager(privData, tunnel.host, portNum, props);
// else
if (pkf != null) {
// Persistent client dest
FileInputStream fis = null;
try {
fis = new FileInputStream(pkf);
sockManager = I2PSocketManagerFactory.createManager(fis, tunnel.host, portNum, props);
} catch (IOException ioe) {
_log.error("Error opening key file", ioe);
// this is going to loop but if we break we'll get a NPE
} finally {
if (fis != null)
try { fis.close(); } catch (IOException ioe) {}
}
} else {
sockManager = I2PSocketManagerFactory.createManager(tunnel.host, portNum, props);
}
if (sockManager == null) {
_log.log(Log.CRIT, "Unable to create socket manager");

View File

@ -39,12 +39,12 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
Logging l,
boolean ownDest,
EventDispatcher notifyThis,
I2PTunnel tunnel) throws IllegalArgumentException {
I2PTunnel tunnel, String pkf) throws IllegalArgumentException {
super(localPort,
ownDest,
l,
notifyThis,
"IRCHandler " + (++__clientId), tunnel);
"IRCHandler " + (++__clientId), tunnel, pkf);
StringTokenizer tok = new StringTokenizer(destinations, ",");
dests = new ArrayList(1);

View File

@ -192,8 +192,13 @@ public class TunnelController implements Logging {
String listenPort = getListenPort();
String dest = getTargetDestination();
String sharedClient = getSharedClient();
if (getPersistentClientKey()) {
String privKeyFile = getPrivKeyFile();
_tunnel.runIrcClient(new String[] { listenPort, dest, sharedClient, privKeyFile }, this);
} else {
_tunnel.runIrcClient(new String[] { listenPort, dest, sharedClient }, this);
}
}
private void startSocksClient() {
setListenOn();
@ -264,8 +269,13 @@ public class TunnelController implements Logging {
String listenPort = getListenPort();
String dest = getTargetDestination();
String sharedClient = getSharedClient();
if (getPersistentClientKey()) {
String privKeyFile = getPrivKeyFile();
_tunnel.runClient(new String[] { listenPort, dest, sharedClient, privKeyFile }, this);
} else {
_tunnel.runClient(new String[] { listenPort, dest, sharedClient }, this);
}
}
private void startServer() {
String targetHost = getTargetHost();
@ -395,7 +405,7 @@ public class TunnelController implements Logging {
public String getProxyList() { return _config.getProperty("proxyList"); }
public String getSharedClient() { return _config.getProperty("sharedClient", "true"); }
public boolean getStartOnLoad() { return "true".equalsIgnoreCase(_config.getProperty("startOnLoad", "true")); }
public boolean getPersistentClientKey() { return Boolean.valueOf(_config.getProperty("persistentClientKey")).booleanValue(); }
public boolean getPersistentClientKey() { return Boolean.valueOf(_config.getProperty("option.persistentClientKey")).booleanValue(); }
public String getMyDestination() {
if (_tunnel != null) {
List sessions = _tunnel.getSessions();

View File

@ -351,6 +351,7 @@
<hr />
</div>
<% if ("client".equals(tunnelType) || "ircclient".equals(tunnelType)) { %>
<div id="optionsField" class="rowItem">
<label for="privKeyFile" accesskey="k">
Persistent private <span class="accessKey">k</span>ey:
@ -365,10 +366,18 @@
<label>File:</label>
<input type="text" size="30" id="clientHost" name="privKeyFile" title="Path to Private Key File" value="<%=editBean.getPrivateKeyFile(curTunnel)%>" class="freetext" />
</div>
<div id="destinationField" class="rowItem">
<label for="localDestination" accesskey="L">
<span class="accessKey">L</span>ocal destination:
</label>
<textarea rows="1" cols="60" readonly="readonly" id="localDestination" title="Read Only: Local Destination (if known)" wrap="off"><%=editBean.getDestinationBase64(curTunnel)%></textarea>
<span class="comment">(if known)</span>
</div>
<div class="subdivider">
<hr />
</div>
<% } %>
<div id="customOptionsField" class="rowItem">
<label for="customOptions" accesskey="u">