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
*/
protected final boolean writeString(String str) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Sending the client: [" + str + "]");
try {
writeBytes(str.getBytes("ISO-8859-1"));
} catch (IOException e) {

View File

@ -17,6 +17,7 @@ import java.net.Socket;
import java.util.Properties;
import java.util.StringTokenizer;
import net.i2p.data.DataHelper;
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
*/
public static SAMHandler createSAMHandler(Socket s, Properties i2cpProps) throws SAMException {
BufferedReader br;
String line;
StringTokenizer tok;
try {
br = new BufferedReader(new InputStreamReader(s.getInputStream(),
"ISO-8859-1"));
line = br.readLine();
line = DataHelper.readLine(s.getInputStream());
if (line == null) {
_log.debug("Connection closed by client");
return null;

View File

@ -201,12 +201,17 @@ public class SAMStreamSession {
*
* @return True if the data was sent, false otherwise
*/
public boolean sendBytes(int id, InputStream in, int size) {
Destination d = new Destination();
public boolean sendBytes(int id, InputStream in, int size) throws IOException {
SAMStreamSessionSocketHandler handler = getSocketHandler(id);
if (handler == null) {
_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;
}
@ -420,6 +425,8 @@ public class SAMStreamSession {
} catch (I2PException e) {
_log.debug("Caught I2PException", e);
}
close();
_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
*/
public boolean sendBytes(InputStream in, int size) { // byte[] data) {
public boolean sendBytes(InputStream in, int size) throws IOException {
if (_log.shouldLog(Log.DEBUG)) {
_log.debug("Handler " + id + ": sending " + size
+ " bytes");
}
ByteCache cache = ByteCache.getInstance(1024, 4);
ByteArray ba = cache.acquire();
int remaining = size;
try {
int remaining = size;
byte buf[] = ba.getData();
while (remaining > 0) {
int read = in.read(buf, 0, remaining > buf.length ? buf.length : remaining);
if (read == -1)
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;
}
//i2pSocketOS.flush();
} catch (IOException e) {
_log.error("Error sending data through I2P socket", e);
return false;
} finally {
cache.release(ba);
}

View File

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

View File

@ -670,6 +670,26 @@ public class DataHelper {
}
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) {
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
* Fix the recently broken SAM bridge (duh)

View File

@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
*
*/
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 long BUILD = 4;
public final static long BUILD = 5;
public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION);
System.out.println("Router ID: " + RouterVersion.ID);

View File

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