Compare commits

...

9 Commits

Author SHA1 Message Date
jrandom
484b528d4f * 2004-12-21 0.4.2.5 released
2004-12-21  jrandom
    * Track a new stat for expired client leases (client.leaseSetExpired).
2004-12-21 18:23:03 +00:00
jrandom
758293dc02 2004-12-21 jrandom
* Cleaned up the postinstall/startup scripts a bit more to handle winME,
      and added windows info to the headless docs. (thanks ardvark!)
    * Fixed a harmless (yet NPE inspiring) race during the final shutdown of
      a stream (thanks frosk!)
    * Add a pair of new stats for monitoring tunnel participation -
      tunnel.participatingBytesProcessed (total # bytes transferred) and
      tunnel.participatingBytesProcessedActive (total # bytes transferred for
      tunnels whose byte count exceed the 10m average).  This should help
      further monitor congestion issues.
    * Made the NamingService factory property public (thanks susi!)
2004-12-21 16:32:49 +00:00
jrandom
6cb316b33e 2004-12-20 jrandom
* No longer do a blocking DNS lookup within the jobqueue (thanks mule!)
    * Set a 60s dns cache TTL, instead of 0s.  Most users who used to use
      dyndns/etc now just use IP autodetection, so the old "we need ttl=0"
      reasoning is gone.
2004-12-20 05:14:56 +00:00
jrandom
1d31831e7d added up.i2p 2004-12-20 02:40:45 +00:00
jrandom
ee32b07995 2004-12-19 jrandom
* Fix for a race on startup wrt the new stats (thanks susi!)
2004-12-19 18:55:09 +00:00
jrandom
81f04ca692 2004-12-19 jrandom
* Added three new stats - router.activePeers, router.fastPeers, and
      router.highCapacityPeers, updated every minute
2004-12-19 16:27:10 +00:00
jrandom
1756997608 2004-12-19 jrandom
* Added a new i2ptunnel type: 'httpserver', allowing you to specify what
      hostname should be sent to the webserver.  By default, new installs will
      have an httpserver pointing at their jetty instance with the spoofed
      name 'mysite.i2p' (editable on the /i2ptunnel/edit.jsp page).
2004-12-19 11:04:56 +00:00
scintilla
ec11ea4ca7 * Convert native jcpuid code from C++ to C. This should alleviate build
problems experienced by some users.
2004-12-19 06:25:27 +00:00
jrandom
a1ebf85e1b added dm.i2p 2004-12-18 06:31:22 +00:00
32 changed files with 533 additions and 123 deletions

View File

@@ -229,6 +229,8 @@ public class I2PTunnel implements Logging, EventDispatcher {
runClientOptions(args, l);
} else if ("server".equals(cmdname)) {
runServer(args, l);
} else if ("httpserver".equals(cmdname)) {
runHttpServer(args, l);
} else if ("textserver".equals(cmdname)) {
runTextServer(args, l);
} else if ("client".equals(cmdname)) {
@@ -281,6 +283,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
l.log("owndest yes|no");
l.log("ping <args>");
l.log("server <host> <port> <privkeyfile>");
l.log("httpserver <host> <port> <spoofedhost> <privkeyfile>");
l.log("textserver <host> <port> <privkey>");
l.log("genkeys <privkeyfile> [<pubkeyfile>]");
l.log("gentextkeys");
@@ -370,6 +373,65 @@ public class I2PTunnel implements Logging, EventDispatcher {
}
}
/**
* Run the HTTP server pointing at the host and port specified using the private i2p
* destination loaded from the specified file, replacing the HTTP headers
* so that the Host: specified is the one spoofed. <p />
*
* Sets the event "serverTaskId" = Integer(taskId) after the tunnel has been started (or -1 on error)
* Also sets the event "openServerResult" = "ok" or "error" (displaying "Ready!" on the logger after
* 'ok'). So, success = serverTaskId != -1 and openServerResult = ok.
*
* @param args {hostname, portNumber, spoofedHost, privKeyFilename}
* @param l logger to receive events and output
*/
public void runHttpServer(String args[], Logging l) {
if (args.length == 4) {
InetAddress serverHost = null;
int portNum = -1;
File privKeyFile = null;
try {
serverHost = InetAddress.getByName(args[0]);
} catch (UnknownHostException uhe) {
l.log("unknown host");
_log.error(getPrefix() + "Error resolving " + args[0], uhe);
notifyEvent("serverTaskId", new Integer(-1));
return;
}
try {
portNum = Integer.parseInt(args[1]);
} catch (NumberFormatException nfe) {
l.log("invalid port");
_log.error(getPrefix() + "Port specified is not valid: " + args[1], nfe);
notifyEvent("serverTaskId", new Integer(-1));
return;
}
String spoofedHost = args[2];
privKeyFile = new File(args[3]);
if (!privKeyFile.canRead()) {
l.log("private key file does not exist");
_log.error(getPrefix() + "Private key file does not exist or is not readable: " + args[3]);
notifyEvent("serverTaskId", new Integer(-1));
return;
}
I2PTunnelHTTPServer serv = new I2PTunnelHTTPServer(serverHost, portNum, privKeyFile, args[3], spoofedHost, l, (EventDispatcher) this, this);
serv.setReadTimeout(readTimeout);
serv.startRunning();
addtask(serv);
notifyEvent("serverTaskId", new Integer(serv.getId()));
return;
} else {
l.log("httpserver <host> <port> <spoofedhost> <privkeyfile>");
l.log(" creates an HTTP server that sends all incoming data\n"
+ " of its destination to host:port., filtering the HTTP\n"
+ " headers so it looks like the request is to the spoofed host.");
notifyEvent("serverTaskId", new Integer(-1));
}
}
/**
* Run the server pointing at the host and port specified using the private i2p
* destination loaded from the given base64 stream. <p />

View File

@@ -0,0 +1,162 @@
/* I2PTunnel is GPL'ed (with the exception mentioned in I2PTunnel.java)
* (c) 2003 - 2004 mihi
*/
package net.i2p.i2ptunnel;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.SocketException;
import java.util.Iterator;
import java.util.Properties;
import net.i2p.I2PAppContext;
import net.i2p.I2PException;
import net.i2p.client.streaming.I2PServerSocket;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.client.streaming.I2PSocketManager;
import net.i2p.data.DataHelper;
import net.i2p.util.EventDispatcher;
import net.i2p.util.I2PThread;
import net.i2p.util.Log;
/**
* Simple extension to the I2PTunnelServer that filters the HTTP
* headers sent from the client to the server, replacing the Host
* header with whatever this instance has been configured with.
*
*/
public class I2PTunnelHTTPServer extends I2PTunnelServer {
private final static Log _log = new Log(I2PTunnelHTTPServer.class);
/** what Host: should we seem to be to the webserver? */
private String _spoofHost;
public I2PTunnelHTTPServer(InetAddress host, int port, String privData, String spoofHost, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) {
super(host, port, privData, l, notifyThis, tunnel);
_spoofHost = spoofHost;
}
public I2PTunnelHTTPServer(InetAddress host, int port, File privkey, String privkeyname, String spoofHost, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) {
super(host, port, privkey, privkeyname, l, notifyThis, tunnel);
_spoofHost = spoofHost;
}
public I2PTunnelHTTPServer(InetAddress host, int port, InputStream privData, String privkeyname, String spoofHost, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) {
super(host, port, privData, privkeyname, l, notifyThis, tunnel);
_spoofHost = spoofHost;
}
public void run() {
try {
I2PServerSocket i2pss = sockMgr.getServerSocket();
while (true) {
I2PSocket i2ps = i2pss.accept();
if (i2ps == null) throw new I2PException("I2PServerSocket closed");
I2PThread t = new I2PThread(new Handler(i2ps));
t.start();
}
} catch (I2PException ex) {
_log.error("Error while waiting for I2PConnections", ex);
} catch (IOException ex) {
_log.error("Error while waiting for I2PConnections", ex);
}
}
/**
* Async handler to keep .accept() from blocking too long.
* todo: replace with a thread pool so we dont get overrun by threads if/when
* receiving a lot of connection requests concurrently.
*
*/
private class Handler implements Runnable {
private I2PSocket _handleSocket;
public Handler(I2PSocket socket) {
_handleSocket = socket;
}
public void run() {
long afterAccept = I2PAppContext.getGlobalContext().clock().now();
long afterSocket = -1;
//local is fast, so synchronously. Does not need that many
//threads.
try {
_handleSocket.setReadTimeout(readTimeout);
String modifiedHeader = getModifiedHeader();
if (_log.shouldLog(Log.DEBUG))
_log.debug("Modified header: [" + modifiedHeader + "]");
Socket s = new Socket(remoteHost, remotePort);
afterSocket = I2PAppContext.getGlobalContext().clock().now();
new I2PTunnelRunner(s, _handleSocket, slock, null, modifiedHeader.getBytes(), null);
} catch (SocketException ex) {
try {
_handleSocket.close();
} catch (IOException ioe) {
_log.error("Error while closing the received i2p con", ex);
}
} catch (IOException ex) {
_log.error("Error while waiting for I2PConnections", ex);
}
long afterHandle = I2PAppContext.getGlobalContext().clock().now();
long timeToHandle = afterHandle - afterAccept;
if (timeToHandle > 1000)
_log.warn("Took a while to handle the request [" + timeToHandle + ", socket create: "
+ (afterSocket-afterAccept) + "]");
}
private String getModifiedHeader() throws IOException {
InputStream in = _handleSocket.getInputStream();
StringBuffer command = new StringBuffer(128);
Properties headers = readHeaders(in, command);
headers.setProperty("Host", _spoofHost);
headers.setProperty("Connection", "close");
return formatHeaders(headers, command);
}
}
private String formatHeaders(Properties headers, StringBuffer command) {
StringBuffer buf = new StringBuffer(command.length() + headers.size() * 64);
buf.append(command.toString()).append('\n');
for (Iterator iter = headers.keySet().iterator(); iter.hasNext(); ) {
String name = (String)iter.next();
String val = headers.getProperty(name);
buf.append(name).append(": ").append(val).append('\n');
}
buf.append('\n');
return buf.toString();
}
private Properties readHeaders(InputStream in, StringBuffer command) throws IOException {
Properties headers = new Properties();
StringBuffer buf = new StringBuffer(128);
boolean ok = DataHelper.readLine(in, command);
if (!ok) throw new IOException("EOF reached while reading the HTTP command [" + command.toString() + "]");
if (_log.shouldLog(Log.DEBUG))
_log.debug("Read the http command [" + command.toString() + "]");
while (true) {
buf.setLength(0);
ok = DataHelper.readLine(in, buf);
if (!ok) throw new IOException("EOF reached before the end of the headers [" + buf.toString() + "]");
if ( (buf.length() <= 1) && ( (buf.charAt(0) == '\n') || (buf.charAt(0) == '\r') ) ) {
// end of headers reached
return headers;
} else {
int split = buf.indexOf(": ");
if (split <= 0) throw new IOException("Invalid HTTP header, missing colon [" + buf.toString() + "]");
String name = buf.substring(0, split);
String value = buf.substring(split+2); // ": "
headers.setProperty(name, value);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Read the header [" + name + "] = [" + value + "]");
}
}
}
}

View File

@@ -40,7 +40,8 @@ public class I2PTunnelRunner extends I2PThread implements I2PSocket.SocketErrorL
Object slock, finishLock = new Object();
boolean finished = false;
HashMap ostreams, sockets;
byte[] initialData;
byte[] initialI2PData;
byte[] initialSocketData;
/** when the last data was sent/received (or -1 if never) */
private long lastActivityOn;
/** when the runner started up */
@@ -53,15 +54,22 @@ public class I2PTunnelRunner extends I2PThread implements I2PSocket.SocketErrorL
private volatile long __forwarderId;
public I2PTunnelRunner(Socket s, I2PSocket i2ps, Object slock, byte[] initialData, List sockList) {
this(s, i2ps, slock, initialData, sockList, null);
public I2PTunnelRunner(Socket s, I2PSocket i2ps, Object slock, byte[] initialI2PData, List sockList) {
this(s, i2ps, slock, initialI2PData, null, sockList, null);
}
public I2PTunnelRunner(Socket s, I2PSocket i2ps, Object slock, byte[] initialData, List sockList, Runnable onTimeout) {
public I2PTunnelRunner(Socket s, I2PSocket i2ps, Object slock, byte[] initialI2PData, byte[] initialSocketData, List sockList) {
this(s, i2ps, slock, initialI2PData, initialSocketData, sockList, null);
}
public I2PTunnelRunner(Socket s, I2PSocket i2ps, Object slock, byte[] initialI2PData, List sockList, Runnable onTimeout) {
this(s, i2ps, slock, initialI2PData, null, sockList, onTimeout);
}
public I2PTunnelRunner(Socket s, I2PSocket i2ps, Object slock, byte[] initialI2PData, byte[] initialSocketData, List sockList, Runnable onTimeout) {
this.sockList = sockList;
this.s = s;
this.i2ps = i2ps;
this.slock = slock;
this.initialData = initialData;
this.initialI2PData = initialI2PData;
this.initialSocketData = initialSocketData;
this.onTimeout = onTimeout;
lastActivityOn = -1;
startedOn = Clock.getInstance().now();
@@ -111,15 +119,19 @@ public class I2PTunnelRunner extends I2PThread implements I2PSocket.SocketErrorL
i2ps.setSocketErrorListener(this);
InputStream i2pin = i2ps.getInputStream();
OutputStream i2pout = i2ps.getOutputStream(); //new BufferedOutputStream(i2ps.getOutputStream(), MAX_PACKET_SIZE);
if (initialData != null) {
if (initialI2PData != null) {
synchronized (slock) {
i2pout.write(initialData);
i2pout.write(initialI2PData);
//i2pout.flush();
}
}
if (initialSocketData != null) {
out.write(initialSocketData);
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("Initial data " + (initialData != null ? initialData.length : 0)
+ " written, starting forwarders");
_log.debug("Initial data " + (initialI2PData != null ? initialI2PData.length : 0)
+ " written to I2P, " + (initialSocketData != null ? initialSocketData.length : 0)
+ " written to the socket, starting forwarders");
Thread t1 = new StreamForwarder(in, i2pout, true);
Thread t2 = new StreamForwarder(i2pin, out, false);
synchronized (finishLock) {

View File

@@ -31,19 +31,20 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
private final static Log _log = new Log(I2PTunnelServer.class);
private I2PSocketManager sockMgr;
private I2PServerSocket i2pss;
protected I2PSocketManager sockMgr;
protected I2PServerSocket i2pss;
private Object lock = new Object(), slock = new Object();
private Object lock = new Object();
protected Object slock = new Object();
private InetAddress remoteHost;
private int remotePort;
protected InetAddress remoteHost;
protected int remotePort;
private Logging l;
private static final long DEFAULT_READ_TIMEOUT = -1; // 3*60*1000;
/** default timeout to 3 minutes - override if desired */
private long readTimeout = DEFAULT_READ_TIMEOUT;
protected long readTimeout = DEFAULT_READ_TIMEOUT;
public I2PTunnelServer(InetAddress host, int port, String privData, Logging l, EventDispatcher notifyThis, I2PTunnel tunnel) {
super(host + ":" + port + " <- " + privData, notifyThis, tunnel);

View File

@@ -57,7 +57,7 @@ public class TunnelController implements Logging {
setConfig(config, prefix);
_messages = new ArrayList(4);
_running = false;
if (createKey && ("server".equals(getType())) )
if (createKey && ("server".equals(getType()) || "httpserver".equals(getType())) )
createPrivateKey();
_starting = getStartOnLoad();
}
@@ -132,6 +132,8 @@ public class TunnelController implements Logging {
startClient();
} else if ("server".equals(type)) {
startServer();
} else if ("httpserver".equals(type)) {
startHttpServer();
} else {
if (_log.shouldLog(Log.ERROR))
_log.error("Cannot start tunnel - unknown type [" + type + "]");
@@ -206,6 +208,18 @@ public class TunnelController implements Logging {
_running = true;
}
private void startHttpServer() {
setI2CPOptions();
setSessionOptions();
String targetHost = getTargetHost();
String targetPort = getTargetPort();
String spoofedHost = getSpoofedHost();
String privKeyFile = getPrivKeyFile();
_tunnel.runHttpServer(new String[] { targetHost, targetPort, spoofedHost, privKeyFile }, this);
acquire();
_running = true;
}
private void setListenOn() {
String listenOn = getListenOnInterface();
if ( (listenOn != null) && (listenOn.length() > 0) ) {
@@ -297,6 +311,7 @@ public class TunnelController implements Logging {
public String getListenOnInterface() { return _config.getProperty("interface"); }
public String getTargetHost() { return _config.getProperty("targetHost"); }
public String getTargetPort() { return _config.getProperty("targetPort"); }
public String getSpoofedHost() { return _config.getProperty("spoofedHost"); }
public String getPrivKeyFile() { return _config.getProperty("privKeyFile"); }
public String getListenPort() { return _config.getProperty("listenPort"); }
public String getTargetDestination() { return _config.getProperty("targetDestination"); }
@@ -314,6 +329,8 @@ public class TunnelController implements Logging {
getClientSummary(buf);
else if ("server".equals(type))
getServerSummary(buf);
else if ("httpserver".equals(type))
getHttpServerSummary(buf);
else
buf.append("Unknown type ").append(type);
}
@@ -367,6 +384,18 @@ public class TunnelController implements Logging {
getOptionSummary(buf);
}
private void getHttpServerSummary(StringBuffer buf) {
String description = getDescription();
if ( (description != null) && (description.trim().length() > 0) )
buf.append("<i>").append(description).append("</i><br />\n");
buf.append("Server tunnel pointing at port ").append(getTargetPort());
buf.append(" on ").append(getTargetHost());
buf.append(" for the site ").append(getSpoofedHost());
buf.append("<br />\n");
buf.append("Private destination loaded from ").append(getPrivKeyFile()).append("<br />\n");
getOptionSummary(buf);
}
private void getOptionSummary(StringBuffer buf) {
String opts = getClientOptions();
if ( (opts != null) && (opts.length() > 0) )
@@ -378,7 +407,7 @@ public class TunnelController implements Logging {
Destination dest = session.getMyDestination();
if (dest != null) {
buf.append("Destination hash: ").append(dest.calculateHash().toBase64()).append("<br />\n");
if ("server".equals(getType())) {
if ( ("server".equals(getType())) || ("httpserver".equals(getType())) ) {
buf.append("Full destination: ");
buf.append("<input type=\"text\" size=\"10\" onclick=\"this.select();\" ");
buf.append("value=\"").append(dest.toBase64()).append("\" />\n");

View File

@@ -18,6 +18,7 @@ class WebEditPageFormGenerator {
"<option value=\"httpclient\">HTTP proxy</option>" +
"<option value=\"client\">Client tunnel</option>" +
"<option value=\"server\">Server tunnel</option>" +
"<option value=\"httpserver\">HTTP server tunnel</option>" +
"</select> <input type=\"submit\" value=\"GO\" />" +
"</form>\n";
@@ -42,6 +43,8 @@ class WebEditPageFormGenerator {
return getEditClientForm(controller, id);
else if ("server".equals(type))
return getEditServerForm(controller, id);
else if ("httpserver".equals(type))
return getEditHttpServerForm(controller, id);
else
return "WTF, unknown type [" + type + "]";
}
@@ -129,6 +132,48 @@ class WebEditPageFormGenerator {
return buf.toString();
}
private static String getEditHttpServerForm(TunnelController controller, String id) {
StringBuffer buf = new StringBuffer(1024);
addGeneral(buf, controller, id);
buf.append("<b>Type:</b> <i>HTTP server tunnel</i><input type=\"hidden\" name=\"type\" value=\"httpserver\" /><br />\n");
buf.append("<b>Target host:</b> <input type=\"text\" size=\"40\" name=\"targetHost\" ");
if ( (controller != null) && (controller.getTargetHost() != null) )
buf.append("value=\"").append(controller.getTargetHost()).append("\" ");
else
buf.append("value=\"127.0.0.1\" ");
buf.append(" /><br />\n");
buf.append("<b>Target port:</b> <input type=\"text\" size=\"4\" name=\"targetPort\" ");
if ( (controller != null) && (controller.getTargetPort() != null) )
buf.append("value=\"").append(controller.getTargetPort()).append("\" ");
else
buf.append("value=\"80\" ");
buf.append(" /><br />\n");
buf.append("<b>Website hostname:</b> <input type=\"text\" size=\"16\" name=\"spoofedHost\" ");
if ( (controller != null) && (controller.getSpoofedHost() != null) )
buf.append("value=\"").append(controller.getSpoofedHost()).append("\" ");
else
buf.append("value=\"mysite.i2p\" ");
buf.append(" /><br />\n");
buf.append("<b>Private key file:</b> <input type=\"text\" name=\"privKeyFile\" value=\"");
if ( (controller != null) && (controller.getPrivKeyFile() != null) ) {
buf.append(controller.getPrivKeyFile()).append("\" /><br />");
} else {
buf.append("myServer.privKey\" /><br />");
buf.append("<input type=\"hidden\" name=\"privKeyGenerate\" value=\"true\" />");
}
addOptions(buf, controller);
buf.append("<input type=\"submit\" name=\"action\" value=\"Save\">\n");
buf.append("<input type=\"submit\" name=\"action\" value=\"Remove\">\n");
buf.append(" <i>confirm removal:</i> <input type=\"checkbox\" name=\"removeConfirm\" value=\"true\" />\n");
buf.append("</form>\n");
return buf.toString();
}
/**
* Start off the form and add some common fields (name, num, description)
*

View File

@@ -38,6 +38,7 @@ public class WebEditPageHelper {
private String _targetDestination;
private String _targetHost;
private String _targetPort;
private String _spoofedHost;
private String _privKeyFile;
private boolean _startOnLoad;
private boolean _privKeyGenerate;
@@ -139,6 +140,10 @@ public class WebEditPageHelper {
public void setTargetPort(String port) {
_targetPort = (port != null ? port.trim() : null);
}
/** What host does this http server tunnel spoof */
public void setSpoofedHost(String host) {
_spoofedHost = (host != null ? host.trim() : null);
}
/** What filename is this server tunnel's private keys stored in */
public void setPrivKeyFile(String file) {
_privKeyFile = (file != null ? file.trim() : null);
@@ -320,6 +325,15 @@ public class WebEditPageHelper {
config.setProperty("targetPort", _targetPort);
if (_privKeyFile != null)
config.setProperty("privKeyFile", _privKeyFile);
} else if ("httpserver".equals(_type)) {
if (_targetHost != null)
config.setProperty("targetHost", _targetHost);
if (_targetPort != null)
config.setProperty("targetPort", _targetPort);
if (_privKeyFile != null)
config.setProperty("privKeyFile", _privKeyFile);
if (_spoofedHost != null)
config.setProperty("spoofedHost", _spoofedHost);
} else {
return null;
}

View File

@@ -25,6 +25,7 @@
<option value="httpclient">HTTP proxy</option>
<option value="client">Client tunnel</option>
<option value="server">Server tunnel</option>
<option value="httpserver">HTTP server tunnel</option>
</select> <input type="submit" value="GO" />
</form>

View File

@@ -17,17 +17,20 @@ class ConnectionDataReceiver implements MessageOutputStream.DataReceiver {
private I2PAppContext _context;
private Log _log;
private Connection _connection;
private MessageOutputStream.WriteStatus _dummyStatus;
private static final MessageOutputStream.WriteStatus _dummyStatus = new DummyStatus();
public ConnectionDataReceiver(I2PAppContext ctx, Connection con) {
_context = ctx;
_log = ctx.logManager().getLog(ConnectionDataReceiver.class);
_connection = con;
_dummyStatus = new DummyStatus();
}
public boolean writeInProcess() {
return _connection.getUnackedPacketsSent() > 0;
Connection con = _connection;
if (con != null)
return con.getUnackedPacketsSent() > 0;
else
return false;
}
/**
@@ -42,10 +45,12 @@ class ConnectionDataReceiver implements MessageOutputStream.DataReceiver {
* delivery.
*/
public MessageOutputStream.WriteStatus writeData(byte[] buf, int off, int size) {
Connection con = _connection;
if (con == null) return _dummyStatus;
boolean doSend = true;
if ( (size <= 0) && (_connection.getLastSendId() >= 0) ) {
if (_connection.getOutputStream().getClosed()) {
if (_connection.getCloseSentOn() < 0) {
if ( (size <= 0) && (con.getLastSendId() >= 0) ) {
if (con.getOutputStream().getClosed()) {
if (con.getCloseSentOn() < 0) {
doSend = true;
} else {
// closed, no new data, and we've already sent a close packet
@@ -57,16 +62,18 @@ class ConnectionDataReceiver implements MessageOutputStream.DataReceiver {
}
}
if (_connection.getUnackedPacketsReceived() > 0)
if (con.getUnackedPacketsReceived() > 0)
doSend = true;
if (_log.shouldLog(Log.INFO) && !doSend)
_log.info("writeData called: size="+size + " doSend=" + doSend
+ " unackedReceived: " + _connection.getUnackedPacketsReceived()
+ " con: " + _connection, new Exception("write called by"));
+ " unackedReceived: " + con.getUnackedPacketsReceived()
+ " con: " + con, new Exception("write called by"));
if (doSend) {
PacketLocal packet = send(buf, off, size);
if (packet == null) return _dummyStatus;
//dont wait for non-acks
if ( (packet.getSequenceNum() > 0) || (packet.isFlagSet(Packet.FLAG_SYNCHRONIZE)) )
return packet;
@@ -85,7 +92,7 @@ class ConnectionDataReceiver implements MessageOutputStream.DataReceiver {
* @param buf data to be sent - may be null
* @param off offset into the buffer to start writing from
* @param size how many bytes of the buffer to write (may be 0)
* @return the packet sent
* @return the packet sent, or null if the connection died
*/
public PacketLocal send(byte buf[], int off, int size) {
return send(buf, off, size, false);
@@ -99,10 +106,12 @@ class ConnectionDataReceiver implements MessageOutputStream.DataReceiver {
* @return the packet sent
*/
public PacketLocal send(byte buf[], int off, int size, boolean forceIncrement) {
Connection con = _connection;
if (con == null) return null;
long before = System.currentTimeMillis();
PacketLocal packet = buildPacket(buf, off, size, forceIncrement);
PacketLocal packet = buildPacket(con, buf, off, size, forceIncrement);
long built = System.currentTimeMillis();
_connection.sendPacket(packet);
con.sendPacket(packet);
long sent = System.currentTimeMillis();
if ( (built-before > 1000) && (_log.shouldLog(Log.WARN)) )
@@ -112,18 +121,18 @@ class ConnectionDataReceiver implements MessageOutputStream.DataReceiver {
return packet;
}
private boolean isAckOnly(int size) {
private boolean isAckOnly(Connection con, int size) {
boolean ackOnly = ( (size <= 0) && // no data
(_connection.getLastSendId() >= 0) && // not a SYN
( (!_connection.getOutputStream().getClosed()) || // not a CLOSE
(_connection.getOutputStream().getClosed() &&
_connection.getCloseSentOn() > 0) )); // or it is a dup CLOSE
(con.getLastSendId() >= 0) && // not a SYN
( (!con.getOutputStream().getClosed()) || // not a CLOSE
(con.getOutputStream().getClosed() &&
con.getCloseSentOn() > 0) )); // or it is a dup CLOSE
return ackOnly;
}
private PacketLocal buildPacket(byte buf[], int off, int size, boolean forceIncrement) {
boolean ackOnly = isAckOnly(size);
PacketLocal packet = new PacketLocal(_context, _connection.getRemotePeer(), _connection);
private PacketLocal buildPacket(Connection con, byte buf[], int off, int size, boolean forceIncrement) {
boolean ackOnly = isAckOnly(con, size);
PacketLocal packet = new PacketLocal(_context, con.getRemotePeer(), con);
byte data[] = new byte[size];
if (size > 0)
System.arraycopy(buf, off, data, 0, size);
@@ -131,36 +140,36 @@ class ConnectionDataReceiver implements MessageOutputStream.DataReceiver {
if (ackOnly && !forceIncrement)
packet.setSequenceNum(0);
else
packet.setSequenceNum(_connection.getNextOutboundPacketNum());
packet.setSendStreamId(_connection.getSendStreamId());
packet.setReceiveStreamId(_connection.getReceiveStreamId());
packet.setSequenceNum(con.getNextOutboundPacketNum());
packet.setSendStreamId(con.getSendStreamId());
packet.setReceiveStreamId(con.getReceiveStreamId());
_connection.getInputStream().updateAcks(packet);
packet.setOptionalDelay(_connection.getOptions().getChoke());
packet.setOptionalMaxSize(_connection.getOptions().getMaxMessageSize());
packet.setResendDelay(_connection.getOptions().getResendDelay());
con.getInputStream().updateAcks(packet);
packet.setOptionalDelay(con.getOptions().getChoke());
packet.setOptionalMaxSize(con.getOptions().getMaxMessageSize());
packet.setResendDelay(con.getOptions().getResendDelay());
if (_connection.getOptions().getProfile() == ConnectionOptions.PROFILE_INTERACTIVE)
if (con.getOptions().getProfile() == ConnectionOptions.PROFILE_INTERACTIVE)
packet.setFlag(Packet.FLAG_PROFILE_INTERACTIVE, true);
else
packet.setFlag(Packet.FLAG_PROFILE_INTERACTIVE, false);
packet.setFlag(Packet.FLAG_SIGNATURE_REQUESTED, _connection.getOptions().getRequireFullySigned());
packet.setFlag(Packet.FLAG_SIGNATURE_REQUESTED, con.getOptions().getRequireFullySigned());
if ( (!ackOnly) && (packet.getSequenceNum() <= 0) ) {
packet.setFlag(Packet.FLAG_SYNCHRONIZE);
packet.setOptionalFrom(_connection.getSession().getMyDestination());
packet.setOptionalFrom(con.getSession().getMyDestination());
}
// don't set the closed flag if this is a plain ACK and there are outstanding
// packets sent, otherwise the other side could receive the CLOSE prematurely,
// since this ACK could arrive before the unacked payload message.
if (_connection.getOutputStream().getClosed() &&
( (size > 0) || (_connection.getUnackedPacketsSent() <= 0) ) ) {
if (con.getOutputStream().getClosed() &&
( (size > 0) || (con.getUnackedPacketsSent() <= 0) ) ) {
packet.setFlag(Packet.FLAG_CLOSE);
_connection.setCloseSentOn(_context.clock().now());
con.setCloseSentOn(_context.clock().now());
if (_log.shouldLog(Log.DEBUG))
_log.debug("Closed is set for a new packet on " + _connection + ": " + packet);
_log.debug("Closed is set for a new packet on " + con + ": " + packet);
} else {
//if (_log.shouldLog(Log.DEBUG))
// _log.debug("Closed is not set for a new packet on " + _connection + ": " + packet);

View File

@@ -20,7 +20,7 @@ mkdir lib/freenet
mkdir lib/freenet/support
mkdir lib/freenet/support/CPUInformation
CPP="g++"
CC="gcc"
case `uname -sr` in
MINGW*)
@@ -43,7 +43,7 @@ esac
echo "Compiling C code..."
rm -f $LIBFILE
$CPP $LINKFLAGS $INCLUDES src/*.cpp -o $LIBFILE
$CC $LINKFLAGS $INCLUDES src/*.c -o $LIBFILE
strip $LIBFILE
echo Built $LIBFILE

View File

@@ -5,8 +5,8 @@ JNIEXPORT jobject JNICALL Java_freenet_support_CPUInformation_CPUID_doCPUID
(JNIEnv * env, jclass cls, jint iFunction)
{
int a,b,c,d;
jclass clsResult = env->FindClass ("freenet/support/CPUInformation/CPUID$CPUIDResult");
jmethodID constructor = env->GetMethodID(clsResult,"<init>","(IIII)V" );
jclass clsResult = (*env)->FindClass(env, "freenet/support/CPUInformation/CPUID$CPUIDResult");
jmethodID constructor = (*env)->GetMethodID(env, clsResult,"<init>","(IIII)V" );
#ifdef _MSC_VER
//Use MSVC assembler notation
_asm
@@ -30,6 +30,6 @@ JNIEXPORT jobject JNICALL Java_freenet_support_CPUInformation_CPUID_doCPUID
:"a"(iFunction)
);
#endif
return env->NewObject(clsResult,constructor,a,b,c,d);
return (*env)->NewObject(env, clsResult,constructor,a,b,c,d);
}

View File

@@ -22,7 +22,8 @@ public abstract class NamingService {
private final static Log _log = new Log(NamingService.class);
protected I2PAppContext _context;
private static final String PROP_IMPL = "i2p.naming.impl";
/** what classname should be used as the naming service impl? */
public static final String PROP_IMPL = "i2p.naming.impl";
private static final String DEFAULT_IMPL = "net.i2p.client.naming.HostsTxtNamingService";

View File

@@ -680,7 +680,19 @@ public class DataHelper {
*/
public static String readLine(InputStream in) throws IOException {
StringBuffer buf = new StringBuffer(128);
boolean ok = readLine(in, buf);
if (ok)
return buf.toString();
else
return null;
}
/**
* Read in a line, placing it into the buffer (excluding the newline).
*
* @return true if the line was read, false if eof was reached before a
* newline was found
*/
public static boolean readLine(InputStream in, StringBuffer buf) throws IOException {
int c = -1;
while ( (c = in.read()) != -1) {
if (c == '\n')
@@ -688,9 +700,9 @@ public class DataHelper {
buf.append((char)c);
}
if (c == -1)
return null;
return false;
else
return buf.toString();
return true;
}

View File

@@ -1,4 +1,44 @@
$Id: history.txt,v 1.110 2004/12/16 05:21:24 jrandom Exp $
$Id: history.txt,v 1.117 2004/12/21 11:32:50 jrandom Exp $
* 2004-12-21 0.4.2.5 released
2004-12-21 jrandom
* Track a new stat for expired client leases (client.leaseSetExpired).
2004-12-21 jrandom
* Cleaned up the postinstall/startup scripts a bit more to handle winME,
and added windows info to the headless docs. (thanks ardvark!)
* Fixed a harmless (yet NPE inspiring) race during the final shutdown of
a stream (thanks frosk!)
* Add a pair of new stats for monitoring tunnel participation -
tunnel.participatingBytesProcessed (total # bytes transferred) and
tunnel.participatingBytesProcessedActive (total # bytes transferred for
tunnels whose byte count exceed the 10m average). This should help
further monitor congestion issues.
* Made the NamingService factory property public (thanks susi!)
2004-12-20 jrandom
* No longer do a blocking DNS lookup within the jobqueue (thanks mule!)
* Set a 60s dns cache TTL, instead of 0s. Most users who used to use
dyndns/etc now just use IP autodetection, so the old "we need ttl=0"
reasoning is gone.
2004-12-19 jrandom
* Fix for a race on startup wrt the new stats (thanks susi!)
2004-12-19 jrandom
* Added three new stats - router.activePeers, router.fastPeers, and
router.highCapacityPeers, updated every minute
2004-12-19 jrandom
* Added a new i2ptunnel type: 'httpserver', allowing you to specify what
hostname should be sent to the webserver. By default, new installs will
have an httpserver pointing at their jetty instance with the spoofed
name 'mysite.i2p' (editable on the /i2ptunnel/edit.jsp page).
2004-12-19 scintilla
* Convert native jcpuid code from C++ to C. This should alleviate build
problems experienced by some users.
* 2004-12-18 0.4.2.4 released

View File

@@ -1,6 +1,8 @@
; TC's hosts.txt guaranteed freshness
; $Id: hosts.txt,v 1.96 2004/12/14 23:23:16 jrandom Exp $
; $Id: hosts.txt,v 1.98 2004/12/18 01:31:22 jrandom Exp $
; changelog:
; (1.121) added up.i2p
; (1.120) added dm.i2p
; (1.119) added piespy.i2p
; (1.118) added sciencebooks.i2p
; (1.117) added forum.fr.i2p, fedo.i2p, and pastebin.i2p
@@ -266,4 +268,6 @@ fedo.i2p=pklxM9~hpluoCoiPgzMBpTHXMpwEdCMMNEatVc4gnQDOXsKkW5FbUMQ9y0vj6EUs2vUZLkw
pastebin.i2p=mUDz9K6KmWe2zE4wj~YjqwD5f8pCjEbze-DuafzjtXOaj9SnRBrLNqgOTt063y9foZett484g9PFm~3ibqFZfUk3LsJi6YhZje-V~RZndBElRJ1cX~MBOG5wdHA2BYpBt7jX-N5J9ww7POtcPFDjyYlJLhRrY5FuRfxdsWJ4BOUHOwvbTq7IWvqHReayte6vKavpyvNcAotcFHAhOGpR6Ua3RncS~b6NA5k2CQIeS4mR6~iNCh0sx1gj4cWWWqXSa6pN19io82L2fcNEcxE-UETj4HkG5fTdBlB4I2cNAm1KnxQw9ntRf19p5EzYkOFYST5ra~RWmy0bWzJMBFlK9QcogVi97gmszuNPyfIpJIE1ssZ6BNHKMkPJ-fjxtSAseTBV-Fa51TIBwNyXC6VxMsixKIBX4Cg64oipoGpm~-7SdRgabHbB0vWwiV6RYEQ88oNcV2ycDqjyfQymT0T5S9b0aVd2Ey1ZWly-PR44~uC3mCctcMqfZVfNFs3NoY3ZAAAA
sciencebooks.i2p=Rrqf6EmeuqckygNrim-ZcZ97uEIL9Ykkr8cj1RSGbeih33~UUpjAp0x2fxrpbibXwuGufWMNoaMkZH8FxOxZr1hvBeV4Mvjrn05kKWyPpBB1x7rAcVCCoD~bl6CUU2k4NtFrO9~BCCZdoIvMxXYWRy4nj18RVaIlOS3qE6~F04pU7Fy0sj7xtd02wgeyKkJ6pXYGfETMr6phVusHSSQfCumDBpnqEt7EcXTIsPz58y9Zim4u1wp6xj~OvGWFIP8fKIxpH~zf6o0qYytXrf6SJbIEvwITKGIXZTM5KxQ0LbEydSgPn4q5PttQlKg~7hxuGG5RYqP2IMg-f9z4-1SfYTbz~EixEq8gv0R30c60tqsyAaw9o37R3k9inkT5WylYwBKM0pzfcAVjejcoPYnFF1iithGl0AYkP~~isxCErCNwLs39NyE688C5amDIpXl7AgB~IvbwZfONbd2cwMOB2RFzTShYZlwcILB7EzgMvEt2l8GBkstP3CzNrjQ2gAL0AAAA
piespy.i2p=jTCW8w04d~Sucb7OXFBZtq7tEOxeFBNm5T4uVZW3xNapThxk0Tie8OAIQMmz4lzDUaHoc97DN1s6k3rTprRrhbr7Idyls5I-r6jAQnrljqUveIMA-lbzXDYTgo8TqBR4~fpSL4RM5u4~sM4ZRKdwufnEjCSlYtTe8qmrofFx3cIuIKhfypsYcu-BEdrw7P~cRpmqJqBV~igulwfIxeABa8ygX~Uk~i68NELte55J70z~kijYGMAgUJVhtQxD~jZD5l3FrGkND9lVaam0lHseujNyy~ZB-ma5IKqJWKLEo19e224EVhIK4jcKYdnr7bE86mZiWg36GvWFhjJOkEvCJ3BWxaMjcDXyk-9vCY7MA403OCMGGHoKlzB2AKq1PEc1teMtoqMG~a42DTKevUbbiALtauxCe-BOxEtxpYTvvql-RVumrUh3hckh0wqAd1Gqr2uqRx4VaCF3X3duOxdoKV6Kgf~icfVIFq5HR7AhN63BGFhAeQLcudp3oA828a06AAAA
dm.i2p=ZPCnBTv~~EZTvbq4D4Lscn4AL~VMwbmKSLEF4Aq8bzynQm~kGnkSLhrDpNaJyAvO0F9wX-7bxyu3KLmpE~0KZt-6-J2spfBqkRTOd39j1YjJ1HHXivWiI8yl4uoHXZun6UW~QdwKQPzAMBnl2W4rXpQekGxwh7HlnQT22FyI-ELtzh8FE8JJ6DxfYsDKd49QnsePM3r2dB6hWb0lPEf-DwSD8JtsRmXMmDfa16-yWt5Wa0K-xrWbKh~oQ8K1aXhHoUxsfJ~LQnklt~QGld9Cbk7q1hJKXFUSqCoLaADZEmvzuNlzE53ChK~W6IanEZ4WeNT7dMJaMtta2Ot5Ym9dXGygFp2XE5zGsOpq38XGNHHI3iKNCexIh0eTL3jwwkUQXl7UPWxrykRff8uRSgBq6s669lOzUbZfdmAbkTG6NvwU0RboQQ-OYs7APDn5ovXHI3zl0bRljZWBxNVswz34fQ~jkA5aHUcgV~sNgwjjz5um7K9V-QEVUBi68AhJbmvRAAAA
up.i2p=D7MtDuWfl9XOkSDC~hCH7QBrnDhg2KdxFq2dyq0e2jJypmXPFSw0Hl6HOMdI3myFTtweKZObHaPzy4c3-hk9ZwBsqzT8XquTVoa~z7OAtoj0QQDdIGXaHpDvVWkj9wAilpJfypqThVho08F0cq9~yChBh2s02JoQersRQ4l9oMQaOSVS85wGudFYSeWUhRPJyb0FN4ic7KPRvFlOBnESCtQUxMa0HV28UDyc9kGUN8AmgaV2qi-LcdrxHsYwzbYKZVa6Tg3mHEqksuzH5AK~9KYHlzLz2QRDesL0jkf7WdVRlKSiqkrYQVSG7MAqHfHNhQbb9oIpqDARyAqUaPJyEVQRAphJ9qv-K54QW1T2Js5tF5XVJoZcU04d9aHyxaUKqWJwIMrRlfeKVGAPlE7pcUjQrTKe6-22-46CzKpHsG8j4kwSyvrwlpGdsbN7-q9tq3KH4b9hJiv5nsQ4lSBQ9Um6YCEmUdwffnfbbfVGPCmj9XcMSrnHfvCD2rf4-V9sAAAA

View File

@@ -1,4 +1,4 @@
$Id: install-headless.txt,v 1.2 2004/09/02 01:54:37 jrandom Exp $
$Id: install-headless.txt,v 1.3 2004/09/29 14:38:15 jrandom Exp $
Headless I2P installation instructions
1) tar xjf i2p.tar.bz2 (you've already done this)
@@ -10,7 +10,8 @@ If you're having trouble, swing by http://forum.i2p.net/, check the
website at http://www.i2p.net/, or get on irc://irc.freenode.net/#i2p
To run I2P explicitly:
sh i2prouter start
(*nix): sh i2prouter start
(win*): I2Psvc.exe -c wrapper.config
To stop the router (gracefully):
lynx http://localhost:7657/configservice.jsp ("Shutdown gracefully")
@@ -26,4 +27,4 @@ Supported JVMs:
Linux: Latest available from http://java.sun.com/ (1.3+ supported)
FreeBSD: /usr/ports/java/linux-sun-jdk1.4
various: http://www.kaffe.org/ using CVS HEAD as of Sept 1, 2004
(or any subsequent releases)
(or any subsequent releases)

View File

@@ -4,7 +4,7 @@
<info>
<appname>i2p</appname>
<appversion>0.4.2.4</appversion>
<appversion>0.4.2.5</appversion>
<authors>
<author name="I2P" email="support@i2p.net"/>
</authors>

View File

@@ -1,39 +1,14 @@
@echo off
setlocal
set INSTALL_PATH="%1"
rem
rem Java Service Wrapper general startup script
rem
rem
rem Resolve the real path of the Wrapper.exe
rem For non NT systems, the _REALPATH and _WRAPPER_CONF values
rem can be hard-coded below and the following test removed.
rem
if "%OS%"=="Windows_NT" goto nt
echo This script only works with NT-based versions of Windows.
goto :eof
set _WRAPPER_EXE=%INSTALL_PATH%I2Psvc.exe
set _WRAPPER_CONF="%INSTALL_PATH%wrapper.config"
:nt
rem
rem Find the application home.
rem
rem %~dp0 is location of current script under NT
set _REALPATH=%~dp0
set _WRAPPER_EXE=%_REALPATH%I2Psvc.exe
rem
rem Find the wrapper.conf
rem
:conf
set _WRAPPER_CONF="%~f1"
if not %_WRAPPER_CONF%=="" goto startup
set _WRAPPER_CONF="%_REALPATH%wrapper.config"
rem
rem Start the Wrapper
rem
:startup
"%_WRAPPER_EXE%" -c %_WRAPPER_CONF%
if not errorlevel 1 goto :eof
pause

View File

@@ -42,9 +42,10 @@ tunnel.2.startOnLoad=false
# local eepserver
tunnel.3.name=eepsite
tunnel.3.description=My eepsite
tunnel.3.type=server
tunnel.3.type=httpserver
tunnel.3.targetHost=127.0.0.1
tunnel.3.targetPort=7658
tunnel.3.spoofedHost=mysite.i2p
tunnel.3.privKeyFile=eepsite/eepPriv.dat
tunnel.3.i2cpHost=127.0.0.1
tunnel.3.i2cpPort=7654

View File

@@ -33,7 +33,7 @@ del /f /q "%INSTALL_PATH%postinstall.sh"
:: del /f /q "%INSTALL_PATH%uninstall_i2p_service_unix"
del /f /q "%INSTALL_PATH%icons\*.xpm"
rmdir /q /s "%INSTALL_PATH%lib\wrapper"
start /b /i /d"%INSTALL_PATH%" i2prouter.bat
start /b /i /d"%INSTALL_PATH%" i2prouter.bat %INSTALL_PATH%
) else (
@@ -47,6 +47,6 @@ del "%INSTALL_PATH%postinstall.sh"
del "%INSTALL_PATH%uninstall_i2p_service_winnt.bat"
del "%INSTALL_PATH%icons\*.xpm"
deltree /Y "%INSTALL_PATH%lib\wrapper"
start /M "%INSTALL_PATH%i2prouter.bat"
start /M "%INSTALL_PATH%i2prouter.bat" %INSTALL_PATH%
)

View File

@@ -75,9 +75,13 @@ public class Router {
public final static String PROP_SHUTDOWN_IN_PROGRESS = "__shutdownInProgress";
static {
// grumble about sun's java caching DNS entries *forever*
System.setProperty("sun.net.inetaddr.ttl", "0");
System.setProperty("networkaddress.cache.ttl", "0");
// grumble about sun's java caching DNS entries *forever* by default
// so lets just keep 'em for a minute
System.setProperty("sun.net.inetaddr.ttl", "60");
System.setProperty("networkaddress.cache.ttl", "60");
// until we handle restricted routes and/or all peers support v6, try v4 first
System.setProperty("java.net.preferIPv4Stack", "true");
System.setProperty("http.agent", "I2P");
// (no need for keepalive)
System.setProperty("http.keepAlive", "false");
System.setProperty("user.timezone", "GMT");
@@ -272,6 +276,9 @@ public class Router {
super(Router.this._context);
Router.this._context.statManager().createRateStat("bw.receiveBps", "How fast we receive data", "Bandwidth", new long[] { 60*1000, 5*60*1000, 60*60*1000 });
Router.this._context.statManager().createRateStat("bw.sendBps", "How fast we send data", "Bandwidth", new long[] { 60*1000, 5*60*1000, 60*60*1000 });
Router.this._context.statManager().createRateStat("router.activePeers", "How many peers we are actively talking with", "Throttle", new long[] { 5*60*1000, 60*60*1000 });
Router.this._context.statManager().createRateStat("router.highCapacityPeers", "How many high capacity peers we know", "Throttle", new long[] { 5*60*1000, 60*60*1000 });
Router.this._context.statManager().createRateStat("router.fastPeers", "How many fast peers we know", "Throttle", new long[] { 5*60*1000, 60*60*1000 });
}
public String getName() { return "Coalesce stats"; }
public void runJob() {
@@ -296,6 +303,15 @@ public class Router {
Router.this._context.statManager().addRateData("bw.sendBps", (long)bps, 60*1000);
}
}
int active = Router.this._context.commSystem().countActivePeers();
Router.this._context.statManager().addRateData("router.activePeers", active, 60*1000);
int fast = Router.this._context.profileOrganizer().countFastPeers();
Router.this._context.statManager().addRateData("router.fastPeers", fast, 60*1000);
int highCap = Router.this._context.profileOrganizer().countHighCapacityPeers();
Router.this._context.statManager().addRateData("router.highCapacityPeers", highCap, 60*1000);
requeue(60*1000);
}

View File

@@ -110,22 +110,7 @@ class RouterThrottleImpl implements RouterThrottle {
return false;
}
// ok, we're not hosed, but can we handle the bandwidth requirements
// of another tunnel?
rs = _context.statManager().getRate("tunnel.participatingMessagesProcessed");
r = null;
if (rs != null)
r = rs.getRate(10*60*1000);
double msgsPerTunnel = (r != null ? r.getAverageValue() : 0);
r = null;
rs = _context.statManager().getRate("tunnel.relayMessageSize");
if (rs != null)
r = rs.getRate(10*60*1000);
double bytesPerMsg = (r != null ? r.getAverageValue() : 0);
double bytesPerTunnel = msgsPerTunnel * bytesPerMsg;
int numTunnels = _context.tunnelManager().getParticipatingCount();
double bytesAllocated = (numTunnels + 1) * bytesPerTunnel;
if (_context.getProperty(Router.PROP_SHUTDOWN_IN_PROGRESS) != null) {
if (_log.shouldLog(Log.WARN))
@@ -209,6 +194,14 @@ class RouterThrottleImpl implements RouterThrottle {
// no default, ignore it
}
}
// ok, we're not hosed, but can we handle the bandwidth requirements
// of another tunnel?
rs = _context.statManager().getRate("tunnel.participatingBytesProcessed");
r = null;
if (rs != null)
r = rs.getRate(10*60*1000);
double bytesAllocated = r.getCurrentTotalValue();
if (!allowTunnel(bytesAllocated, numTunnels)) {
_context.statManager().addRateData("router.throttleTunnelBandwidthExceeded", (long)bytesAllocated, 0);

View File

@@ -15,8 +15,8 @@ import net.i2p.CoreVersion;
*
*/
public class RouterVersion {
public final static String ID = "$Revision: 1.115 $ $Date: 2004/12/16 05:21:23 $";
public final static String VERSION = "0.4.2.4";
public final static String ID = "$Revision: 1.122 $ $Date: 2004/12/21 11:32:50 $";
public final static String VERSION = "0.4.2.5";
public final static long BUILD = 0;
public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION);

View File

@@ -115,6 +115,8 @@ public class StatisticsManager implements Service {
//includeRate("jobQueue.droppedJobs", stats, new long[] { 60*60*1000, 24*60*60*1000 });
//includeRate("inNetPool.dropped", stats, new long[] { 60*60*1000, 24*60*60*1000 });
includeRate("tunnel.participatingTunnels", stats, new long[] { 5*60*1000, 60*60*1000 });
includeRate("tunnel.participatingBytesProcessed", stats, new long[] { 10*60*1000 });
includeRate("tunnel.participatingBytesProcessedActive", stats, new long[] { 10*60*1000 });
includeRate("tunnel.testSuccessTime", stats, new long[] { 60*60*1000l, 24*60*60*1000l });
//includeRate("tunnel.outboundMessagesProcessed", stats, new long[] { 10*60*1000, 60*60*1000 });
//includeRate("tunnel.inboundMessagesProcessed", stats, new long[] { 10*60*1000, 60*60*1000 });

View File

@@ -56,6 +56,7 @@ public class TunnelInfo extends DataStructureImpl {
private boolean _wasEverReady;
private int _messagesProcessed;
private int _tunnelFailures;
private long _bytesProcessed;
public TunnelInfo(I2PAppContext context) {
_context = context;
@@ -79,6 +80,7 @@ public class TunnelInfo extends DataStructureImpl {
_lastTested = -1;
_messagesProcessed = 0;
_tunnelFailures = 0;
_bytesProcessed = 0;
}
public TunnelId getTunnelId() { return _id; }
@@ -182,7 +184,12 @@ public class TunnelInfo extends DataStructureImpl {
return _messagesProcessed;
}
/** we have just processed a message for this tunnel */
public void messageProcessed() { _messagesProcessed++; }
public void messageProcessed(int size) {
_messagesProcessed++;
_bytesProcessed += size;
}
/** how many bytes have been pumped through this tunnel in its lifetime? */
public long getBytesProcessed() { return _bytesProcessed; }
/**
* the tunnel was (potentially) unable to pass a message through.

View File

@@ -240,7 +240,7 @@ public class HandleTunnelMessageJob extends JobImpl {
if (info == null)
return;
info.messageProcessed();
info.messageProcessed(_message.getMessageSize());
//if ( (_message.getVerificationStructure() == null) && (info.getSigningKey() != null) ) {
if (_message.getVerificationStructure() == null) {

View File

@@ -121,7 +121,7 @@ public class SendTunnelMessageJob extends JobImpl {
}
}
info.messageProcessed();
info.messageProcessed(_message.getMessageSize());
if (isEndpoint(info)) {
if (_log.shouldLog(Log.INFO))

View File

@@ -51,7 +51,7 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
_manager.restart();
}
public int countActivePeers() { return _manager.countActivePeers(); }
public int countActivePeers() { return (_manager == null ? 0 : _manager.countActivePeers()); }
public List getBids(OutNetMessage msg) {
return _manager.getBids(msg);

View File

@@ -170,4 +170,12 @@ public class TCPAddress {
}
return false;
}
public boolean equals(RouterAddress addr) {
if (addr == null) return false;
Properties opts = addr.getOptions();
if (opts == null) return false;
return ( (_host.equals(opts.getProperty(PROP_HOST))) &&
(Integer.toString(_port).equals(opts.getProperty(PROP_PORT))) );
}
}

View File

@@ -132,8 +132,7 @@ public class TCPTransport extends TransportImpl {
if (addr == null)
return null;
TCPAddress tcpAddr = new TCPAddress(addr);
if ( (_myAddress != null) && (tcpAddr.equals(_myAddress)) )
if ( (_myAddress != null) && (_myAddress.equals(addr)) )
return null; // dont talk to yourself
TransportBid bid = new TransportBid();

View File

@@ -51,6 +51,8 @@ class ClientLeaseSetManagerJob extends JobImpl {
_pool = pool;
_currentLeaseSet = null;
_lastCreated = -1;
context.statManager().createRateStat("client.leaseSetExpired", "How long ago did our leaseSet expire?", "ClientMessages", new long[] { 60*60*1000l, 24*60*60*1000l });
}
public void forceRequestLease() {
@@ -106,6 +108,13 @@ class ClientLeaseSetManagerJob extends JobImpl {
_log.warn("Insufficient safe inbound tunnels exist for the client (" + available
+ " available, " + _pool.getClientSettings().getNumInboundTunnels()
+ " required) - no leaseSet requested");
if (_currentLeaseSet != null) {
long howOld = getContext().clock().now() - _currentLeaseSet.getEarliestLeaseDate();
if (howOld > 0) {
// expired
getContext().statManager().addRateData("client.leaseSetExpired", howOld, 0);
}
}
}
requeue(RECHECK_DELAY);
}

View File

@@ -68,6 +68,8 @@ class TunnelPool {
_context.statManager().createRateStat("tunnel.outboundMessagesProcessed", "How many messages does an inbound tunnel process in its lifetime?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
_context.statManager().createRateStat("tunnel.participatingMessagesProcessed", "How many messages does an inbound tunnel process in its lifetime?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
_context.statManager().createRateStat("tunnel.participatingMessagesProcessedActive", "How many messages beyond the average were processed in a more-than-average tunnel's lifetime?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
_context.statManager().createRateStat("tunnel.participatingBytesProcessed", "How many bytes does an inbound tunnel process in its lifetime?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
_context.statManager().createRateStat("tunnel.participatingBytesProcessedActive", "How many bytes beyond the average were processed in a more-than-average tunnel's lifetime?", "Tunnels", new long[] { 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
_isLive = true;
_persistenceHelper = new TunnelPoolPersistenceHelper(_context);
@@ -662,6 +664,11 @@ class TunnelPool {
numMsgs-lastAvg,
info.getSettings().getExpiration() -
info.getSettings().getCreated());
long numBytes = info.getBytesProcessed();
lastAvg = (long)_context.statManager().getRate("tunnel.participatingBytesProcessed").getRate(10*60*1000l).getAverageValue();
_context.statManager().addRateData("tunnel.participatingBytesProcessed", numBytes, numMsgs);
if (numBytes > lastAvg)
_context.statManager().addRateData("tunnel.participatingBytesProcessedActive", numBytes-lastAvg, numMsgs);
break;
case TunnelId.TYPE_UNSPECIFIED:
default: