2006-04-01 jrandom
* Take out the router watchdog's teeth (don't restart on leaseset failure) * Filter the IRC ping/pong messages, as some clients send unsafe information in them (thanks aardvax and dust!)
This commit is contained in:
@ -27,6 +27,8 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
|||||||
protected List dests;
|
protected List dests;
|
||||||
private static final long DEFAULT_READ_TIMEOUT = 5*60*1000; // -1
|
private static final long DEFAULT_READ_TIMEOUT = 5*60*1000; // -1
|
||||||
protected long readTimeout = DEFAULT_READ_TIMEOUT;
|
protected long readTimeout = DEFAULT_READ_TIMEOUT;
|
||||||
|
/** this is the pong response the client expects for their last ping. at least, i hope so... */
|
||||||
|
private String _expectedPong;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws IllegalArgumentException if the I2PTunnel does not contain
|
* @throws IllegalArgumentException if the I2PTunnel does not contain
|
||||||
@ -44,6 +46,8 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
|||||||
l,
|
l,
|
||||||
notifyThis,
|
notifyThis,
|
||||||
"IRCHandler " + (++__clientId), tunnel);
|
"IRCHandler " + (++__clientId), tunnel);
|
||||||
|
|
||||||
|
_expectedPong = null;
|
||||||
|
|
||||||
StringTokenizer tok = new StringTokenizer(destinations, ",");
|
StringTokenizer tok = new StringTokenizer(destinations, ",");
|
||||||
dests = new ArrayList(1);
|
dests = new ArrayList(1);
|
||||||
@ -147,6 +151,8 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
|||||||
break;
|
break;
|
||||||
if(inmsg.endsWith("\r"))
|
if(inmsg.endsWith("\r"))
|
||||||
inmsg=inmsg.substring(0,inmsg.length()-1);
|
inmsg=inmsg.substring(0,inmsg.length()-1);
|
||||||
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
|
_log.debug("in: [" + inmsg + "]");
|
||||||
String outmsg = inboundFilter(inmsg);
|
String outmsg = inboundFilter(inmsg);
|
||||||
if(outmsg!=null)
|
if(outmsg!=null)
|
||||||
{
|
{
|
||||||
@ -217,9 +223,41 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
|||||||
break;
|
break;
|
||||||
if(inmsg.endsWith("\r"))
|
if(inmsg.endsWith("\r"))
|
||||||
inmsg=inmsg.substring(0,inmsg.length()-1);
|
inmsg=inmsg.substring(0,inmsg.length()-1);
|
||||||
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
|
_log.debug("out: [" + inmsg + "]");
|
||||||
String outmsg = outboundFilter(inmsg);
|
String outmsg = outboundFilter(inmsg);
|
||||||
if(outmsg!=null)
|
if(outmsg!=null)
|
||||||
{
|
{
|
||||||
|
if (outmsg.indexOf("PING") >= 0) {
|
||||||
|
// Most clients just send a PING and are happy with any old PONG. Others,
|
||||||
|
// like BitchX, actually expect certain behavior. It sends two different pings:
|
||||||
|
// "PING :irc.freshcoffee.i2p" and "PING 1234567890 127.0.0.1" (where the IP is the proxy)
|
||||||
|
// the PONG to the former seems to be "PONG 127.0.0.1", while the PONG to the later is
|
||||||
|
// ":irc.freshcoffee.i2p PONG irc.freshcoffe.i2p :1234567890".
|
||||||
|
// We don't want to send them our proxy's IP address, so we need to rewrite the PING
|
||||||
|
// sent to the server, but when we get a PONG back, use what we expected, rather than
|
||||||
|
// what they sent.
|
||||||
|
//
|
||||||
|
// Yuck.
|
||||||
|
StringTokenizer tok = new StringTokenizer(inmsg, " ");
|
||||||
|
int tokens = tok.countTokens();
|
||||||
|
if ( (tokens <= 2) || (tokens == 3) ) { // "PING nonce" or "PING nonce serverIP"
|
||||||
|
tok.nextToken(); // skip
|
||||||
|
//_expectedPong = "PONG 127.0.0.1 :" + tok.nextToken();
|
||||||
|
_expectedPong = "PONG " + tok.nextToken();
|
||||||
|
} else {
|
||||||
|
// if it isn't one of those two, we will filter out all PONGs, which means
|
||||||
|
// the client will fail. whee!
|
||||||
|
if (_log.shouldLog(Log.ERROR))
|
||||||
|
_log.error("IRC client sent a PING we don't understand (\"" + inmsg + "\"), so we're filtering it");
|
||||||
|
_expectedPong = null;
|
||||||
|
}
|
||||||
|
if (_log.shouldLog(Log.WARN)) {
|
||||||
|
_log.warn("outbound rewritten PING: "+outmsg + ", waiting for [" + _expectedPong + "]");
|
||||||
|
_log.warn(" - outbound was: "+inmsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(!inmsg.equals(outmsg)) {
|
if(!inmsg.equals(outmsg)) {
|
||||||
if (_log.shouldLog(Log.WARN)) {
|
if (_log.shouldLog(Log.WARN)) {
|
||||||
_log.warn("outbound FILTERED: "+outmsg);
|
_log.warn("outbound FILTERED: "+outmsg);
|
||||||
@ -256,7 +294,7 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public static String inboundFilter(String s) {
|
public String inboundFilter(String s) {
|
||||||
|
|
||||||
String field[]=s.split(" ",4);
|
String field[]=s.split(" ",4);
|
||||||
String command;
|
String command;
|
||||||
@ -264,8 +302,8 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
|||||||
final String[] allowedCommands =
|
final String[] allowedCommands =
|
||||||
{
|
{
|
||||||
"NOTICE",
|
"NOTICE",
|
||||||
"PING",
|
//"PING",
|
||||||
"PONG",
|
//"PONG",
|
||||||
"MODE",
|
"MODE",
|
||||||
"JOIN",
|
"JOIN",
|
||||||
"NICK",
|
"NICK",
|
||||||
@ -293,6 +331,21 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
|||||||
new Integer(command);
|
new Integer(command);
|
||||||
return s;
|
return s;
|
||||||
} catch(NumberFormatException nfe){}
|
} catch(NumberFormatException nfe){}
|
||||||
|
|
||||||
|
|
||||||
|
if ("PING".equals(command))
|
||||||
|
return "PING 127.0.0.1"; // no way to know what the ircd to i2ptunnel server con is, so localhost works
|
||||||
|
if ("PONG".equals(command)) {
|
||||||
|
// Turn the received ":irc.freshcoffee.i2p PONG irc.freshcoffee.i2p :127.0.0.1"
|
||||||
|
// into ":127.0.0.1 PONG 127.0.0.1 " so that the caller can append the client's extra parameter
|
||||||
|
// though, does 127.0.0.1 work for irc clients connecting remotely? and for all of them? sure would
|
||||||
|
// be great if irc clients actually followed the RFCs here, but i guess thats too much to ask.
|
||||||
|
// If we haven't PINGed them, or the PING we sent isn't something we know how to filter, this
|
||||||
|
// is null.
|
||||||
|
String pong = _expectedPong;
|
||||||
|
_expectedPong = null;
|
||||||
|
return pong;
|
||||||
|
}
|
||||||
|
|
||||||
// Allow all allowedCommands
|
// Allow all allowedCommands
|
||||||
for(int i=0;i<allowedCommands.length;i++) {
|
for(int i=0;i<allowedCommands.length;i++) {
|
||||||
@ -331,7 +384,6 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
|||||||
final String[] allowedCommands =
|
final String[] allowedCommands =
|
||||||
{
|
{
|
||||||
"NOTICE",
|
"NOTICE",
|
||||||
"PONG",
|
|
||||||
"MODE",
|
"MODE",
|
||||||
"JOIN",
|
"JOIN",
|
||||||
"NICK",
|
"NICK",
|
||||||
@ -345,7 +397,8 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
|||||||
"MAP", // seems safe enough, the ircd should protect themselves though
|
"MAP", // seems safe enough, the ircd should protect themselves though
|
||||||
"PART",
|
"PART",
|
||||||
"OPER",
|
"OPER",
|
||||||
"PING",
|
// "PONG", // replaced with a filtered PING/PONG since some clients send the server IP (thanks aardvax!)
|
||||||
|
// "PING",
|
||||||
"KICK",
|
"KICK",
|
||||||
"HELPME",
|
"HELPME",
|
||||||
"RULES",
|
"RULES",
|
||||||
@ -361,6 +414,23 @@ public class I2PTunnelIRCClient extends I2PTunnelClientBase implements Runnable
|
|||||||
|
|
||||||
command = field[0].toUpperCase();
|
command = field[0].toUpperCase();
|
||||||
|
|
||||||
|
if ("PING".equals(command)) {
|
||||||
|
// e.g. "PING", "PING nonce", or "PING nonce serverIP"
|
||||||
|
if (field.length == 1) {
|
||||||
|
return "PING";
|
||||||
|
} else if (field.length == 2) {
|
||||||
|
return "PING " + field[1];
|
||||||
|
} else if (field.length == 3) {
|
||||||
|
return "PING " + field[1];
|
||||||
|
} else {
|
||||||
|
if (_log.shouldLog(Log.ERROR))
|
||||||
|
_log.error("IRC client sent a PING we don't understand, filtering it (\"" + s + "\")");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ("PONG".equals(command))
|
||||||
|
return "PONG 127.0.0.1"; // no way to know what the ircd to i2ptunnel server con is, so localhost works
|
||||||
|
|
||||||
// Allow all allowedCommands
|
// Allow all allowedCommands
|
||||||
for(int i=0;i<allowedCommands.length;i++)
|
for(int i=0;i<allowedCommands.length;i++)
|
||||||
{
|
{
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
$Id: history.txt,v 1.441 2006/03/30 02:26:43 jrandom Exp $
|
$Id: history.txt,v 1.442 2006/04/01 14:05:37 jrandom Exp $
|
||||||
|
|
||||||
2006-04-01 jrandom
|
2006-04-01 jrandom
|
||||||
* Take out the router watchdog's teeth (don't restart on leaseset failure)
|
* Take out the router watchdog's teeth (don't restart on leaseset failure)
|
||||||
|
* Filter the IRC ping/pong messages, as some clients send unsafe
|
||||||
|
information in them (thanks aardvax and dust!)
|
||||||
|
|
||||||
2006-03-30 jrandom
|
2006-03-30 jrandom
|
||||||
* Substantially reduced the lock contention in the message registry (a
|
* Substantially reduced the lock contention in the message registry (a
|
||||||
|
@ -326,7 +326,9 @@ public abstract class I2NPMessageImpl extends DataStructureImpl implements I2NPM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void verifyUnwritten() { if (_written) throw new RuntimeException("Already written"); }
|
protected void verifyUnwritten() {
|
||||||
|
// if (_written) throw new RuntimeException("Already written");
|
||||||
|
}
|
||||||
protected void written() { _written = true; }
|
protected void written() { _written = true; }
|
||||||
protected void read() { _read = true; }
|
protected void read() { _read = true; }
|
||||||
|
|
||||||
|
@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class RouterVersion {
|
public class RouterVersion {
|
||||||
public final static String ID = "$Revision: 1.382 $ $Date: 2006/03/30 02:26:49 $";
|
public final static String ID = "$Revision: 1.383 $ $Date: 2006/04/01 14:08:41 $";
|
||||||
public final static String VERSION = "0.6.1.13";
|
public final static String VERSION = "0.6.1.13";
|
||||||
public final static long BUILD = 2;
|
public final static long BUILD = 3;
|
||||||
public static void main(String args[]) {
|
public static void main(String args[]) {
|
||||||
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
|
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
|
||||||
System.out.println("Router ID: " + RouterVersion.ID);
|
System.out.println("Router ID: " + RouterVersion.ID);
|
||||||
|
Reference in New Issue
Block a user