I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit 203d0e87 authored by jrandom's avatar jrandom Committed by zzz
Browse files

allow the user to override the I2CP options (exposed on the command line, ala

SAMBridge [[listenHost ]listenPort[ name=val]*]
where listenHost defaults to localhost, listenPort defaults to 7656, and name=val
can be the I2CP options to override (e.g. i2cp.tcp.host=localhost i2cp.tcp.port=4001)
parent bed7d097
No related branches found
No related tags found
No related merge requests found
...@@ -12,6 +12,7 @@ import java.io.IOException; ...@@ -12,6 +12,7 @@ import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
import java.util.Properties;
import net.i2p.util.I2PThread; import net.i2p.util.I2PThread;
import net.i2p.util.Log; import net.i2p.util.Log;
...@@ -25,81 +26,136 @@ public class SAMBridge implements Runnable { ...@@ -25,81 +26,136 @@ public class SAMBridge implements Runnable {
private final static Log _log = new Log(SAMBridge.class); private final static Log _log = new Log(SAMBridge.class);
private ServerSocket serverSocket; private ServerSocket serverSocket;
private Properties i2cpProps;
private boolean acceptConnections = true; private boolean acceptConnections = true;
private final static int SAM_LISTENPORT = 7656; private final static int SAM_LISTENPORT = 7656;
/** private SAMBridge() {}
* Build a new SAM bridge listening on 127.0.0.1.
*
* @param listenPort The port to listen on
*/
public SAMBridge(int listenPort) {
this((String)null, listenPort);
}
/** /**
* Build a new SAM bridge. * Build a new SAM bridge.
* *
* @param listenHost The network interface to listen on * @param listenHost hostname to listen for SAM connections on ("0.0.0.0" for all)
* @param listenPort The port to listen on * @param listenPort port number to listen for SAM connections on
* @param i2cpProps set of I2CP properties for finding and communicating with the router
*/ */
public SAMBridge(String listenHost, int listenPort) { public SAMBridge(String listenHost, int listenPort, Properties i2cpProps) {
try { try {
if (listenHost != null) { if ( (listenHost != null) && !("0.0.0.0".equals(listenHost)) ) {
serverSocket = new ServerSocket(listenPort, 0, serverSocket = new ServerSocket(listenPort, 0, InetAddress.getByName(listenHost));
InetAddress.getByName(listenHost)); if (_log.shouldLog(Log.DEBUG))
_log.debug("SAM bridge listening on " _log.debug("SAM bridge listening on "
+ listenHost + ":" + listenPort); + listenHost + ":" + listenPort);
} else { } else {
serverSocket = new ServerSocket(listenPort); serverSocket = new ServerSocket(listenPort);
_log.debug("SAM bridge listening on 0.0.0.0:" + listenPort); if (_log.shouldLog(Log.DEBUG))
} _log.debug("SAM bridge listening on 0.0.0.0:" + listenPort);
} catch (Exception e) { }
_log.error("Error starting SAM bridge on " } catch (Exception e) {
+ (listenHost == null ? "0.0.0.0" : listenHost) if (_log.shouldLog(Log.ERROR))
+ ":" + listenPort, e); _log.error("Error starting SAM bridge on "
} + (listenHost == null ? "0.0.0.0" : listenHost)
+ ":" + listenPort, e);
}
this.i2cpProps = i2cpProps;
} }
/**
* Usage:
* <pre>SAMBridge [[listenHost ]listenPort[ name=val]*]</pre>
*
* name=val options are passed to the I2CP code to build a session,
* allowing the bridge to specify an alternate I2CP host and port, tunnel
* depth, etc.
*/
public static void main(String args[]) { public static void main(String args[]) {
SAMBridge bridge = new SAMBridge(SAM_LISTENPORT); int port = SAM_LISTENPORT;
I2PThread t = new I2PThread(bridge, "SAMListener"); String host = "0.0.0.0";
t.start(); Properties opts = null;
if (args.length > 0) {
int portIndex = 0;
try {
port = Integer.parseInt(args[portIndex]);
} catch (NumberFormatException nfe) {
host = args[0];
portIndex++;
try {
port = Integer.parseInt(args[portIndex]);
} catch (NumberFormatException nfe1) {
usage();
return;
}
}
opts = parseOptions(args, portIndex+1);
}
SAMBridge bridge = new SAMBridge(host, port, opts);
I2PThread t = new I2PThread(bridge, "SAMListener");
t.start();
} }
private static Properties parseOptions(String args[], int startArgs) {
Properties props = new Properties();
// skip over first few options
for (int i = startArgs; i < args.length; i++) {
int eq = args[i].indexOf('=');
if (eq <= 0) continue;
if (eq >= args[i].length()-1) continue;
String key = args[i].substring(0, eq);
String val = args[i].substring(eq+1);
key = key.trim();
val = val.trim();
if ( (key.length() > 0) && (val.length() > 0) )
props.setProperty(key, val);
}
return props;
}
private static void usage() {
System.err.println("Usage: SAMBridge [listenHost listenPortNum[ name=val]*]");
System.err.println(" listenHost: interface to listen on (0.0.0.0 for all interfaces)");
System.err.println(" listenPort: port to listen for SAM connections on (default 7656)");
System.err.println(" name=val: options to pass when connecting via I2CP, such as ");
System.err.println(" i2cp.host=localhost and i2cp.port=7654");
}
public void run() { public void run() {
try { try {
while (acceptConnections) { while (acceptConnections) {
Socket s = serverSocket.accept(); Socket s = serverSocket.accept();
_log.debug("New connection from " if (_log.shouldLog(Log.DEBUG))
+ s.getInetAddress().toString() + ":" _log.debug("New connection from "
+ s.getPort()); + s.getInetAddress().toString() + ":"
+ s.getPort());
try {
SAMHandler handler = SAMHandlerFactory.createSAMHandler(s); try {
if (handler == null) { SAMHandler handler = SAMHandlerFactory.createSAMHandler(s, i2cpProps);
_log.debug("SAM handler has not been instantiated"); if (handler == null) {
try { if (_log.shouldLog(Log.DEBUG))
s.close(); _log.debug("SAM handler has not been instantiated");
} catch (IOException e) {} try {
continue; s.close();
} } catch (IOException e) {}
handler.startHandling(); continue;
} catch (SAMException e) { }
_log.error("SAM error: " + e.getMessage()); handler.startHandling();
s.close(); } catch (SAMException e) {
} if (_log.shouldLog(Log.ERROR))
} _log.error("SAM error: " + e.getMessage(), e);
} catch (Exception e) { s.close();
_log.error("Unexpected error while listening for connections", e); }
} finally { }
try { } catch (Exception e) {
_log.debug("Shutting down, closing server socket"); if (_log.shouldLog(Log.ERROR))
serverSocket.close(); _log.error("Unexpected error while listening for connections", e);
} catch (IOException e) {} } finally {
} try {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Shutting down, closing server socket");
serverSocket.close();
} catch (IOException e) {}
}
} }
} }
...@@ -13,6 +13,8 @@ import java.io.InputStream; ...@@ -13,6 +13,8 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.net.Socket; import java.net.Socket;
import java.util.Properties;
import net.i2p.util.I2PThread; import net.i2p.util.I2PThread;
import net.i2p.util.Log; import net.i2p.util.Log;
...@@ -35,6 +37,9 @@ public abstract class SAMHandler implements Runnable { ...@@ -35,6 +37,9 @@ public abstract class SAMHandler implements Runnable {
protected int verMajor = 0; protected int verMajor = 0;
protected int verMinor = 0; protected int verMinor = 0;
/** I2CP options configuring the I2CP connection (port, host, numHops, etc) */
protected Properties i2cpProps = null;
private Object stopLock = new Object(); private Object stopLock = new Object();
private boolean stopHandler = false; private boolean stopHandler = false;
...@@ -45,14 +50,16 @@ public abstract class SAMHandler implements Runnable { ...@@ -45,14 +50,16 @@ public abstract class SAMHandler implements Runnable {
* @param s Socket attached to a SAM client * @param s Socket attached to a SAM client
* @param verMajor SAM major version to manage * @param verMajor SAM major version to manage
* @param verMinor SAM minor version to manage * @param verMinor SAM minor version to manage
* @param i2cpProps properties to configure the I2CP connection (host, port, etc)
*/ */
protected SAMHandler(Socket s, protected SAMHandler(Socket s,
int verMajor, int verMinor) throws IOException { int verMajor, int verMinor, Properties i2cpProps) throws IOException {
socket = s; socket = s;
socketOS = socket.getOutputStream(); socketOS = socket.getOutputStream();
this.verMajor = verMajor; this.verMajor = verMajor;
this.verMinor = verMinor; this.verMinor = verMinor;
this.i2cpProps = i2cpProps;
} }
/** /**
......
...@@ -31,10 +31,11 @@ public class SAMHandlerFactory { ...@@ -31,10 +31,11 @@ public class SAMHandlerFactory {
* required by the client. * required by the client.
* *
* @param s Socket attached to SAM client * @param s Socket attached to SAM client
* @param i2cpProps config options for our i2cp connection
* *
* @return A SAM protocol handler * @return A SAM protocol handler
*/ */
public static SAMHandler createSAMHandler(Socket s) throws SAMException { public static SAMHandler createSAMHandler(Socket s, Properties i2cpProps) throws SAMException {
BufferedReader br; BufferedReader br;
String line; String line;
StringTokenizer tok; StringTokenizer tok;
...@@ -127,7 +128,7 @@ public class SAMHandlerFactory { ...@@ -127,7 +128,7 @@ public class SAMHandlerFactory {
try { try {
switch (verMajor) { switch (verMajor) {
case 1: case 1:
handler = new SAMv1Handler(s, verMajor, verMinor); handler = new SAMv1Handler(s, verMajor, verMinor, i2cpProps);
break; break;
default: default:
_log.error("BUG! Trying to initialize the wrong SAM version!"); _log.error("BUG! Trying to initialize the wrong SAM version!");
......
...@@ -55,7 +55,20 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag ...@@ -55,7 +55,20 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
* @param verMinor SAM minor version to manage * @param verMinor SAM minor version to manage
*/ */
public SAMv1Handler(Socket s, int verMajor, int verMinor) throws SAMException, IOException { public SAMv1Handler(Socket s, int verMajor, int verMinor) throws SAMException, IOException {
super(s, verMajor, verMinor); this(s, verMajor, verMinor, new Properties());
}
/**
* Create a new SAM version 1 handler. This constructor expects
* that the SAM HELLO message has been still answered (and
* stripped) from the socket input stream.
*
* @param s Socket attached to a SAM client
* @param verMajor SAM major version to manage (should be 1)
* @param verMinor SAM minor version to manage
* @param i2cpProps properties to configure the I2CP connection (host, port, etc)
*/
public SAMv1Handler(Socket s, int verMajor, int verMinor, Properties i2cpProps) throws SAMException, IOException {
super(s, verMajor, verMinor, i2cpProps);
_log.debug("SAM version 1 handler instantiated"); _log.debug("SAM version 1 handler instantiated");
if ((this.verMajor != 1) || (this.verMinor != 0)) { if ((this.verMajor != 1) || (this.verMinor != 0)) {
...@@ -113,6 +126,8 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag ...@@ -113,6 +126,8 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
+ "\"; opcode: \"" + opcode + "\")"); + "\"; opcode: \"" + opcode + "\")");
} }
props = SAMUtils.parseParams(tok); props = SAMUtils.parseParams(tok);
if (i2cpProps != null)
props.putAll(i2cpProps); // make sure we've got the i2cp settings
if (domain.equals("STREAM")) { if (domain.equals("STREAM")) {
canContinue = execStreamMessage(opcode, props); canContinue = execStreamMessage(opcode, props);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment