propagate from branch 'i2p.i2p.zzz.test' (head c92ec83848e87e27921bada8ee24fd108050a50a)
to branch 'i2p.i2p' (head efebdaa0f53b9bc0234d18a7a934cc0f4fa6231e)
This commit is contained in:
@ -46,7 +46,7 @@ public class DoCMDS implements Runnable {
|
|||||||
|
|
||||||
// FIX ME
|
// FIX ME
|
||||||
// I need a better way to do versioning, but this will do for now.
|
// I need a better way to do versioning, but this will do for now.
|
||||||
public static final String BMAJ = "00", BMIN = "00", BREV = "03", BEXT = "";
|
public static final String BMAJ = "00", BMIN = "00", BREV = "04", BEXT = "";
|
||||||
public static final String BOBversion = BMAJ + "." + BMIN + "." + BREV + BEXT;
|
public static final String BOBversion = BMAJ + "." + BMIN + "." + BREV + BEXT;
|
||||||
private Socket server;
|
private Socket server;
|
||||||
private Properties props;
|
private Properties props;
|
||||||
|
@ -70,7 +70,7 @@ public class I2Plistener implements Runnable {
|
|||||||
boolean g = false;
|
boolean g = false;
|
||||||
I2PSocket sessSocket = null;
|
I2PSocket sessSocket = null;
|
||||||
|
|
||||||
serverSocket.setSoTimeout(100);
|
serverSocket.setSoTimeout(50);
|
||||||
database.getReadLock();
|
database.getReadLock();
|
||||||
info.getReadLock();
|
info.getReadLock();
|
||||||
if(info.exists("INPORT")) {
|
if(info.exists("INPORT")) {
|
||||||
|
@ -173,7 +173,7 @@ die: {
|
|||||||
boolean spin = true;
|
boolean spin = true;
|
||||||
while(spin) {
|
while(spin) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(1000); //sleep for 1000 ms (One second)
|
Thread.sleep(200); //sleep for 200 ms (Two thenths second)
|
||||||
} catch(InterruptedException e) {
|
} catch(InterruptedException e) {
|
||||||
// nop
|
// nop
|
||||||
}
|
}
|
||||||
@ -213,14 +213,21 @@ die: {
|
|||||||
}
|
}
|
||||||
} // die
|
} // die
|
||||||
|
|
||||||
|
try {
|
||||||
|
Thread.sleep(500); //sleep for 500 ms (One half second)
|
||||||
|
} catch(InterruptedException ex) {
|
||||||
|
// nop
|
||||||
|
}
|
||||||
// wait for child threads and thread groups to die
|
// wait for child threads and thread groups to die
|
||||||
// System.out.println("MUXlisten: waiting for children");
|
// System.out.println("MUXlisten: waiting for children");
|
||||||
while(tg.activeCount() + tg.activeGroupCount() != 0) {
|
if(tg.activeCount() + tg.activeGroupCount() != 0) {
|
||||||
tg.interrupt(); // unwedge any blocking threads.
|
tg.interrupt(); // unwedge any blocking threads.
|
||||||
try {
|
while(tg.activeCount() + tg.activeGroupCount() != 0) {
|
||||||
Thread.sleep(100); //sleep for 100 ms (One tenth second)
|
try {
|
||||||
} catch(InterruptedException ex) {
|
Thread.sleep(100); //sleep for 100 ms (One tenth second)
|
||||||
// nop
|
} catch(InterruptedException ex) {
|
||||||
|
// nop
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tg.destroy();
|
tg.destroy();
|
||||||
@ -260,17 +267,33 @@ die: {
|
|||||||
}
|
}
|
||||||
// This is here to catch when something fucks up REALLY bad.
|
// This is here to catch when something fucks up REALLY bad.
|
||||||
if(tg != null) {
|
if(tg != null) {
|
||||||
while(tg.activeCount() + tg.activeGroupCount() != 0) {
|
if(tg.activeCount() + tg.activeGroupCount() != 0) {
|
||||||
tg.interrupt(); // unwedge any blocking threads.
|
tg.interrupt(); // unwedge any blocking threads.
|
||||||
|
while(tg.activeCount() + tg.activeGroupCount() != 0) {
|
||||||
try {
|
try {
|
||||||
Thread.sleep(100); //sleep for 100 ms (One tenth second)
|
Thread.sleep(100); //sleep for 100 ms (One tenth second)
|
||||||
} catch(InterruptedException ex) {
|
} catch(InterruptedException ex) {
|
||||||
// nop
|
// nop
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
tg.destroy();
|
tg.destroy();
|
||||||
// Zap reference to the ThreadGroup so the JVM can GC it.
|
// Zap reference to the ThreadGroup so the JVM can GC it.
|
||||||
tg = null;
|
tg = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lastly try to close things again.
|
||||||
|
if(this.come_in) {
|
||||||
|
try {
|
||||||
|
listener.close();
|
||||||
|
} catch(IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
socketManager.destroySocketManager();
|
||||||
|
} catch(Exception e) {
|
||||||
|
// nop
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,9 +56,28 @@ public class TCPio implements Runnable {
|
|||||||
* Copy from source to destination...
|
* Copy from source to destination...
|
||||||
* and yes, we are totally OK to block here on writes,
|
* and yes, we are totally OK to block here on writes,
|
||||||
* The OS has buffers, and I intend to use them.
|
* The OS has buffers, and I intend to use them.
|
||||||
|
* We send an interrupt signal to the threadgroup to
|
||||||
|
* unwedge any pending writes.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void run() {
|
public void run() {
|
||||||
|
/*
|
||||||
|
* NOTE:
|
||||||
|
* The write method of OutputStream calls the write method of
|
||||||
|
* one argument on each of the bytes to be written out.
|
||||||
|
* Subclasses are encouraged to override this method and provide
|
||||||
|
* a more efficient implementation.
|
||||||
|
*
|
||||||
|
* So, is this really a performance problem?
|
||||||
|
* Should we expand to several bytes?
|
||||||
|
* I don't believe there would be any gain, since read method
|
||||||
|
* has the same reccomendations. If anyone has a better way to
|
||||||
|
* do this, I'm interested in performance improvements.
|
||||||
|
*
|
||||||
|
* --Sponge
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
int b;
|
int b;
|
||||||
byte a[] = new byte[1];
|
byte a[] = new byte[1];
|
||||||
boolean spin = true;
|
boolean spin = true;
|
||||||
|
@ -77,7 +77,7 @@ public class TCPlistener implements Runnable {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Socket server = new Socket();
|
Socket server = new Socket();
|
||||||
listener.setSoTimeout(1000);
|
listener.setSoTimeout(50); // Half of the expected time from MUXlisten
|
||||||
info.releaseReadLock();
|
info.releaseReadLock();
|
||||||
database.releaseReadLock();
|
database.releaseReadLock();
|
||||||
while(spin) {
|
while(spin) {
|
||||||
|
@ -16,6 +16,7 @@ import net.i2p.data.DataFormatException;
|
|||||||
import net.i2p.data.DataHelper;
|
import net.i2p.data.DataHelper;
|
||||||
import net.i2p.data.Destination;
|
import net.i2p.data.Destination;
|
||||||
import net.i2p.data.Hash;
|
import net.i2p.data.Hash;
|
||||||
|
import net.i2p.data.Base32;
|
||||||
import net.i2p.util.EventDispatcher;
|
import net.i2p.util.EventDispatcher;
|
||||||
import net.i2p.util.I2PThread;
|
import net.i2p.util.I2PThread;
|
||||||
import net.i2p.util.Log;
|
import net.i2p.util.Log;
|
||||||
@ -36,26 +37,27 @@ import net.i2p.util.Log;
|
|||||||
* "custom options" section of i2ptunnel.
|
* "custom options" section of i2ptunnel.
|
||||||
* - ircserver.cloakKey unset: Cloak with a random value that is persistent for
|
* - ircserver.cloakKey unset: Cloak with a random value that is persistent for
|
||||||
* the life of this tunnel. This is the default.
|
* the life of this tunnel. This is the default.
|
||||||
* - ircserver.cloakKey=none: Don't cloak. Users may be correlated with their
|
|
||||||
* (probably) shared clients destination.
|
|
||||||
* Of course if the ircd does cloaking than this is ok.
|
|
||||||
* - ircserver.cloakKey=somepassphrase: Cloak with the hash of the passphrase. Use this to
|
* - ircserver.cloakKey=somepassphrase: Cloak with the hash of the passphrase. Use this to
|
||||||
* have consistent mangling across restarts, or to
|
* have consistent mangling across restarts, or to
|
||||||
* have multiple IRC servers cloak consistently to
|
* have multiple IRC servers cloak consistently to
|
||||||
* be able to track users even when they switch servers.
|
* be able to track users even when they switch servers.
|
||||||
* Note: don't quote or put spaces in the passphrase,
|
* Note: don't quote or put spaces in the passphrase,
|
||||||
* the i2ptunnel gui can't handle it.
|
* the i2ptunnel gui can't handle it.
|
||||||
|
* - ircserver.fakeHostname=%f.b32.i2p: Set the fake hostname sent by I2PTunnel,
|
||||||
|
* %f is the full B32 destination hash
|
||||||
|
* %c is the cloaked hash.
|
||||||
*
|
*
|
||||||
* There is no outbound filtering.
|
* There is no outbound filtering.
|
||||||
*
|
*
|
||||||
* @author zzz
|
* @author zzz
|
||||||
*/
|
*/
|
||||||
public class I2PTunnelIRCServer extends I2PTunnelServer implements Runnable {
|
public class I2PTunnelIRCServer extends I2PTunnelServer implements Runnable {
|
||||||
|
public static final String PROP_CLOAK="ircserver.cloakKey";
|
||||||
|
public static final String PROP_HOSTNAME="ircserver.fakeHostname";
|
||||||
|
public static final String PROP_HOSTNAME_DEFAULT="%f.b32.i2p";
|
||||||
|
|
||||||
private static final Log _log = new Log(I2PTunnelIRCServer.class);
|
private static final Log _log = new Log(I2PTunnelIRCServer.class);
|
||||||
private static final String PROP_CLOAK="ircserver.cloakKey";
|
|
||||||
private boolean _cloak;
|
|
||||||
private byte[] _cloakKey; // 32 bytes of stuff to scramble the dest with
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws IllegalArgumentException if the I2PTunnel does not contain
|
* @throws IllegalArgumentException if the I2PTunnel does not contain
|
||||||
@ -71,15 +73,14 @@ public class I2PTunnelIRCServer extends I2PTunnelServer implements Runnable {
|
|||||||
private void initCloak(I2PTunnel tunnel) {
|
private void initCloak(I2PTunnel tunnel) {
|
||||||
Properties opts = tunnel.getClientOptions();
|
Properties opts = tunnel.getClientOptions();
|
||||||
String passphrase = opts.getProperty(PROP_CLOAK);
|
String passphrase = opts.getProperty(PROP_CLOAK);
|
||||||
_cloak = passphrase == null || !"none".equals(passphrase);
|
if (passphrase == null) {
|
||||||
if (_cloak) {
|
this.cloakKey = new byte[Hash.HASH_LENGTH];
|
||||||
if (passphrase == null) {
|
tunnel.getContext().random().nextBytes(this.cloakKey);
|
||||||
_cloakKey = new byte[Hash.HASH_LENGTH];
|
} else {
|
||||||
tunnel.getContext().random().nextBytes(_cloakKey);
|
this.cloakKey = SHA256Generator.getInstance().calculateHash(passphrase.trim().getBytes()).getData();
|
||||||
} else {
|
|
||||||
_cloakKey = SHA256Generator.getInstance().calculateHash(passphrase.trim().getBytes()).getData();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.hostname = opts.getProperty(PROP_HOSTNAME, PROP_HOSTNAME_DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void blockingHandle(I2PSocket socket) {
|
protected void blockingHandle(I2PSocket socket) {
|
||||||
@ -122,16 +123,17 @@ public class I2PTunnelIRCServer extends I2PTunnelServer implements Runnable {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
String cloakDest(Destination d) {
|
String cloakDest(Destination d) {
|
||||||
Hash h;
|
String hf;
|
||||||
if (_cloak) {
|
String hc;
|
||||||
byte[] b = new byte[d.size() + _cloakKey.length];
|
|
||||||
System.arraycopy(b, 0, d.toByteArray(), 0, d.size());
|
byte[] b = new byte[d.size() + this.cloakKey.length];
|
||||||
System.arraycopy(b, d.size(), _cloakKey, 0, _cloakKey.length);
|
System.arraycopy(b, 0, d.toByteArray(), 0, d.size());
|
||||||
h = SHA256Generator.getInstance().calculateHash(b);
|
System.arraycopy(b, d.size(), this.cloakKey, 0, this.cloakKey.length);
|
||||||
} else {
|
hc = Base32.encode(SHA256Generator.getInstance().calculateHash(b).getData());
|
||||||
h = d.calculateHash();
|
|
||||||
}
|
hf = Base32.encode(d.calculateHash().getData());
|
||||||
return h.toBase64().substring(0, 8) + ".i2p";
|
|
||||||
|
return this.hostname.replace("%f", hf).replace("%c", hc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** keep reading until we see USER or SERVER */
|
/** keep reading until we see USER or SERVER */
|
||||||
@ -156,9 +158,10 @@ public class I2PTunnelIRCServer extends I2PTunnelServer implements Runnable {
|
|||||||
if(field[0].charAt(0)==':')
|
if(field[0].charAt(0)==':')
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
try { command = field[idx++]; }
|
try {
|
||||||
catch (IndexOutOfBoundsException ioobe) // wtf, server sent borked command?
|
command = field[idx++];
|
||||||
{
|
} catch (IndexOutOfBoundsException ioobe) {
|
||||||
|
// wtf, server sent borked command?
|
||||||
throw new IOException("Dropping defective message: index out of bounds while extracting command.");
|
throw new IOException("Dropping defective message: index out of bounds while extracting command.");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +172,8 @@ public class I2PTunnelIRCServer extends I2PTunnelServer implements Runnable {
|
|||||||
// =>
|
// =>
|
||||||
// USER zzz1 abcd1234.i2p localhost :zzz
|
// USER zzz1 abcd1234.i2p localhost :zzz
|
||||||
// this whole class is for these two lines...
|
// this whole class is for these two lines...
|
||||||
buf.append("USER ").append(field[idx]).append(' ').append(newHostname).append(".i2p ");
|
buf.append("USER ").append(field[idx]).append(' ').append(newHostname);
|
||||||
|
buf.append(' ');
|
||||||
buf.append(field[idx+2]).append(' ').append(field[idx+3]).append("\r\n");
|
buf.append(field[idx+2]).append(' ').append(field[idx+3]).append("\r\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -181,4 +185,7 @@ public class I2PTunnelIRCServer extends I2PTunnelServer implements Runnable {
|
|||||||
_log.debug("All done, sending: " + buf.toString());
|
_log.debug("All done, sending: " + buf.toString());
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private byte[] cloakKey; // 32 bytes of stuff to scramble the dest with
|
||||||
|
private String hostname;
|
||||||
}
|
}
|
||||||
|
@ -261,7 +261,7 @@ public class PrivateKeyFile {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuffer s = new StringBuffer(128);
|
StringBuffer s = new StringBuffer(128);
|
||||||
s.append("Dest: ");
|
s.append("Dest: ");
|
||||||
s.append(this.dest.toBase64());
|
s.append(this.dest != null ? this.dest.toBase64() : "null");
|
||||||
s.append("\nContains: ");
|
s.append("\nContains: ");
|
||||||
s.append(this.dest);
|
s.append(this.dest);
|
||||||
s.append("\nPrivate Key: ");
|
s.append("\nPrivate Key: ");
|
||||||
|
51
history.txt
51
history.txt
@ -1,3 +1,54 @@
|
|||||||
|
2009-03-16 zzz
|
||||||
|
* help.jsp: Add some
|
||||||
|
* I2PTunnel: Cleanup
|
||||||
|
* I2PTunnelHTTPClient: Fix NPE on delayed open
|
||||||
|
* I2PTunnelHTTPServer: Maybe catch an NPE
|
||||||
|
* SOCKS: Allow .onion addresses for onioncat testing
|
||||||
|
* Tunnel: Catch a rare AIOOB
|
||||||
|
|
||||||
|
2009-03-09 zzz
|
||||||
|
* Client:
|
||||||
|
- Clean up retry code
|
||||||
|
- Bring I2CP listen error to the summary bar
|
||||||
|
http://forum.i2p/viewtopic.php?t=3133
|
||||||
|
* I2PSnark: Remove the http from the add torrent box
|
||||||
|
* I2PTunnel:
|
||||||
|
- Add persistent key option for standard and IRC clients
|
||||||
|
- Add delay-open option for clients
|
||||||
|
- Get regenerate-dest-on-reconnect working
|
||||||
|
- Add default key file name
|
||||||
|
- Add link to addressbook
|
||||||
|
- I2PSink: Send protocol byte
|
||||||
|
* OCMOSJ:
|
||||||
|
- Change from 5% reply requests to at least
|
||||||
|
once per minute, in hopes of reducing IRC drops
|
||||||
|
- More clean up of the cache cleaning
|
||||||
|
* Routerconsole: Don't OOM configpeer.jsp on huge blocklists
|
||||||
|
|
||||||
|
2009-02-26 zzz
|
||||||
|
* I2CP Client: Add support for muxing
|
||||||
|
* I2PTunnel:
|
||||||
|
- Add new IRCServer tunnel type
|
||||||
|
- Add SOCKS 4/4a support
|
||||||
|
- Catch OOMs in HTTPServer
|
||||||
|
- Name the IRCClient filter threads
|
||||||
|
- Port Streamr to I2PTunnel
|
||||||
|
- The beginnings of SOCKS UDP support
|
||||||
|
* Naming: Add reverse lookup by hash
|
||||||
|
* OCMOSJ: Clean up the cache cleaning
|
||||||
|
* Router: Move addShutdownTask from Router to I2PAppContext
|
||||||
|
so that apps can register more easily
|
||||||
|
* Routerconsole:
|
||||||
|
- Thread hard shutdown and restart requests from the routerconsole,
|
||||||
|
and add a delay even if no tunnels, to allow time for a UI response
|
||||||
|
- Sort the summary bar destinations
|
||||||
|
- Move dest-to-hash converter to new helper class so we can
|
||||||
|
use it in i2ptunnel
|
||||||
|
|
||||||
|
2009-02-22 sponge
|
||||||
|
* BOB: Orphan tunnel issue fix, bump BOB version
|
||||||
|
* bump to Build 6
|
||||||
|
|
||||||
2009-02-16 zzz
|
2009-02-16 zzz
|
||||||
* Streaming lib: Plug timer leak, don't send keepalives
|
* Streaming lib: Plug timer leak, don't send keepalives
|
||||||
after close, don't disconnect hard after close
|
after close, don't disconnect hard after close
|
||||||
|
@ -17,7 +17,7 @@ import net.i2p.CoreVersion;
|
|||||||
public class RouterVersion {
|
public class RouterVersion {
|
||||||
public final static String ID = "$Revision: 1.548 $ $Date: 2008-06-07 23:00:00 $";
|
public final static String ID = "$Revision: 1.548 $ $Date: 2008-06-07 23:00:00 $";
|
||||||
public final static String VERSION = CoreVersion.VERSION;
|
public final static String VERSION = CoreVersion.VERSION;
|
||||||
public final static long BUILD = 5;
|
public final static long BUILD = 9;
|
||||||
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