2004-12-05 jrandom

* Default the I2CP listener to localhost only, unless overridden by
      i2cp.tcp.bindAllInterfaces=true (thanks dm!)
    * More SAM fixes for things recently broken (whee)
This commit is contained in:
jrandom
2004-12-06 00:54:07 +00:00
committed by zzz
parent 499eeb275b
commit 88bb176f3b
8 changed files with 70 additions and 37 deletions

View File

@ -119,6 +119,8 @@ public abstract class SAMHandler implements Runnable {
* @return True is the string was successfully written, false otherwise * @return True is the string was successfully written, false otherwise
*/ */
protected final boolean writeString(String str) { protected final boolean writeString(String str) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Sending the client: [" + str + "]");
try { try {
writeBytes(str.getBytes("ISO-8859-1")); writeBytes(str.getBytes("ISO-8859-1"));
} catch (IOException e) { } catch (IOException e) {

View File

@ -17,6 +17,7 @@ import java.net.Socket;
import java.util.Properties; import java.util.Properties;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import net.i2p.data.DataHelper;
import net.i2p.util.Log; import net.i2p.util.Log;
/** /**
@ -36,14 +37,11 @@ public class SAMHandlerFactory {
* @return A SAM protocol handler, or null if the client closed before the handshake * @return A SAM protocol handler, or null if the client closed before the handshake
*/ */
public static SAMHandler createSAMHandler(Socket s, Properties i2cpProps) throws SAMException { public static SAMHandler createSAMHandler(Socket s, Properties i2cpProps) throws SAMException {
BufferedReader br;
String line; String line;
StringTokenizer tok; StringTokenizer tok;
try { try {
br = new BufferedReader(new InputStreamReader(s.getInputStream(), line = DataHelper.readLine(s.getInputStream());
"ISO-8859-1"));
line = br.readLine();
if (line == null) { if (line == null) {
_log.debug("Connection closed by client"); _log.debug("Connection closed by client");
return null; return null;

View File

@ -201,12 +201,17 @@ public class SAMStreamSession {
* *
* @return True if the data was sent, false otherwise * @return True if the data was sent, false otherwise
*/ */
public boolean sendBytes(int id, InputStream in, int size) { public boolean sendBytes(int id, InputStream in, int size) throws IOException {
Destination d = new Destination();
SAMStreamSessionSocketHandler handler = getSocketHandler(id); SAMStreamSessionSocketHandler handler = getSocketHandler(id);
if (handler == null) { if (handler == null) {
_log.error("Trying to send bytes through inexistent handler " +id); _log.error("Trying to send bytes through inexistent handler " +id);
// even though it failed, we need to read those bytes!
for (int i = 0; i < size; i++) {
int c = in.read();
if (c == -1)
break;
}
return false; return false;
} }
@ -420,6 +425,8 @@ public class SAMStreamSession {
} catch (I2PException e) { } catch (I2PException e) {
_log.debug("Caught I2PException", e); _log.debug("Caught I2PException", e);
} }
close();
_log.debug("Shutting down SAM STREAM session server"); _log.debug("Shutting down SAM STREAM session server");
} }
@ -463,27 +470,25 @@ public class SAMStreamSession {
* *
* @return True if data has been sent without errors, false otherwise * @return True if data has been sent without errors, false otherwise
*/ */
public boolean sendBytes(InputStream in, int size) { // byte[] data) { public boolean sendBytes(InputStream in, int size) throws IOException {
if (_log.shouldLog(Log.DEBUG)) { if (_log.shouldLog(Log.DEBUG)) {
_log.debug("Handler " + id + ": sending " + size _log.debug("Handler " + id + ": sending " + size
+ " bytes"); + " bytes");
} }
ByteCache cache = ByteCache.getInstance(1024, 4); ByteCache cache = ByteCache.getInstance(1024, 4);
ByteArray ba = cache.acquire(); ByteArray ba = cache.acquire();
int remaining = size;
try { try {
int remaining = size;
byte buf[] = ba.getData(); byte buf[] = ba.getData();
while (remaining > 0) { while (remaining > 0) {
int read = in.read(buf, 0, remaining > buf.length ? buf.length : remaining); int read = in.read(buf, 0, remaining > buf.length ? buf.length : remaining);
if (read == -1) if (read == -1)
throw new IOException("Insufficient data from the SAM client (" + remaining + "/" + size + ")"); throw new IOException("Insufficient data from the SAM client (" + remaining + "/" + size + ")");
i2pSocketOS.write(buf, 0, read); else if (read > 0)
i2pSocketOS.write(buf, 0, read);
remaining -= read; remaining -= read;
} }
//i2pSocketOS.flush();
} catch (IOException e) {
_log.error("Error sending data through I2P socket", e);
return false;
} finally { } finally {
cache.release(ba); cache.release(ba);
} }

View File

@ -26,6 +26,7 @@ import net.i2p.I2PException;
import net.i2p.client.I2PSessionException; import net.i2p.client.I2PSessionException;
import net.i2p.data.Base64; import net.i2p.data.Base64;
import net.i2p.data.DataFormatException; import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Destination; import net.i2p.data.Destination;
import net.i2p.util.Log; import net.i2p.util.Log;
@ -80,9 +81,10 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
} }
public void handle() { public void handle() {
String msg, domain, opcode; String msg = null;
String domain = null;
String opcode = null;
boolean canContinue = false; boolean canContinue = false;
ByteArrayOutputStream buf = new ByteArrayOutputStream(IN_BUFSIZE);
StringTokenizer tok; StringTokenizer tok;
Properties props; Properties props;
@ -99,22 +101,15 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
break; break;
} }
while ((b = in.read()) != -1) { msg = DataHelper.readLine(in);
if (b == '\n') { if (msg == null) {
break;
}
buf.write(b);
}
if (b == -1) {
_log.debug("Connection closed by client"); _log.debug("Connection closed by client");
break; break;
} }
msg = buf.toString("ISO-8859-1").trim();
if (_log.shouldLog(Log.DEBUG)) { if (_log.shouldLog(Log.DEBUG)) {
_log.debug("New message received: [" + msg + "]"); _log.debug("New message received: [" + msg + "]");
} }
buf.reset();
tok = new StringTokenizer(msg, " "); tok = new StringTokenizer(msg, " ");
if (tok.countTokens() < 2) { if (tok.countTokens() < 2) {
@ -154,14 +149,11 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
break; break;
} }
} }
} catch (UnsupportedEncodingException e) {
_log.error("Caught UnsupportedEncodingException ("
+ e.getMessage() + ")", e);
} catch (IOException e) { } catch (IOException e) {
_log.debug("Caught IOException (" _log.debug("Caught IOException ("
+ e.getMessage() + ")", e); + e.getMessage() + ") for message [" + msg + "]", e);
} catch (Exception e) { } catch (Exception e) {
_log.error("Unexpected exception", e); _log.error("Unexpected exception for message [" + msg + "]", e);
} finally { } finally {
_log.debug("Stopping handler"); _log.debug("Stopping handler");
try { try {
@ -555,7 +547,7 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
try { try {
if (!streamSession.sendBytes(id, getClientSocketInputStream(), size)) { // data)) { if (!streamSession.sendBytes(id, getClientSocketInputStream(), size)) { // data)) {
_log.error("STREAM SEND failed"); _log.error("STREAM SEND [" + size + "] failed");
boolean rv = writeString("STREAM CLOSED RESULT=CANT_REACH_PEER ID=" + id + " MESSAGE=\"Send of " + size + " bytes failed\"\n"); boolean rv = writeString("STREAM CLOSED RESULT=CANT_REACH_PEER ID=" + id + " MESSAGE=\"Send of " + size + " bytes failed\"\n");
streamSession.closeConnection(id); streamSession.closeConnection(id);
return rv; return rv;
@ -563,11 +555,11 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
return true; return true;
} catch (EOFException e) { } catch (EOFException e) {
_log.debug("Too few bytes with RAW SEND message (expected: " _log.debug("Too few bytes with STREAM SEND message (expected: "
+ size); + size);
return false; return false;
} catch (IOException e) { } catch (IOException e) {
_log.debug("Caught IOException while parsing RAW SEND message", _log.debug("Caught IOException while parsing STREAM SEND message",
e); e);
return false; return false;
} }

View File

@ -670,6 +670,26 @@ public class DataHelper {
} }
return cur; return cur;
} }
/**
* Read a newline delimited line from the stream, returning the line (without
* the newline), or null if EOF reached before the newline was found
*/
public static String readLine(InputStream in) throws IOException {
StringBuffer buf = new StringBuffer(128);
int c = -1;
while ( (c = in.read()) != -1) {
if (c == '\n')
break;
buf.append((char)c);
}
if (c == -1)
return null;
else
return buf.toString();
}
public static List sortStructures(Collection dataStructures) { public static List sortStructures(Collection dataStructures) {
if (dataStructures == null) return new ArrayList(); if (dataStructures == null) return new ArrayList();

View File

@ -1,4 +1,9 @@
$Id: history.txt,v 1.95 2004/12/05 05:22:58 jrandom Exp $ $Id: history.txt,v 1.96 2004/12/05 10:32:34 jrandom Exp $
2004-12-05 jrandom
* Default the I2CP listener to localhost only, unless overridden by
i2cp.tcp.bindAllInterfaces=true (thanks dm!)
* More SAM fixes for things recently broken (whee)
2004-12-05 jrandom 2004-12-05 jrandom
* Fix the recently broken SAM bridge (duh) * Fix the recently broken SAM bridge (duh)

View File

@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
* *
*/ */
public class RouterVersion { public class RouterVersion {
public final static String ID = "$Revision: 1.100 $ $Date: 2004/12/05 05:22:58 $"; public final static String ID = "$Revision: 1.101 $ $Date: 2004/12/05 10:32:33 $";
public final static String VERSION = "0.4.2.2"; public final static String VERSION = "0.4.2.2";
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); System.out.println("I2P Router version: " + VERSION);
System.out.println("Router ID: " + RouterVersion.ID); System.out.println("Router ID: " + RouterVersion.ID);

View File

@ -9,6 +9,7 @@ package net.i2p.router.client;
*/ */
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket; import java.net.ServerSocket;
import java.net.Socket; import java.net.Socket;
@ -28,15 +29,21 @@ public class ClientListenerRunner implements Runnable {
private ClientManager _manager; private ClientManager _manager;
private ServerSocket _socket; private ServerSocket _socket;
private int _port; private int _port;
private boolean _bindAllInterfaces;
private boolean _running; private boolean _running;
private long _nextFailDelay = 1000; private long _nextFailDelay = 1000;
public static final String BIND_ALL_INTERFACES = "i2cp.tcp.bindAllInterfaces";
public ClientListenerRunner(RouterContext context, ClientManager manager, int port) { public ClientListenerRunner(RouterContext context, ClientManager manager, int port) {
_context = context; _context = context;
_log = _context.logManager().getLog(ClientListenerRunner.class); _log = _context.logManager().getLog(ClientListenerRunner.class);
_manager = manager; _manager = manager;
_port = port; _port = port;
_running = false; _running = false;
String val = context.getProperty(BIND_ALL_INTERFACES, "False");
_bindAllInterfaces = Boolean.valueOf(val).booleanValue();
} }
public void setPort(int port) { _port = port; } public void setPort(int port) { _port = port; }
@ -55,7 +62,11 @@ public class ClientListenerRunner implements Runnable {
while (_running) { while (_running) {
try { try {
_log.info("Starting up listening for connections on port " + _port); _log.info("Starting up listening for connections on port " + _port);
_socket = new ServerSocket(_port); if (_bindAllInterfaces)
_socket = new ServerSocket(_port);
else
_socket = new ServerSocket(_port, 5, InetAddress.getLocalHost());
curDelay = 0; curDelay = 0;
while (_running) { while (_running) {
try { try {
@ -82,7 +93,7 @@ public class ClientListenerRunner implements Runnable {
if (_context.router().isAlive()) if (_context.router().isAlive())
_log.error("Error listening on port " + _port, ioe); _log.error("Error listening on port " + _port, ioe);
} }
if (_socket != null) { if (_socket != null) {
try { _socket.close(); } catch (IOException ioe) {} try { _socket.close(); } catch (IOException ioe) {}
_socket = null; _socket = null;