Compare commits

..

40 Commits

Author SHA1 Message Date
jrandom
d70c5df5a0 0.3.1.3 (not backwards compatible, yadda yadda yadda) 2004-05-20 11:32:32 +00:00
jrandom
b2799d198c add (commented out) router.shutdownPassword 2004-05-20 11:27:49 +00:00
jrandom
f2fa2038b1 * made dbStore use a pessimistic algorithm - requiring confirmation of a store, rather than optimistically considering all store messages successful (NOT BACKWARDS COMPATIBLE)
* when allocating tunnels for a client, make sure it has a good amount of time left in it (using default values, this means at least 7.5 minutes)
* allow overriding the profile organizer's thresholds so as to enforce a minimum number of fast and reliable peers, allowing a base level of tunnel diversification.  this is done through the "profileOrganizer.minFastPeers" router.config / context property (default minimum = 4 fast and reliable peers)
* don't be so harsh with the isFailing calculator regarding db lookup responses, since we've decreased the timeout.  however, include "participated in a failed tunnel" as part of the criteria
* more logging than god
* for dropped messages, if it is a DeliveryStatusMessage its not an error, its just lag / congestion (keep the average delay as the new stat "inNetPool.droppedDeliveryStatusDelay")
2004-05-20 11:06:25 +00:00
jrandom
bfd59e64ea refactored the cleanup job
logging
2004-05-20 10:53:31 +00:00
jrandom
60e05e270a cleaned up slice processing
reduced max queued messages per connection to 10 (additional ones are immediately marked as failed)
update the I2P_FLAG byte to '*' making this NOT BACKWARDS COMPATIBLE
formatting
2004-05-20 10:51:22 +00:00
jrandom
242b9a6af9 fix the reread short circuiting algorithm 2004-05-20 10:44:31 +00:00
jrandom
e7e8ad9bdc add the socketErrorListener interface (sorry duck) 2004-05-19 22:30:52 +00:00
jrandom
0e5d164a8a support shutting down the router from the web console:
specify a "router.shutdownPassword" value in the router.config (or in the environment [ala -D]),
  then specify that password on the shutdown form in the web console and hit submit.  after 30 seconds, it'll kill the router (and unless you're running the sim, it'll kill the JVM too, including clientApp.* started tunnels / etc)
if we had some sort of ACL for accessing the web console, we could avoid the password field altogether, but we dont, so we cant.
2004-05-19 22:00:32 +00:00
jrandom
7293a8d3c0 more logging than your mom 2004-05-19 15:24:25 +00:00
jrandom
097a4647a8 handle i2ptunnel server connection .accept()s asynchronously so we don't refuse lots of requests, causing intermittent "failures"
use the new async error listening interface of the ministreaming lib
truckloads of logging
2004-05-19 15:20:55 +00:00
jrandom
0942a7f3ff truckloads of logging
new async interface for error notification (e.g. you can get notified of an error prior to it throwing the IOException).
This async is useful since the IOException can be delayed for up to a minute while waiting for the close packet to be delivered.
The alternative is to fire off a new thread to do the closing, and we may want to go there later, but i'm not sure.
2004-05-19 15:14:30 +00:00
brianr
2df4370477 Some changes to make the SAM module never block if called on a socket
which select() says is safe to read/write or called in any case on a socket
which is O_NONBLOCK

Significant work is still required.
2004-05-19 01:26:02 +00:00
jrandom
7243963106 removed the insane explicit GC 2004-05-18 18:39:43 +00:00
jrandom
9f17654052 tuned to avoid expensive biginteger operation (well, not "expensive", but a lot more expensive than a few shifts)
when we need to debug, essentially assert the validity of the new tuned op, losing the performance benefit by duplicating the effort (to verify)
2004-05-18 18:33:37 +00:00
jrandom
1a65d7061d added morph.i2p 2004-05-17 05:46:06 +00:00
shendaras
292363eb65 imports (sorry, includes alphabetizing, wee)
(shendaras)
2004-05-17 03:38:53 +00:00
jrandom
07e79ce61a * do a db store after a successful db search (healing the netDb)
* timeout each peer in a db search after 10 seconds, not 30
* logging
2004-05-17 00:59:29 +00:00
brianr
1cf7dac82b test 2004-05-16 21:44:23 +00:00
brianr
6003b2902f Preliminary checkin of (mostly useless) Net::SAM perl module.
Net::SAM::StreamSession is currently unimplemented.
Net::Sam::[Datagram|Raw]Session block when they shouldn't and are buggy.
2004-05-16 21:35:46 +00:00
jrandom
ff0023a889 big ol' memory, cpu usage, and shutdown handling update. main changes include:
* rather than have all jobs created hooked into the clock for offset updates, have the jobQueue stay hooked up and update any active jobs accordingly (killing a memory leak of a JobTiming objects - one per job)
* dont go totally insane during shutdown and log like mad (though the clientApp things still log like mad, since they don't know the router is going down)
* adjust memory buffer sizes based on real world values so we don't have to expand/contract a lot
* dont display things that are completely useless (who cares what the first 32 bytes of a public key are?)
* reduce temporary object creation
* use more efficient collections at times
* on shutdown, log some state information (ready/timed jobs, pending messages, etc)
* explicit GC every 10 jobs.  yeah, not efficient, but just for now we'll keep 'er in there
* only reread the router config file if it changes (duh)
2004-05-16 04:54:50 +00:00
jrandom
8c6bf5a1cc added nickster.i2p 2004-05-16 04:42:17 +00:00
jrandom
61c97ab940 0.3.1.2 (backwards compatible, etc) 2004-05-13 23:49:08 +00:00
jrandom
b0a1b3b5ca added some harvest options
dont use javaw, since its a bitch to kill multiple jvms (yeah, this leaves a dos box.  we'll deal until we've got the shutdown admin control)
2004-05-13 23:32:57 +00:00
jrandom
4c7af01edc allow dynamic update to the reliability threshold factor (e.g. rather than the top 2/3rds being considered "reliable", allow that to be the top 1/3, or 1/2, etc)
the router.config var "profileOrganizer.reliabilityThresholdFactor=0.75" (or environment property -DprofileOrganizer.reliabilityThresholdFactor=0.5) etc
2004-05-13 23:24:09 +00:00
jrandom
0d431213cd include the previous period in the measurements (since they're discrete, not rolling)
also include the other elements as necessary by default
2004-05-13 07:14:54 +00:00
jrandom
ad9dd9a2e2 Lots of updates. I'm not calling this 0.3.1.2, still need to
"burn it it" some more, but its looking good.
* test all tunnels we manage every period or two. later we'll want to include some randomization to help fight traffic analysis, but that falls into the i2p 3.0 tunnel chaff / mixing / etc)
* test inbound tunnels correctly (use an outbound tunnel, not direct)
* only give the tunnels 30 seconds to succeed
* mark the tunnel as tested for both the inbound and outbound side and adjust the profiles for all participants accordingly
* keep track of the 'last test time' on a tunnel
* new tunnel test response time profile stat, as well as overall router stat (published in the netDb as "tunnel.testSuccessTime")
* rewrite of the speed calculator - the value it generates now is essentially "how many round trip messages can this router pass in a minute".
  it also allows a few runtime configurable options:
  = speedCalculator.eventThreshold:
    we use the smallest measurement period that has at least this many events in it (10m, 60m, 24h, lifetime)
  = speedCalculator.useInstantaneousRates:
    when we use the estimated round trip time, do we use instantaneous or period averages?
  = speedCalculator.useTunnelTestOnly:
    do we only use the tunnel test time (no db response or tunnel create time, or even estimated round trip times)?
* fix the reliability calculator to use the 10 minute tunnel create successes, not the (almost always 0) 1 minute rate.
* persist the tunnel create response time and send success time correctly (duh)
* add a new main() to PeerProfile - PeerProfile [filename]* will calculate the values of the peer profiles specified.  useful for tweaking the calculator, and/or the configurable options.  ala:
     java -DspeedCalculator.useInstantaneousRates peerProfiles/profile-*.dat
2004-05-13 04:32:26 +00:00
jrandom
c7895ed905 oh, you mean we're supposed to be at least a /little/ resiliant? 2004-05-13 03:54:33 +00:00
jrandom
57d7979d51 removed obsolete code
minor reorganization to help track down whats intermittently b0rking my kaffe instance
logging
2004-05-12 07:55:25 +00:00
jrandom
61f6871cd1 logging and a catastrophic try/catch (no situations have called for this yet, but its worth testing for) 2004-05-12 07:47:22 +00:00
jrandom
406048f7b9 ugly tests to see if the minimal RAW side of SAM works (it does, w00t) 2004-05-11 03:00:53 +00:00
jrandom
6dd5b0fe45 basic datagram tests (that work now :) 2004-05-11 02:44:16 +00:00
jrandom
fd4bc5e3cf keystream fixes 2004-05-11 02:43:52 +00:00
jrandom
3bab2d8957 only append the client's config properties to the SESSION commands (since some of the rest get confused with unknown tags...) 2004-05-11 02:07:27 +00:00
jrandom
af2f5cd2e1 kaffe shits a brick if you want the socket's address after .close() (grumble) 2004-05-11 01:55:22 +00:00
jrandom
d4bb32da82 fix per http://twiki.ntp.org/bin/view/Support/JavaSntpClientDev (thanks duck!)
this may have caused some clock skew problems on the deployed 0.3.1.1, so we'll get this deployed asap
2004-05-11 01:45:18 +00:00
jrandom
08aca6ca61 while (true) { m00; } 2004-05-09 07:23:43 +00:00
jrandom
697b3c6772 SAM .net lib work in progress - dm and firerabbit 2004-05-09 07:16:04 +00:00
jrandom
878525ced8 handle corrupt files more gracefully 2004-05-09 04:14:30 +00:00
shendaras
418531736b imports
Did you miss me?
(shendaras)
2004-05-09 01:31:12 +00:00
jrandom
6c175440c6 added mush.zeit.i2p 2004-05-08 06:41:01 +00:00
268 changed files with 3719 additions and 1867 deletions

View File

@@ -4,7 +4,6 @@ import net.i2p.data.Destination;
import net.i2p.util.Clock;
import net.i2p.util.I2PThread;
import net.i2p.util.Log;
import net.i2p.util.Clock;
/**
* Responsible for actually conducting the tests, coordinating the storing of the

View File

@@ -2,11 +2,11 @@ package net.i2p.heartbeat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import net.i2p.stat.Rate;

View File

@@ -10,7 +10,6 @@ import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
class HeartbeatMonitorGUI extends JFrame {
private HeartbeatMonitor _monitor;

View File

@@ -1,6 +1,5 @@
package net.i2p.heartbeat.gui;
import java.awt.Color;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

View File

@@ -1,26 +1,23 @@
package net.i2p.heartbeat.gui;
import java.awt.Color;
import java.awt.Font;
import java.util.List;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.XYItemRenderer;
import org.jfree.chart.renderer.XYLineAndShapeRenderer;
import org.jfree.data.XYSeries;
import org.jfree.data.XYSeriesCollection;
import net.i2p.heartbeat.PeerData;
import net.i2p.util.Log;
import org.jfree.data.XYSeries;
import org.jfree.data.XYSeriesCollection;
import org.jfree.data.MovingAverage;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.renderer.XYLineAndShapeRenderer;
import org.jfree.chart.renderer.XYItemRenderer;
import org.jfree.chart.renderer.XYDotRenderer;
import java.util.List;
import javax.swing.JPanel;
import java.awt.Font;
import java.awt.Color;
class JFreeChartAdapter {
private final static Log _log = new Log(JFreeChartAdapter.class);
private final static Color WHITE = new Color(255, 255, 255);

View File

@@ -1,21 +1,14 @@
package net.i2p.heartbeat.gui;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import javax.swing.JLabel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import net.i2p.heartbeat.PeerDataWriter;
import net.i2p.util.Log;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import org.jfree.chart.ChartPanel;
import net.i2p.util.Log;
/**
* Render the graph and legend
*

View File

@@ -11,8 +11,8 @@ import java.util.Set;
import java.util.TreeMap;
import net.i2p.data.Destination;
import net.i2p.util.Log;
import net.i2p.heartbeat.ClientConfig;
import net.i2p.util.Log;
/**
* Configure how we want to render a particular clientConfig in the GUI

View File

@@ -7,8 +7,8 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import net.i2p.I2PAppContext;
import net.i2p.I2PException;
import net.i2p.client.naming.NamingService;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.client.streaming.I2PSocketManager;
import net.i2p.client.streaming.I2PSocketOptions;
@@ -19,7 +19,6 @@ import net.i2p.httptunnel.SocketManagerProducer;
import net.i2p.httptunnel.filter.Filter;
import net.i2p.httptunnel.filter.NullFilter;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
* Handler for browsing Eepsites.

View File

@@ -3,7 +3,7 @@ package net.i2p.httptunnel.handler;
import java.io.IOException;
import java.io.OutputStream;
import net.i2p.client.naming.NamingService;
import net.i2p.I2PAppContext;
import net.i2p.client.streaming.I2PSocketManager;
import net.i2p.data.Destination;
import net.i2p.httptunnel.HTTPListener;
@@ -12,7 +12,6 @@ import net.i2p.httptunnel.SocketManagerProducer;
import net.i2p.httptunnel.filter.Filter;
import net.i2p.httptunnel.filter.NullFilter;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
* Handler for proxying "normal" HTTP requests.

View File

@@ -67,6 +67,8 @@ public class I2PTunnel implements Logging, EventDispatcher {
private Log _log;
private EventDispatcherImpl _event;
private I2PAppContext _context;
private static long __tunnelId = 0;
private long _tunnelId;
public static final int PACKET_DELAY = 100;
@@ -98,7 +100,8 @@ public class I2PTunnel implements Logging, EventDispatcher {
}
public I2PTunnel(String[] args, ConnectionEventListener lsnr) {
_context = new I2PAppContext();
_context = I2PAppContext.getGlobalContext(); // new I2PAppContext();
_tunnelId = ++__tunnelId;
_log = _context.logManager().getLog(I2PTunnel.class);
_event = new EventDispatcherImpl();
addConnectionEventListener(lsnr);
@@ -114,7 +117,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
checkRunByE = false;
} else if (args[i].equals("-nogui")) {
gui = false;
_log.warn("The `-nogui' option of I2PTunnel is deprecated.\n"
_log.warn(getPrefix() + "The `-nogui' option of I2PTunnel is deprecated.\n"
+ "Use `-cli', `-nocli' (aka `-wait') or `-die' instead.");
} else if (args[i].equals("-cli")) {
gui = false;
@@ -280,7 +283,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
serverHost = InetAddress.getByName(args[0]);
} catch (UnknownHostException uhe) {
l.log("unknown host");
_log.error("Error resolving " + args[0], uhe);
_log.error(getPrefix() + "Error resolving " + args[0], uhe);
notifyEvent("serverTaskId", new Integer(-1));
return;
}
@@ -289,7 +292,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
portNum = Integer.parseInt(args[1]);
} catch (NumberFormatException nfe) {
l.log("invalid port");
_log.error("Port specified is not valid: " + args[1], nfe);
_log.error(getPrefix() + "Port specified is not valid: " + args[1], nfe);
notifyEvent("serverTaskId", new Integer(-1));
return;
}
@@ -297,7 +300,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
privKeyFile = new File(args[2]);
if (!privKeyFile.canRead()) {
l.log("private key file does not exist");
_log.error("Private key file does not exist or is not readable: " + args[2]);
_log.error(getPrefix() + "Private key file does not exist or is not readable: " + args[2]);
notifyEvent("serverTaskId", new Integer(-1));
return;
}
@@ -333,7 +336,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
serverHost = InetAddress.getByName(args[0]);
} catch (UnknownHostException uhe) {
l.log("unknown host");
_log.error("Error resolving " + args[0], uhe);
_log.error(getPrefix() + "Error resolving " + args[0], uhe);
notifyEvent("serverTaskId", new Integer(-1));
return;
}
@@ -342,7 +345,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
portNum = Integer.parseInt(args[1]);
} catch (NumberFormatException nfe) {
l.log("invalid port");
_log.error("Port specified is not valid: " + args[1], nfe);
_log.error(getPrefix() + "Port specified is not valid: " + args[1], nfe);
notifyEvent("serverTaskId", new Integer(-1));
return;
}
@@ -378,7 +381,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
port = Integer.parseInt(args[0]);
} catch (NumberFormatException nfe) {
l.log("invalid port");
_log.error("Port specified is not valid: " + args[0], nfe);
_log.error(getPrefix() + "Port specified is not valid: " + args[0], nfe);
notifyEvent("clientTaskId", new Integer(-1));
return;
}
@@ -410,7 +413,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
port = Integer.parseInt(args[0]);
} catch (NumberFormatException nfe) {
l.log("invalid port");
_log.error("Port specified is not valid: " + args[0], nfe);
_log.error(getPrefix() + "Port specified is not valid: " + args[0], nfe);
notifyEvent("httpclientTaskId", new Integer(-1));
return;
}
@@ -451,7 +454,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
port = Integer.parseInt(args[0]);
} catch (NumberFormatException nfe) {
l.log("invalid port");
_log.error("Port specified is not valid: " + args[0], nfe);
_log.error(getPrefix() + "Port specified is not valid: " + args[0], nfe);
notifyEvent("sockstunnelTaskId", new Integer(-1));
return;
}
@@ -565,7 +568,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
pubdest = new FileOutputStream(args[1]);
} catch (IOException ioe) {
l.log("Error opening output stream");
_log.error("Error generating keys to out", ioe);
_log.error(getPrefix() + "Error generating keys to out", ioe);
notifyEvent("genkeysResult", "error");
return;
}
@@ -588,7 +591,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
} catch (IOException ioe) {
l.log("Error generating keys - " + ioe.getMessage());
notifyEvent("genkeysResult", "error");
_log.error("Error generating keys", ioe);
_log.error(getPrefix() + "Error generating keys", ioe);
}
}
@@ -722,7 +725,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
notifyEvent("runResult", "ok");
} catch (IOException ioe) {
l.log("IO error running the file");
_log.error("Error running the file", ioe);
_log.error(getPrefix() + "Error running the file", ioe);
notifyEvent("runResult", "error");
}
} else {
@@ -796,12 +799,12 @@ public class I2PTunnel implements Logging, EventDispatcher {
private boolean closetask(int num, boolean forced, Logging l) {
boolean closed = false;
_log.debug("closetask(): looking for task " + num);
_log.debug(getPrefix() + "closetask(): looking for task " + num);
synchronized (tasks) {
for (Iterator it = tasks.iterator(); it.hasNext();) {
I2PTunnelTask t = (I2PTunnelTask) it.next();
int id = t.getId();
_log.debug("closetask(): parsing task " + id + " (" + t.toString() + ")");
_log.debug(getPrefix() + "closetask(): parsing task " + id + " (" + t.toString() + ")");
if (id == num) {
closed = closetask(t, forced, l);
break;
@@ -836,7 +839,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
for (Iterator it = tasks.iterator(); it.hasNext();) {
I2PTunnelTask t = (I2PTunnelTask) it.next();
if (!t.isOpen()) {
_log.debug("Purging inactive tunnel: [" + t.getId() + "] " + t.toString());
_log.debug(getPrefix() + "Purging inactive tunnel: [" + t.getId() + "] " + t.toString());
it.remove();
}
}
@@ -849,7 +852,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
*/
public void log(String s) {
System.out.println(s);
_log.info("Display: " + s);
_log.info(getPrefix() + "Display: " + s);
}
/**
@@ -982,6 +985,8 @@ public class I2PTunnel implements Logging, EventDispatcher {
listeners.remove(lsnr);
}
}
private String getPrefix() { return '[' + _tunnelId + "]: "; }
/**
* Call this whenever we lose touch with the router involuntarily (aka the router
@@ -989,7 +994,7 @@ public class I2PTunnel implements Logging, EventDispatcher {
*
*/
void routerDisconnected() {
_log.error("Router disconnected - firing notification events");
_log.error(getPrefix() + "Router disconnected - firing notification events");
synchronized (listeners) {
for (Iterator iter = listeners.iterator(); iter.hasNext();) {
ConnectionEventListener lsnr = (ConnectionEventListener) iter.next();

View File

@@ -5,7 +5,6 @@ package net.i2p.i2ptunnel;
import java.net.Socket;
import net.i2p.I2PException;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;

View File

@@ -34,7 +34,7 @@ public abstract class I2PTunnelClientBase extends I2PTunnelTask implements Runna
private static final long DEFAULT_CONNECT_TIMEOUT = 60 * 1000;
private static volatile long __clientId = 0;
private long _clientId;
protected long _clientId;
protected Object sockLock = new Object(); // Guards sockMgr and mySockets
private I2PSocketManager sockMgr;
private List mySockets = new ArrayList();

View File

@@ -10,9 +10,6 @@ import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.util.Date;
import java.util.List;
import java.util.ArrayList;
import java.util.StringTokenizer;
import net.i2p.I2PException;
import net.i2p.client.streaming.I2PSocket;
@@ -101,6 +98,8 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
notifyEvent("openHTTPClientResult", "ok");
}
private String getPrefix() { return "Client[" + _clientId + "]: "; }
protected void clientConnectionRun(Socket s) {
OutputStream out = null;
String targetRequest = null;
@@ -113,7 +112,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
StringBuffer newRequest = new StringBuffer();
while ((line = br.readLine()) != null) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Line=[" + line + "]");
_log.debug(getPrefix() + "Line=[" + line + "]");
if (line.startsWith("Connection: ") ||
line.startsWith("Keep-Alive: ") ||
@@ -122,7 +121,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
if (method == null) { // first line (GET /base64/realaddr)
if (_log.shouldLog(Log.DEBUG))
_log.debug("Method is null for [" + line + "]");
_log.debug(getPrefix() + "Method is null for [" + line + "]");
int pos = line.indexOf(" ");
if (pos == -1) break;
@@ -158,7 +157,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
destination = wwwProxy;
usingWWWProxy = true;
if (_log.shouldLog(Log.DEBUG))
_log.debug("Host doesnt end with .i2p and it contains a period [" + host + "]: wwwProxy!");
_log.debug(getPrefix() + "Host doesnt end with .i2p and it contains a period [" + host + "]: wwwProxy!");
} else {
request = request.substring(pos + 1);
pos = request.indexOf("/");
@@ -168,27 +167,27 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
boolean isValid = usingWWWProxy || isSupportedAddress(host, protocol);
if (!isValid) {
if (_log.shouldLog(Log.INFO)) _log.info("notValid(" + host + ")");
if (_log.shouldLog(Log.INFO)) _log.info(getPrefix() + "notValid(" + host + ")");
method = null;
destination = null;
break;
} else if (!usingWWWProxy) {
if (_log.shouldLog(Log.INFO)) _log.info("host=getHostName(" + destination + ")");
if (_log.shouldLog(Log.INFO)) _log.info(getPrefix() + "host=getHostName(" + destination + ")");
host = getHostName(destination); // hide original host
}
if (_log.shouldLog(Log.DEBUG)) {
_log.debug("METHOD:" + method + ":");
_log.debug("PROTOC:" + protocol + ":");
_log.debug("HOST :" + host + ":");
_log.debug("DEST :" + destination + ":");
_log.debug(getPrefix() + "METHOD:" + method + ":");
_log.debug(getPrefix() + "PROTOC:" + protocol + ":");
_log.debug(getPrefix() + "HOST :" + host + ":");
_log.debug(getPrefix() + "DEST :" + destination + ":");
}
} else {
if (line.startsWith("Host: ") && !usingWWWProxy) {
line = "Host: " + host;
if (_log.shouldLog(Log.INFO))
_log.info("Setting host = " + host);
_log.info(getPrefix() + "Setting host = " + host);
}
}
@@ -200,7 +199,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
}
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("NewRequest header: [" + newRequest.toString() + "]");
_log.debug(getPrefix() + "NewRequest header: [" + newRequest.toString() + "]");
while (br.ready()) { // empty the buffer (POST requests)
int i = br.read();
@@ -222,7 +221,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("Destination: " + destination);
_log.debug(getPrefix() + "Destination: " + destination);
Destination dest = I2PTunnel.destFromName(destination);
if (dest == null) {
@@ -239,19 +238,19 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
timeoutThread.start();
} catch (SocketException ex) {
if (timeoutThread != null) timeoutThread.disable();
_log.info("Error trying to connect", ex);
_log.info(getPrefix() + "Error trying to connect", ex);
l.log(ex.getMessage());
handleHTTPClientException(ex, out, targetRequest, usingWWWProxy, wwwProxy);
closeSocket(s);
} catch (IOException ex) {
if (timeoutThread != null) timeoutThread.disable();
_log.info("Error trying to connect", ex);
_log.info(getPrefix() + "Error trying to connect", ex);
l.log(ex.getMessage());
handleHTTPClientException(ex, out, targetRequest, usingWWWProxy, wwwProxy);
closeSocket(s);
} catch (I2PException ex) {
if (timeoutThread != null) timeoutThread.disable();
_log.info("Error trying to connect", ex);
_log.info("getPrefix() + Error trying to connect", ex);
l.log(ex.getMessage());
handleHTTPClientException(ex, out, targetRequest, usingWWWProxy, wwwProxy);
closeSocket(s);
@@ -280,7 +279,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
_useWWWProxy = useWWWProxy;
_disabled = false;
long timeoutId = ++__timeoutId;
setName("InactivityThread " + timeoutId);
setName("InactivityThread " + getPrefix() + timeoutId);
}
public void disable() {
@@ -293,15 +292,15 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
public void run() {
while (!_disabled) {
if (_runner.isFinished()) {
if (_log.shouldLog(Log.INFO)) _log.info("HTTP client request completed prior to timeout");
if (_log.shouldLog(Log.INFO)) _log.info(getPrefix() + "HTTP client request completed prior to timeout");
return;
}
if (_runner.getLastActivityOn() < Clock.getInstance().now() - INACTIVITY_TIMEOUT) {
if (_runner.getStartedOn() < Clock.getInstance().now() - INACTIVITY_TIMEOUT) {
if (_log.shouldLog(Log.WARN))
_log.warn("HTTP client request timed out (lastActivity: "
_log.warn(getPrefix() + "HTTP client request timed out (lastActivity: "
+ new Date(_runner.getLastActivityOn()) + ", startedOn: "
+ new Date(_runner.getLastActivityOn()) + ")");
+ new Date(_runner.getStartedOn()) + ")");
timeout();
return;
} else {
@@ -320,7 +319,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
}
private void timeout() {
_log.info("Inactivity timeout reached");
_log.info(getPrefix() + "Inactivity timeout reached");
l.log("Inactivity timeout reached");
if (_out != null) {
try {
@@ -330,10 +329,10 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
writeErrorMessage(ERR_TIMEOUT, _out, _targetRequest, _useWWWProxy, wwwProxy);
}
} catch (IOException ioe) {
_log.warn("Error writing out the 'timeout' message", ioe);
_log.warn(getPrefix() + "Error writing out the 'timeout' message", ioe);
}
} else {
_log.warn("Client disconnected before we could say we timed out");
_log.warn(getPrefix() + "Client disconnected before we could say we timed out");
}
closeSocket(s);
}
@@ -364,16 +363,16 @@ public class I2PTunnelHTTPClient extends I2PTunnelClientBase implements Runnable
}
}
private static void handleHTTPClientException(Exception ex, OutputStream out, String targetRequest,
private void handleHTTPClientException(Exception ex, OutputStream out, String targetRequest,
boolean usingWWWProxy, String wwwProxy) {
if (out != null) {
try {
writeErrorMessage(ERR_DESTINATION_UNKNOWN, out, targetRequest, usingWWWProxy, wwwProxy);
} catch (IOException ioe) {
_log.warn("Error writing out the 'destination was unknown' " + "message", ioe);
_log.warn(getPrefix() + "Error writing out the 'destination was unknown' " + "message", ioe);
}
} else {
_log.warn("Client disconnected before we could say that destination " + "was unknown", ex);
_log.warn(getPrefix() + "Client disconnected before we could say that destination " + "was unknown", ex);
}
}

View File

@@ -18,7 +18,7 @@ import net.i2p.util.Clock;
import net.i2p.util.I2PThread;
import net.i2p.util.Log;
public class I2PTunnelRunner extends I2PThread {
public class I2PTunnelRunner extends I2PThread implements I2PSocket.SocketErrorListener {
private final static Log _log = new Log(I2PTunnelRunner.class);
private static volatile long __runnerId;
@@ -51,8 +51,9 @@ public class I2PTunnelRunner extends I2PThread {
this.slock = slock;
this.initialData = initialData;
lastActivityOn = -1;
startedOn = -1;
_log.info("I2PTunnelRunner started");
startedOn = Clock.getInstance().now();
if (_log.shouldLog(Log.INFO))
_log.info("I2PTunnelRunner started");
_runnerId = ++__runnerId;
setName("I2PTunnelRunner " + _runnerId);
start();
@@ -90,10 +91,10 @@ public class I2PTunnelRunner extends I2PThread {
}
public void run() {
startedOn = Clock.getInstance().now();
try {
InputStream in = s.getInputStream();
OutputStream out = new BufferedOutputStream(s.getOutputStream(), NETWORK_BUFFER_SIZE);
i2ps.setSocketErrorListener(this);
InputStream i2pin = i2ps.getInputStream();
OutputStream i2pout = new BufferedOutputStream(i2ps.getOutputStream(), MAX_PACKET_SIZE);
if (initialData != null) {
@@ -121,6 +122,8 @@ public class I2PTunnelRunner extends I2PThread {
} catch (IOException ex) {
ex.printStackTrace();
_log.debug("Error forwarding", ex);
} catch (Exception e) {
_log.error("Internal error", e);
} finally {
try {
if (s != null) s.close();
@@ -132,6 +135,13 @@ public class I2PTunnelRunner extends I2PThread {
}
}
public void errorOccurred() {
synchronized (finishLock) {
finished = true;
finishLock.notifyAll();
}
}
private volatile long __forwarderId = 0;
private class StreamForwarder extends I2PThread {
@@ -187,7 +197,8 @@ public class I2PTunnelRunner extends I2PThread {
out.close();
in.close();
} catch (IOException ex) {
_log.error("Error closing streams", ex);
if (_log.shouldLog(Log.WARN))
_log.warn("Error closing streams", ex);
}
synchronized (finishLock) {
finished = true;

View File

@@ -15,6 +15,7 @@ import java.util.Iterator;
import java.util.Properties;
import net.i2p.I2PException;
import net.i2p.I2PAppContext;
import net.i2p.client.I2PClient;
import net.i2p.client.I2PClientFactory;
import net.i2p.client.streaming.I2PServerSocket;
@@ -144,15 +145,8 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
I2PServerSocket i2pss = sockMgr.getServerSocket();
while (true) {
I2PSocket i2ps = i2pss.accept();
//local is fast, so synchronously. Does not need that many
//threads.
try {
i2ps.setReadTimeout(readTimeout);
Socket s = new Socket(remoteHost, remotePort);
new I2PTunnelRunner(s, i2ps, slock, null);
} catch (SocketException ex) {
i2ps.close();
}
I2PThread t = new I2PThread(new Handler(i2ps));
t.start();
}
} catch (I2PException ex) {
_log.error("Error while waiting for I2PConnections", ex);
@@ -160,5 +154,43 @@ public class I2PTunnelServer extends I2PTunnelTask implements Runnable {
_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);
Socket s = new Socket(remoteHost, remotePort);
afterSocket = I2PAppContext.getGlobalContext().clock().now();
new I2PTunnelRunner(s, _handleSocket, slock, 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) + "]");
}
}
}

View File

@@ -6,7 +6,7 @@ public class ByteCollector {
int size;
public ByteCollector() {
contents = new byte[80];
contents = new byte[1024];
size = 0;
}

View File

@@ -1,15 +1,14 @@
package net.i2p.client.streaming;
import java.net.ConnectException;
import net.i2p.I2PException;
import net.i2p.util.Log;
import net.i2p.util.Clock;
import net.i2p.I2PAppContext;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.i2p.I2PAppContext;
import net.i2p.I2PException;
import net.i2p.util.Clock;
import net.i2p.util.Log;
/**
* Server socket implementation, allowing multiple threads to accept I2PSockets
@@ -90,7 +89,7 @@ class I2PServerSocketImpl implements I2PServerSocket {
*/
public boolean addWaitForAccept(I2PSocket s, long timeoutMs) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("addWaitForAccept [new socket arrived, pending: " + pendingSockets.size());
_log.debug("addWaitForAccept [new socket arrived [" + s.toString() + "], pending: " + pendingSockets.size());
if (closing) {
if (_log.shouldLog(Log.WARN))
@@ -112,7 +111,7 @@ class I2PServerSocketImpl implements I2PServerSocket {
long now = clock.now();
if (now >= end) {
if (_log.shouldLog(Log.INFO))
_log.info("Expired while waiting for accept (time elapsed =" + (now - start) + "ms");
_log.info("Expired while waiting for accept (time elapsed =" + (now - start) + "ms) for socket " + s.toString());
pendingSockets.remove(s);
return false;
}
@@ -131,7 +130,7 @@ class I2PServerSocketImpl implements I2PServerSocket {
}
long now = clock.now();
if (_log.shouldLog(Log.DEBUG))
_log.info("Socket accepted after " + (now-start) + "ms");
_log.info("Socket accepted after " + (now-start) + "ms for socket " + s.toString());
return true;
}

View File

@@ -50,4 +50,21 @@ public interface I2PSocket {
* Closes the socket if not closed yet
*/
public void close() throws IOException;
public void setSocketErrorListener(SocketErrorListener lsnr);
/**
* Allow notification of underlying errors communicating across I2P without
* waiting for any sort of cleanup process. For example, if some data could
* not be sent, this listener is notified immediately, and while the input/output
* streams are notified through IOExceptions, they are told only after the
* TCP-like stream is closed (which may be a minute later, if the close message
* times out as well). This is not fired on normal close() activity.
*
*/
public interface SocketErrorListener {
/**
* An error occurred communicating with the peer.
*/
void errorOccurred();
}
}

View File

@@ -29,7 +29,12 @@ class I2PSocketImpl implements I2PSocket {
private Object remoteIDWaiter = new Object();
private I2PInputStream in;
private I2POutputStream out;
private SocketErrorListener _socketErrorListener;
private boolean outgoing;
private long _socketId;
private static long __socketId = 0;
private long _bytesRead = 0;
private long _bytesWritten = 0;
private Object flagLock = new Object();
/**
@@ -61,6 +66,7 @@ class I2PSocketImpl implements I2PSocket {
this.outgoing = outgoing;
manager = mgr;
remote = peer;
_socketId = ++__socketId;
local = mgr.getSession().getMyDestination();
in = new I2PInputStream();
I2PInputStream pin = new I2PInputStream();
@@ -153,6 +159,7 @@ class I2PSocketImpl implements I2PSocket {
* @param data the data to inject into our local inputStream
*/
public void queueData(byte[] data) {
_bytesRead += data.length;
in.queueData(data);
}
@@ -232,6 +239,17 @@ class I2PSocketImpl implements I2PSocket {
in.setReadTimeout(ms);
}
public void setSocketErrorListener(SocketErrorListener lsnr) {
_socketErrorListener = lsnr;
}
void errorOccurred() {
if (_socketErrorListener != null)
_socketErrorListener.errorOccurred();
}
private String getPrefix() { return "[" + _socketId + "]: "; }
//--------------------------------------------------
private class I2PInputStream extends InputStream {
@@ -256,7 +274,8 @@ class I2PSocketImpl implements I2PSocket {
}
public synchronized int read(byte[] b, int off, int len) throws IOException {
_log.debug("Read called: " + this.hashCode());
if (_log.shouldLog(Log.DEBUG))
_log.debug(getPrefix() + "Read called: " + this.hashCode());
if (len == 0) return 0;
long dieAfter = System.currentTimeMillis() + readTimeout;
byte[] read = bc.startToByteArray(len);
@@ -265,7 +284,8 @@ class I2PSocketImpl implements I2PSocket {
while (read.length == 0) {
synchronized (flagLock) {
if (closed) {
_log.debug("Closed is set, so closing stream: " + hashCode());
if (_log.shouldLog(Log.DEBUG))
_log.debug(getPrefix() + "Closed is set after reading " + _bytesRead + " and writing " + _bytesWritten + ", so closing stream: " + hashCode());
return -1;
}
}
@@ -279,7 +299,7 @@ class I2PSocketImpl implements I2PSocket {
if ((readTimeout >= 0)
&& (System.currentTimeMillis() >= dieAfter)) {
throw new InterruptedIOException("Timeout reading from I2PSocket (" + readTimeout + " msecs)");
throw new InterruptedIOException(getPrefix() + "Timeout reading from I2PSocket (" + readTimeout + " msecs)");
}
read = bc.startToByteArray(len);
@@ -288,7 +308,7 @@ class I2PSocketImpl implements I2PSocket {
System.arraycopy(read, 0, b, off, read.length);
if (_log.shouldLog(Log.DEBUG)) {
_log.debug("Read from I2PInputStream " + hashCode() + " returned "
_log.debug(getPrefix() + "Read from I2PInputStream " + hashCode() + " returned "
+ read.length + " bytes");
}
//if (_log.shouldLog(Log.DEBUG)) {
@@ -309,7 +329,7 @@ class I2PSocketImpl implements I2PSocket {
public synchronized void queueData(byte[] data, int off, int len) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Insert " + len + " bytes into queue: " + hashCode());
_log.debug(getPrefix() + "Insert " + len + " bytes into queue: " + hashCode());
bc.append(data, off, len);
notifyAll();
}
@@ -338,6 +358,7 @@ class I2PSocketImpl implements I2PSocket {
}
public void write(byte[] b, int off, int len) throws IOException {
_bytesWritten += len;
sendTo.queueData(b, off, len);
}
@@ -353,10 +374,10 @@ class I2PSocketImpl implements I2PSocket {
public I2PSocketRunner(InputStream in) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Runner's input stream is: " + in.hashCode());
_log.debug(getPrefix() + "Runner's input stream is: " + in.hashCode());
this.in = in;
String peer = I2PSocketImpl.this.remote.calculateHash().toBase64();
setName("SocketRunner " + (++__runnerId) + " " + peer.substring(0, 4));
setName("SocketRunner " + (++__runnerId) + "/" + _socketId + " " + peer.substring(0, 4));
start();
}
@@ -378,7 +399,7 @@ class I2PSocketImpl implements I2PSocket {
}
if ((bcsize < MAX_PACKET_SIZE) && (in.available() == 0)) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Runner Point d: " + hashCode());
_log.debug(getPrefix() + "Runner Point d: " + hashCode());
try {
Thread.sleep(PACKET_DELAY);
@@ -390,10 +411,11 @@ class I2PSocketImpl implements I2PSocket {
byte[] data = bc.startToByteArray(MAX_PACKET_SIZE);
if (data.length > 0) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Message size is: " + data.length);
_log.debug(getPrefix() + "Message size is: " + data.length);
boolean sent = sendBlock(data);
if (!sent) {
_log.error("Error sending message to peer. Killing socket runner");
_log.error(getPrefix() + "Error sending message to peer. Killing socket runner");
errorOccurred();
return false;
}
}
@@ -413,7 +435,7 @@ class I2PSocketImpl implements I2PSocket {
packetsHandled++;
}
if ((bc.getCurrentSize() > 0) && (packetsHandled > 1)) {
_log.error("A SCARY MONSTER HAS EATEN SOME DATA! " + "(input stream: "
_log.error(getPrefix() + "A SCARY MONSTER HAS EATEN SOME DATA! " + "(input stream: "
+ in.hashCode() + "; "
+ "queue size: " + bc.getCurrentSize() + ")");
}
@@ -426,32 +448,33 @@ class I2PSocketImpl implements I2PSocket {
} // FIXME: Race here?
if (sc) {
if (_log.shouldLog(Log.INFO))
_log.info("Sending close packet: " + outgoing);
_log.info(getPrefix() + "Sending close packet: (we started? " + outgoing + ") after reading " + _bytesRead + " and writing " + _bytesWritten);
byte[] packet = I2PSocketManager.makePacket(getMask(0x02), remoteID, new byte[0]);
boolean sent = manager.getSession().sendMessage(remote, packet);
if (!sent) {
_log.error("Error sending close packet to peer");
_log.error(getPrefix() + "Error sending close packet to peer");
errorOccurred();
}
}
manager.removeSocket(I2PSocketImpl.this);
} catch (InterruptedIOException ex) {
_log.error("BUG! read() operations should not timeout!", ex);
_log.error(getPrefix() + "BUG! read() operations should not timeout!", ex);
} catch (IOException ex) {
// WHOEVER removes this event on inconsistent
// state before fixing the inconsistent state (a
// reference on the socket in the socket manager
// etc.) will get hanged by me personally -- mihi
_log.error("Error running - **INCONSISTENT STATE!!!**", ex);
_log.error(getPrefix() + "Error running - **INCONSISTENT STATE!!!**", ex);
} catch (I2PException ex) {
_log.error("Error running - **INCONSISTENT STATE!!!**", ex);
_log.error(getPrefix() + "Error running - **INCONSISTENT STATE!!!**", ex);
}
}
private boolean sendBlock(byte data[]) throws I2PSessionException {
if (_log.shouldLog(Log.DEBUG))
_log.debug("TIMING: Block to send for " + I2PSocketImpl.this.hashCode());
_log.debug(getPrefix() + "TIMING: Block to send for " + I2PSocketImpl.this.hashCode());
if (remoteID == null) {
_log.error("NULL REMOTEID");
_log.error(getPrefix() + "NULL REMOTEID");
return false;
}
byte[] packet = I2PSocketManager.makePacket(getMask(0x00), remoteID, data);
@@ -463,4 +486,6 @@ class I2PSocketImpl implements I2PSocket {
return sent;
}
}
public String toString() { return "" + hashCode(); }
}

View File

@@ -4,7 +4,6 @@
*/
package net.i2p.client.streaming;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InterruptedIOException;
@@ -21,8 +20,8 @@ import net.i2p.client.I2PSession;
import net.i2p.client.I2PSessionException;
import net.i2p.client.I2PSessionListener;
import net.i2p.data.Base64;
import net.i2p.data.Destination;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
import net.i2p.util.Log;
/**
@@ -190,7 +189,7 @@ public class I2PSocketManager implements I2PSessionListener {
s = (I2PSocketImpl) _outSockets.get(id);
}
_log.debug("*Disconnect outgoing!");
_log.debug("*Disconnect outgoing for socket " + s);
try {
if (s != null) {
if (payload.length > 0) {
@@ -208,7 +207,7 @@ public class I2PSocketManager implements I2PSessionListener {
}
return;
} catch (Exception t) {
_log.error("Ignoring error on disconnect", t);
_log.error("Ignoring error on disconnect for socket " + s, t);
}
}
@@ -226,7 +225,7 @@ public class I2PSocketManager implements I2PSessionListener {
// packet send outgoing
if (_log.shouldLog(Log.DEBUG))
_log.debug("*Packet send outgoing [" + payload.length + "]");
_log.debug("*Packet send outgoing [" + payload.length + "] for socket " + s);
if (s != null) {
s.queueData(payload);
return;
@@ -246,7 +245,6 @@ public class I2PSocketManager implements I2PSessionListener {
*/
private void synIncomingAvailable(String id, byte payload[], I2PSession session)
throws DataFormatException, I2PSessionException {
_log.debug("*Syn!");
Destination d = new Destination();
d.fromByteArray(payload);
@@ -260,6 +258,7 @@ public class I2PSocketManager implements I2PSessionListener {
s.setRemoteID(id);
}
}
_log.debug("*Syn! for socket " + s);
if (!acceptConnections) {
// The app did not instantiate an I2PServerSocket
@@ -284,7 +283,7 @@ public class I2PSocketManager implements I2PSessionListener {
if (!replySentOk) {
if (_log.shouldLog(Log.WARN))
_log.warn("Error sending reply to " + d.calculateHash().toBase64()
+ " in response to a new con message",
+ " in response to a new con message for socket " + s,
new Exception("Failed creation"));
s.internalClose();
}
@@ -294,7 +293,7 @@ public class I2PSocketManager implements I2PSessionListener {
packet[0] = CLOSE_OUT;
boolean nackSent = session.sendMessage(d, packet);
if (!nackSent) {
_log.warn("Error sending NACK for session creation");
_log.warn("Error sending NACK for session creation for socket " + s);
}
s.internalClose();
}
@@ -307,7 +306,6 @@ public class I2PSocketManager implements I2PSessionListener {
*
*/
private void disconnectIncoming(String id, byte payload[]) {
_log.debug("*Disconnect incoming!");
I2PSocketImpl s = null;
synchronized (lock) {
s = (I2PSocketImpl) _inSockets.get(id);
@@ -316,6 +314,8 @@ public class I2PSocketManager implements I2PSessionListener {
}
}
_log.debug("*Disconnect incoming for socket " + s);
try {
if (payload.length == 0 && s != null) {
s.internalClose();
@@ -340,12 +340,13 @@ public class I2PSocketManager implements I2PSessionListener {
* @throws IllegalStateException if the socket isn't open or isn't known
*/
private void sendIncoming(String id, byte payload[]) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("*Packet send incoming [" + payload.length + "]");
I2PSocketImpl s = null;
synchronized (lock) {
s = (I2PSocketImpl) _inSockets.get(id);
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("*Packet send incoming [" + payload.length + "] for socket " + s);
if (s != null) {
s.queueData(payload);
@@ -423,7 +424,7 @@ public class I2PSocketManager implements I2PSessionListener {
boolean sent = false;
sent = _session.sendMessage(peer, packet);
if (!sent) {
_log.info("Unable to send & receive ack for SYN packet");
_log.info("Unable to send & receive ack for SYN packet for socket " + s);
synchronized (lock) {
_outSockets.remove(s.getLocalID());
}
@@ -432,18 +433,18 @@ public class I2PSocketManager implements I2PSessionListener {
remoteID = s.getRemoteID(true, options.getConnectTimeout());
if (remoteID == null)
throw new ConnectException("Connection refused by peer");
throw new ConnectException("Connection refused by peer for socket " + s);
if ("".equals(remoteID))
throw new NoRouteToHostException("Unable to reach peer");
throw new NoRouteToHostException("Unable to reach peer for socket " + s);
if (_log.shouldLog(Log.DEBUG))
_log.debug("TIMING: s given out for remoteID "
+ getReadableForm(remoteID));
+ getReadableForm(remoteID) + " for socket " + s);
return s;
} catch (InterruptedIOException ioe) {
if (_log.shouldLog(Log.ERROR))
_log.error("Timeout waiting for ack from syn for id "
+ getReadableForm(lcID), ioe);
+ getReadableForm(lcID) + " for socket " + s, ioe);
synchronized (lock) {
_outSockets.remove(s.getLocalID());
}
@@ -457,7 +458,7 @@ public class I2PSocketManager implements I2PSessionListener {
throw ex;
} catch (IOException ex) {
if (_log.shouldLog(Log.ERROR))
_log.error("Error sending syn on id " + getReadableForm(lcID), ex);
_log.error("Error sending syn on id " + getReadableForm(lcID) + " for socket " + s, ex);
synchronized (lock) {
_outSockets.remove(s.getLocalID());
}
@@ -465,7 +466,7 @@ public class I2PSocketManager implements I2PSessionListener {
throw new I2PException("Unhandled IOException occurred");
} catch (I2PException ex) {
if (_log.shouldLog(Log.INFO))
_log.info("Error sending syn on id " + getReadableForm(lcID), ex);
_log.info("Error sending syn on id " + getReadableForm(lcID) + " for socket " + s, ex);
synchronized (lock) {
_outSockets.remove(s.getLocalID());
}
@@ -578,7 +579,7 @@ public class I2PSocketManager implements I2PSessionListener {
public void removeSocket(I2PSocketImpl sock) {
synchronized (lock) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Removing socket \"" + getReadableForm(sock.getLocalID()) + "\"");
_log.debug("Removing socket \"" + getReadableForm(sock.getLocalID()) + "\" [" + sock + "]");
_inSockets.remove(sock.getLocalID());
_outSockets.remove(sock.getLocalID());
lock.notify();

View File

@@ -1,17 +1,18 @@
package net.i2p.netmonitor;
import net.i2p.data.RouterInfo;
import net.i2p.util.Log;
import net.i2p.util.Clock;
import java.util.Properties;
import java.util.Iterator;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Locale;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Properties;
import java.util.StringTokenizer;
import net.i2p.data.RouterInfo;
import net.i2p.util.Clock;
import net.i2p.util.Log;
/**
* Pull out important data from the published routerInfo and stash it away

View File

@@ -1,18 +1,18 @@
package net.i2p.netmonitor;
import net.i2p.util.Log;
import net.i2p.util.I2PThread;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.Map;
import java.util.HashMap;
import java.io.IOException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import net.i2p.util.I2PThread;
import net.i2p.util.Log;
/**
* Main driver for the app that harvests data about the performance of the network,

View File

@@ -1,19 +1,17 @@
package net.i2p.netmonitor;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.io.IOException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import net.i2p.util.Clock;
import net.i2p.util.Log;
import net.i2p.data.DataFormatException;
import net.i2p.data.RouterInfo;
import net.i2p.util.Clock;
import net.i2p.util.Log;
/**
* Active process that drives the monitoring by periodically rading the

View File

@@ -1,16 +1,16 @@
package net.i2p.netmonitor;
import net.i2p.util.Clock;
import net.i2p.util.Log;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.Set;
import java.util.TreeMap;
import net.i2p.util.Clock;
import net.i2p.util.Log;
/**
* coordinate the data points summarizing the performance of a particular peer

View File

@@ -1,20 +1,17 @@
package net.i2p.netmonitor;
import net.i2p.util.Log;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.TreeSet;
import java.util.Set;
import java.util.Locale;
import java.util.Date;
import java.util.StringTokenizer;
import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.StringTokenizer;
import net.i2p.util.Log;
/**
* Load up the peer summary
@@ -33,57 +30,61 @@ class PeerSummaryReader {
PeerSummary summary = null;
String curDescription = null;
List curArgs = null;
while ((line = reader.readLine()) != null) {
if (line.startsWith("peer\t")) {
String name = line.substring("peer\t".length()).trim();
summary = monitor.getSummary(name);
if (summary == null)
summary = new PeerSummary(name);
} else if (line.startsWith("## ")) {
curDescription = line.substring("## ".length()).trim();
curArgs = new ArrayList(4);
} else if (line.startsWith("# param ")) {
int start = line.indexOf(':');
String arg = line.substring(start+1).trim();
curArgs.add(arg);
} else {
StringTokenizer tok = new StringTokenizer(line);
String name = tok.nextToken();
try {
long when = getTime(tok.nextToken());
boolean isDouble = false;
List argVals = new ArrayList(curArgs.size());
while (tok.hasMoreTokens()) {
String val = (String)tok.nextToken();
if (val.indexOf('.') >= 0) {
argVals.add(new Double(val));
isDouble = true;
} else {
argVals.add(new Long(val));
try {
while ((line = reader.readLine()) != null) {
if (line.startsWith("peer\t")) {
String name = line.substring("peer\t".length()).trim();
summary = monitor.getSummary(name);
if (summary == null)
summary = new PeerSummary(name);
} else if (line.startsWith("## ")) {
curDescription = line.substring("## ".length()).trim();
curArgs = new ArrayList(4);
} else if (line.startsWith("# param ")) {
int start = line.indexOf(':');
String arg = line.substring(start+1).trim();
curArgs.add(arg);
} else {
StringTokenizer tok = new StringTokenizer(line);
String name = tok.nextToken();
try {
long when = getTime(tok.nextToken());
boolean isDouble = false;
List argVals = new ArrayList(curArgs.size());
while (tok.hasMoreTokens()) {
String val = (String)tok.nextToken();
if (val.indexOf('.') >= 0) {
argVals.add(new Double(val));
isDouble = true;
} else {
argVals.add(new Long(val));
}
}
String valDescriptions[] = new String[curArgs.size()];
for (int i = 0; i < curArgs.size(); i++)
valDescriptions[i] = (String)curArgs.get(i);
if (isDouble) {
double values[] = new double[argVals.size()];
for (int i = 0; i < argVals.size(); i++)
values[i] = ((Double)argVals.get(i)).doubleValue();
summary.addData(name, curDescription, valDescriptions, when, values);
} else {
long values[] = new long[argVals.size()];
for (int i = 0; i < argVals.size(); i++)
values[i] = ((Long)argVals.get(i)).longValue();
summary.addData(name, curDescription, valDescriptions, when, values);
}
} catch (ParseException pe) {
_log.error("Error parsing the data line [" + line + "]", pe);
} catch (NumberFormatException nfe) {
_log.error("Error parsing the data line [" + line + "]", nfe);
}
String valDescriptions[] = new String[curArgs.size()];
for (int i = 0; i < curArgs.size(); i++)
valDescriptions[i] = (String)curArgs.get(i);
if (isDouble) {
double values[] = new double[argVals.size()];
for (int i = 0; i < argVals.size(); i++)
values[i] = ((Double)argVals.get(i)).doubleValue();
summary.addData(name, curDescription, valDescriptions, when, values);
} else {
long values[] = new long[argVals.size()];
for (int i = 0; i < argVals.size(); i++)
values[i] = ((Long)argVals.get(i)).longValue();
summary.addData(name, curDescription, valDescriptions, when, values);
}
} catch (ParseException pe) {
_log.error("Error parsing the data line [" + line + "]", pe);
} catch (NumberFormatException nfe) {
_log.error("Error parsing the data line [" + line + "]", nfe);
}
}
}
} catch (Exception e) {
_log.error("Error handling the data", e);
throw new IOException("Error parsing the data");
}
if (summary == null)
return;
summary.coallesceData(monitor.getSummaryDurationHours() * 60*60*1000);

View File

@@ -1,15 +1,15 @@
package net.i2p.netmonitor;
import net.i2p.util.Log;
import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.TreeSet;
import java.util.Set;
import java.util.Locale;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.util.TreeSet;
import net.i2p.util.Log;
/**
* Dump various peer summaries to disk (so external apps (or good ol' vi) can

View File

@@ -1,14 +1,15 @@
package net.i2p.netmonitor;
import net.i2p.util.Log;
import java.io.IOException;
import java.io.File;
import java.io.FileInputStream;
import java.util.List;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import net.i2p.util.Log;
/**
* Load up the StatGroups from the location specified to configure the data harvester.
* The stat groups are formatted in a simple properties file style, e.g.: <pre>

View File

@@ -1,28 +1,24 @@
package net.i2p.netmonitor.gui;
import net.i2p.netmonitor.PeerSummary;
import net.i2p.netmonitor.PeerStat;
import net.i2p.util.Log;
import org.jfree.data.XYSeries;
import org.jfree.data.XYSeriesCollection;
import org.jfree.data.MovingAverage;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.renderer.XYLineAndShapeRenderer;
import org.jfree.chart.renderer.XYItemRenderer;
import org.jfree.chart.renderer.XYDotRenderer;
import java.awt.Color;
import java.awt.Font;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Iterator;
import javax.swing.JPanel;
import java.awt.Font;
import java.awt.Color;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.Plot;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.XYItemRenderer;
import org.jfree.chart.renderer.XYLineAndShapeRenderer;
import org.jfree.data.XYSeries;
import org.jfree.data.XYSeriesCollection;
import net.i2p.netmonitor.PeerStat;
import net.i2p.util.Log;
class JFreeChartAdapter {
private final static Log _log = new Log(JFreeChartAdapter.class);

View File

@@ -1,20 +1,15 @@
package net.i2p.netmonitor.gui;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import javax.swing.JLabel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import net.i2p.util.Log;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import org.jfree.chart.ChartPanel;
import net.i2p.util.Log;
/**
* Render the graph and legend
*

View File

@@ -1,14 +1,13 @@
package net.i2p.netmonitor.gui;
import net.i2p.netmonitor.NetMonitor;
import net.i2p.netmonitor.PeerSummary;
import net.i2p.netmonitor.PeerStat;
import net.i2p.util.Log;
import net.i2p.util.I2PThread;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import net.i2p.netmonitor.NetMonitor;
import net.i2p.util.I2PThread;
import net.i2p.util.Log;
/**
* Coordinate the visualization of the network monitor. <p />

View File

@@ -5,7 +5,6 @@ import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import java.awt.Dimension;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;

View File

@@ -1,9 +1,5 @@
package net.i2p.netmonitor.gui;
import java.awt.Color;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.swing.JPanel;
import javax.swing.JTextArea;

View File

@@ -1,20 +1,15 @@
package net.i2p.netmonitor.gui;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.TreeMap;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import net.i2p.data.Destination;
import net.i2p.util.Log;
import net.i2p.netmonitor.PeerSummary;
import net.i2p.util.Log;
/**
* Configure how we want to render a particular peerSummary in the GUI

View File

@@ -5,25 +5,21 @@ import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.TreeMap;
import java.util.List;
import java.util.ArrayList;
import java.util.Set;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.TreeMap;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import net.i2p.util.Log;
import net.i2p.netmonitor.PeerStat;
import net.i2p.netmonitor.PeerSummary;
import net.i2p.util.Log;
class PeerPlotConfigPane extends JPanel implements PeerPlotConfig.UpdateListener {
private final static Log _log = new Log(PeerPlotConfigPane.class);

View File

@@ -0,0 +1,58 @@
using System.Reflection;
using System.Runtime.CompilerServices;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly: AssemblyTitle("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")]
//
// In order to sign your assembly you must specify a key to use. Refer to the
// Microsoft .NET Framework documentation for more information on assembly signing.
//
// Use the attributes below to control which key is used for signing.
//
// Notes:
// (*) If no key is specified, the assembly is not signed.
// (*) KeyName refers to a key that has been installed in the Crypto Service
// Provider (CSP) on your machine. KeyFile refers to a file which contains
// a key.
// (*) If the KeyFile and the KeyName values are both specified, the
// following processing occurs:
// (1) If the KeyName can be found in the CSP, that key is used.
// (2) If the KeyName does not exist and the KeyFile does exist, the key
// in the KeyFile is installed into the CSP and used.
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
// When specifying the KeyFile, the location of the KeyFile should be
// relative to the project output directory which is
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
// located in the project directory, you would specify the AssemblyKeyFile
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
// documentation for more information on this.
//
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")]

View File

@@ -0,0 +1,50 @@
using System;
using System.Net;
using System.Threading;
using System.Text;
using System.Collections;
namespace SAM.NET
{
class SAMTester
{
[STAThread]
static void Main(string[] args)
{
new SAMTester();
}
public SAMTester ()
{
SAMConnection connection1 = new SAMConnection(IPAddress.Parse("127.0.0.1"),7656);
SAMSession session1 = new SAMSession(connection1,SAM.NET.SamSocketType.Stream,"alice");
SAMConnection connection2 = new SAMConnection(IPAddress.Parse("127.0.0.1"),7656);
SAMSession session2 = new SAMSession(connection2,SAM.NET.SamSocketType.Stream,"bob");
SAMStream stream1 = new SAMStream(connection1,session1,233);
stream1.Connect(session2.getKey());
//Wait till we are connected to destination
while (!stream1.isConnected)
Thread.Sleep(1000);
//Send some bytes
stream1.Write(Encoding.ASCII.GetBytes(DateTime.Now.ToLongTimeString() + "Hi!!!!!!"));
//Wait till a stream magically appears on the other side
while (session2.getStreams().Count == 0) Thread.Sleep(1000);
Thread.Sleep(1000);
foreach (SAMStream stream in session2.getStreams().Values)
{
Console.WriteLine("Text received on " + stream.getID() + " at " + DateTime.Now.ToLongTimeString());
Console.WriteLine(Encoding.ASCII.GetString(stream.ReadToEnd()));
stream.Close();
}
stream1.Close();
connection1.Close();
connection2.Close();
}
}
}

View File

@@ -0,0 +1,58 @@
using System.Reflection;
using System.Runtime.CompilerServices;
//
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
//
[assembly: AssemblyTitle("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
//
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.*")]
//
// In order to sign your assembly you must specify a key to use. Refer to the
// Microsoft .NET Framework documentation for more information on assembly signing.
//
// Use the attributes below to control which key is used for signing.
//
// Notes:
// (*) If no key is specified, the assembly is not signed.
// (*) KeyName refers to a key that has been installed in the Crypto Service
// Provider (CSP) on your machine. KeyFile refers to a file which contains
// a key.
// (*) If the KeyFile and the KeyName values are both specified, the
// following processing occurs:
// (1) If the KeyName can be found in the CSP, that key is used.
// (2) If the KeyName does not exist and the KeyFile does exist, the key
// in the KeyFile is installed into the CSP and used.
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
// When specifying the KeyFile, the location of the KeyFile should be
// relative to the project output directory which is
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
// located in the project directory, you would specify the AssemblyKeyFile
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
// documentation for more information on this.
//
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("")]
[assembly: AssemblyKeyName("")]

View File

@@ -0,0 +1,271 @@
using System;
using System.Net.Sockets;
using System.Text;
using System.Net;
using System.IO;
using System.Collections;
using System.Threading;
namespace SAM.NET
{
public enum SamSocketType
{
Stream,
Datagram,
Raw
}
public class SAMConnection
{
private const string propertyMinVersion = "1.0";
private const string propertyMaxVersion = "1.0";
private Socket _sock;
private NetworkStream _sockStream;
private StreamReader _sockStreamIn;
private StreamWriter _sockStreamOut;
public SAMConnection(IPAddress routerIP, int port)
{
_sock = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
IPEndPoint rEP = new IPEndPoint(routerIP,port);
_sock.Connect(rEP);
_sockStream = new NetworkStream(_sock);
_sockStreamIn = new StreamReader(_sockStream);
_sockStreamOut = new StreamWriter(_sockStream);
try
{
sendVersion(propertyMinVersion,propertyMinVersion);
}
catch (Exception e)
{
_sock.Close();
throw (new Exception("No SAM for you :("));
}
}
private void sendVersion(string min, string max)
{
_sockStreamOut.WriteLine("HELLO VERSION MIN=" + propertyMinVersion + " MAX=" + propertyMaxVersion);
_sockStreamOut.Flush();
Hashtable response = SAMUtil.parseKeyValues(_sockStreamIn.ReadLine(),2);
if (response["RESULT"].ToString() != "OK") throw (new Exception("Version mismatch"));
}
public StreamWriter getOutputStream()
{
return _sockStreamOut;
}
public StreamReader getInputStream()
{
return _sockStreamIn;
}
public NetworkStream getStream()
{
return _sockStream;
}
public void Close()
{
_sock.Close();
}
}
/*
* Creating a SAMSession object will automatically:
* 1) create a sesion on SAM
* 1) query for the base64key
* 2) start a listening thread to catch all stream commands
*/
public class SAMSession
{
private Hashtable _streams;
private string _sessionKey;
public SAMSession (SAMConnection connection, SamSocketType type, string destination)
{
_streams = new Hashtable();
StreamWriter writer = connection.getOutputStream();
StreamReader reader = connection.getInputStream();
writer.WriteLine("SESSION CREATE STYLE=STREAM DESTINATION=" + destination);
writer.Flush();
Hashtable response = SAMUtil.parseKeyValues(reader.ReadLine(),2);
if (response["RESULT"].ToString() != "OK")
{
throw (new Exception(response["MESSAGE"].ToString()));
}
else
{
writer.WriteLine("NAMING LOOKUP NAME=ME");
writer.Flush();
response = SAMUtil.parseKeyValues(reader.ReadLine(),2);
_sessionKey = response["VALUE"].ToString();
SAMSessionListener listener = new SAMSessionListener(connection,this,_streams);
new Thread(new ThreadStart(listener.startListening)).Start();
}
}
public void addStream(SAMStream stream)
{
_streams.Add(stream.getID(),stream);
}
public string getKey()
{
return _sessionKey;
}
public Hashtable getStreams()
{
return _streams;
}
}
public class SAMSessionListener
{
private Hashtable _streams;
private SAMConnection _connection;
private SAMSession _session;
private bool stayAlive = true;
public SAMSessionListener(SAMConnection connection,SAMSession session, Hashtable streams)
{
_streams = streams;
_connection = connection;
_session = session;
}
public void startListening()
{
StreamReader reader = _connection.getInputStream();
while (stayAlive)
{
string response = reader.ReadLine();
if (response.StartsWith("STREAM STATUS"))
{
Hashtable values = SAMUtil.parseKeyValues(response,2);
SAMStream theStream = (SAMStream)_streams[int.Parse(values["ID"].ToString())];
if (theStream != null) theStream.ReceivedStatus(values);
}
if (response.StartsWith("STREAM CONNECTED"))
{
Hashtable values = SAMUtil.parseKeyValues(response,2);
SAMStream theStream = (SAMStream)_streams[int.Parse(values["ID"].ToString())];
if (theStream != null) theStream.isConnected = true;
}
if (response.StartsWith("STREAM RECEIVED"))
{
Hashtable values = SAMUtil.parseKeyValues(response,2);
int streamID = int.Parse(values["ID"].ToString());
SAMStream theStream = (SAMStream)_streams[streamID];
if (theStream == null) new SAMStream(_connection,_session,streamID);
theStream = (SAMStream)_streams[streamID];
theStream.ReceivedData(int.Parse(values["SIZE"].ToString()));
}
if (response.StartsWith("STREAM CLOSE"))
{
Hashtable values = SAMUtil.parseKeyValues(response,2);
SAMStream theStream = (SAMStream)_streams[int.Parse(values["ID"].ToString())];
if (theStream != null) theStream.isConnected = false;
}
}
}
}
public class SAMStream
{
private int _ID;
private byte[] _data;
private int _position=0;
private int _size=0;
private SAMSession _session;
private SAMConnection _connection;
public bool isConnected=false;
public SAMStream (SAMConnection connection,SAMSession session, int ID)
{
_data = new byte[100000]; //FIXME: change to non-static structure for storing stream data
_ID = ID;
_connection = connection;
_session = session;
_session.addStream(this);
}
public void Connect(string destination)
{
StreamWriter writer = _connection.getOutputStream();
writer.WriteLine("STREAM CONNECT ID=" + _ID.ToString() + " DESTINATION=" + destination);
writer.Flush();
}
public void ReceivedData(int size) //FIXME: WTF is going on when reading the payload here? All zeros and way too many of them.
{
NetworkStream stream = _connection.getStream();
int bytesRead = stream.Read(_data,_size,size);
_size = _size + bytes;
}
public void ReceivedStatus(Hashtable response)
{
if (response["RESULT"].ToString() != "OK")
{
throw (new Exception(response["RESULT"].ToString()));
}
else
{
isConnected = true;
}
}
public int getID() {return _ID;}
public bool DataAvailable()
{
return _position != _size;
}
public void Write(byte[] buf)
{
NetworkStream stream = _connection.getStream();
int sent = 0;
while (sent < buf.Length)
{
int toSend = Math.Min(buf.Length - sent,32768);
string header = "STREAM SEND ID=" + _ID.ToString() + " SIZE=" + toSend.ToString() + "\n";
byte[] headerbytes = Encoding.ASCII.GetBytes(header);
stream.Write(headerbytes,0,headerbytes.Length);
stream.Write(buf,sent,toSend);
sent = sent + toSend;
}
}
public byte[] ReadToEnd()
{
byte[] ret = new byte[_size - _position];
Array.Copy(_data,_position,ret,0,_size - _position);
_position = _size;
return ret;
}
public void Close()
{
StreamWriter writer = _connection.getOutputStream();
writer.WriteLine("STREAM CLOSE " + _ID.ToString());
writer.Flush();
}
}
public class SAMUtil
{
public static Hashtable parseKeyValues(string str, int startingWord)
{
Hashtable hash = new Hashtable();
string strTruncated = string.Join(" ",str.Split(' '),startingWord,str.Split(' ').Length - startingWord);
string[] sets = strTruncated.Split('=',' ');
for (int i=0; i<sets.Length; i=i+2)
{
hash.Add(sets[i],sets[i+1]);
}
return hash;
}
}
}

View File

@@ -8,29 +8,25 @@ package net.i2p.sam;
*
*/
import java.io.IOException;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Properties;
import java.util.Map;
import java.util.HashMap;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;
import net.i2p.data.Destination;
import net.i2p.data.DataFormatException;
import net.i2p.data.PrivateKey;
import net.i2p.data.SigningPrivateKey;
import net.i2p.data.Destination;
import net.i2p.util.I2PThread;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
* SAM bridge implementation.

View File

@@ -8,16 +8,14 @@ package net.i2p.sam;
*
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import net.i2p.client.I2PSessionException;
import net.i2p.client.datagram.I2PDatagramDissector;
import net.i2p.client.datagram.I2PDatagramMaker;
import net.i2p.client.datagram.I2PInvalidDatagramException;
import net.i2p.client.I2PSessionException;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
import net.i2p.util.Log;

View File

@@ -12,7 +12,6 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Properties;
import net.i2p.util.I2PThread;

View File

@@ -9,8 +9,8 @@ package net.i2p.sam;
*/
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;

View File

@@ -9,9 +9,8 @@ package net.i2p.sam;
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import net.i2p.client.I2PClient;

View File

@@ -8,10 +8,8 @@ package net.i2p.sam;
*
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import net.i2p.client.I2PSessionException;

View File

@@ -9,29 +9,27 @@ package net.i2p.sam;
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.util.HashMap;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.NoRouteToHostException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
import net.i2p.I2PException;
import net.i2p.client.I2PClient;
import net.i2p.client.streaming.I2PServerSocket;
import net.i2p.client.streaming.I2PSocket;
import net.i2p.client.streaming.I2PSocketManager;
import net.i2p.client.streaming.I2PSocketManagerFactory;
import net.i2p.client.streaming.I2PSocketOptions;
import net.i2p.client.I2PClient;
import net.i2p.data.Base64;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
import net.i2p.I2PException;
import net.i2p.util.HexDump;
import net.i2p.util.I2PThread;
import net.i2p.util.Log;

View File

@@ -8,22 +8,20 @@ package net.i2p.sam;
*
*/
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Properties;
import java.util.StringTokenizer;
import net.i2p.I2PAppContext;
import net.i2p.I2PException;
import net.i2p.client.I2PClient;
import net.i2p.client.I2PClientFactory;
import net.i2p.client.naming.NamingService;
import net.i2p.data.Base64;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
* Miscellaneous utility methods used by SAM protocol handlers.

View File

@@ -8,27 +8,24 @@ package net.i2p.sam;
*
*/
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.InputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.ConnectException;
import java.net.NoRouteToHostException;
import java.util.Enumeration;
import java.net.Socket;
import java.util.Properties;
import java.util.StringTokenizer;
import net.i2p.I2PException;
import net.i2p.client.I2PSessionException;
import net.i2p.data.Base64;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
import net.i2p.I2PException;
import net.i2p.util.Log;
/**
@@ -127,8 +124,6 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
+ "\"; opcode: \"" + opcode + "\")");
}
props = SAMUtils.parseParams(tok);
if (i2cpProps != null)
props.putAll(i2cpProps); // make sure we've got the i2cp settings
if (domain.equals("STREAM")) {
canContinue = execStreamMessage(opcode, props);
@@ -137,6 +132,8 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
} else if (domain.equals("RAW")) {
canContinue = execRawMessage(opcode, props);
} else if (domain.equals("SESSION")) {
if (i2cpProps != null)
props.putAll(i2cpProps); // make sure we've got the i2cp settings
canContinue = execSessionMessage(opcode, props);
} else if (domain.equals("DEST")) {
canContinue = execDestMessage(opcode, props);
@@ -234,9 +231,9 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
props.remove("STYLE");
if (style.equals("RAW")) {
rawSession = new SAMRawSession(dest, props, this);
rawSession = new SAMRawSession(destKeystream, props, this);
} else if (style.equals("DATAGRAM")) {
datagramSession = new SAMDatagramSession(dest, props,this);
datagramSession = new SAMDatagramSession(destKeystream, props,this);
} else if (style.equals("STREAM")) {
String dir = props.getProperty("DIRECTION");
if (dir == null) {

View File

@@ -0,0 +1,78 @@
package net.i2p.sam;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import net.i2p.util.Log;
public class TestCreateSessionDatagram {
private static Log _log = new Log(TestCreateSessionDatagram.class);
private static void runTest(String samHost, int samPort, String conOptions) {
testTransient(samHost, samPort, conOptions);
testNewDest(samHost, samPort, conOptions);
testOldDest(samHost, samPort, conOptions);
}
private static void testTransient(String host, int port, String conOptions) {
testDest(host, port, conOptions, "TRANSIENT");
_log.debug("\n\nTest of transient complete\n\n\n");
try { Thread.sleep(10*1000); } catch (InterruptedException ie) {}
}
private static void testNewDest(String host, int port, String conOptions) {
String destName = "Alice" + Math.random();
testDest(host, port, conOptions, destName);
}
private static void testOldDest(String host, int port, String conOptions) {
String destName = "Alice" + Math.random();
testDest(host, port, conOptions, destName);
_log.debug("\n\nTest of initial contact for " + destName + " complete, waiting 90 seconds");
try { Thread.sleep(90*1000); } catch (InterruptedException ie) {}
_log.debug("now testing subsequent contact\n\n\n");
testDest(host, port, conOptions, destName);
_log.debug("\n\nTest of subsequent contact complete\n\n");
}
private static void testDest(String host, int port, String conOptions, String destName) {
_log.info("\n\nTesting creating a new destination (should come back with 'SESSION STATUS RESULT=OK DESTINATION=someName)\n\n\n");
try {
Socket s = new Socket(host, port);
OutputStream out = s.getOutputStream();
out.write("HELLO VERSION MIN=1.0 MAX=1.0\n".getBytes());
BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = reader.readLine();
_log.debug("line read for valid version: " + line);
String req = "SESSION CREATE STYLE=DATAGRAM DESTINATION=" + destName + " " + conOptions + "\n";
out.write(req.getBytes());
line = reader.readLine();
_log.info("Response to creating the session with destination " + destName + ": " + line);
_log.debug("The above should contain SESSION STATUS RESULT=OK\n\n\n");
try { Thread.sleep(5*1000); } catch (InterruptedException ie) {}
s.close();
} catch (Exception e) {
_log.error("Error testing for valid version", e);
}
}
public static void main(String args[]) {
// "i2cp.tcp.host=www.i2p.net i2cp.tcp.port=7765";
// "i2cp.tcp.host=localhost i2cp.tcp.port=7654 tunnels.inboundDepth=0";
String conOptions = "i2cp.tcp.host=localhost i2cp.tcp.port=7654 tunnels.inboundDepth=0"; // "i2cp.tcp.host=dev.i2p.net i2cp.tcp.port=7002 tunnels.inboundDepth=0";
if (args.length > 0) {
conOptions = "";
for (int i = 0; i < args.length; i++)
conOptions = conOptions + " " + args[i];
}
try {
TestUtil.startupBridge(6000);
runTest("localhost", 6000, conOptions);
} catch (Throwable t) {
_log.error("Error running test", t);
}
try { Thread.sleep(5*1000); } catch (InterruptedException ie) {}
System.exit(0);
}
}

View File

@@ -0,0 +1,78 @@
package net.i2p.sam;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import net.i2p.util.Log;
public class TestCreateSessionRaw {
private static Log _log = new Log(TestCreateSessionRaw.class);
private static void runTest(String samHost, int samPort, String conOptions) {
testTransient(samHost, samPort, conOptions);
testNewDest(samHost, samPort, conOptions);
testOldDest(samHost, samPort, conOptions);
}
private static void testTransient(String host, int port, String conOptions) {
testDest(host, port, conOptions, "TRANSIENT");
_log.debug("\n\nTest of transient complete\n\n\n");
try { Thread.sleep(10*1000); } catch (InterruptedException ie) {}
}
private static void testNewDest(String host, int port, String conOptions) {
String destName = "Alice" + Math.random();
testDest(host, port, conOptions, destName);
}
private static void testOldDest(String host, int port, String conOptions) {
String destName = "Alice" + Math.random();
testDest(host, port, conOptions, destName);
_log.debug("\n\nTest of initial contact for " + destName + " complete, waiting 90 seconds");
try { Thread.sleep(90*1000); } catch (InterruptedException ie) {}
_log.debug("now testing subsequent contact\n\n\n");
testDest(host, port, conOptions, destName);
_log.debug("\n\nTest of subsequent contact complete\n\n");
}
private static void testDest(String host, int port, String conOptions, String destName) {
_log.info("\n\nTesting creating a new destination (should come back with 'SESSION STATUS RESULT=OK DESTINATION=someName)\n\n\n");
try {
Socket s = new Socket(host, port);
OutputStream out = s.getOutputStream();
out.write("HELLO VERSION MIN=1.0 MAX=1.0\n".getBytes());
BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = reader.readLine();
_log.debug("line read for valid version: " + line);
String req = "SESSION CREATE STYLE=RAW DESTINATION=" + destName + " " + conOptions + "\n";
out.write(req.getBytes());
line = reader.readLine();
_log.info("Response to creating the session with destination " + destName + ": " + line);
_log.debug("The above should contain SESSION STATUS RESULT=OK\n\n\n");
try { Thread.sleep(5*1000); } catch (InterruptedException ie) {}
s.close();
} catch (Exception e) {
_log.error("Error testing for valid version", e);
}
}
public static void main(String args[]) {
// "i2cp.tcp.host=www.i2p.net i2cp.tcp.port=7765";
// "i2cp.tcp.host=localhost i2cp.tcp.port=7654 tunnels.inboundDepth=0";
String conOptions = "i2cp.tcp.host=dev.i2p.net i2cp.tcp.port=7002 tunnels.inboundDepth=0";
if (args.length > 0) {
conOptions = "";
for (int i = 0; i < args.length; i++)
conOptions = conOptions + " " + args[i];
}
try {
TestUtil.startupBridge(6000);
runTest("localhost", 6000, conOptions);
} catch (Throwable t) {
_log.error("Error running test", t);
}
try { Thread.sleep(5*1000); } catch (InterruptedException ie) {}
System.exit(0);
}
}

View File

@@ -0,0 +1,106 @@
package net.i2p.sam;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.util.StringTokenizer;
import java.util.Properties;
import net.i2p.util.Log;
import net.i2p.sam.SAMUtils;
public class TestDatagramTransfer {
private static Log _log = new Log(TestCreateSessionDatagram.class);
private static void runTest(String samHost, int samPort, String conOptions) {
testTransfer(samHost, samPort, conOptions);
}
private static void testTransfer(String host, int port, String conOptions) {
String destName = "TRANSIENT";
_log.info("\n\nTesting creating a new destination (should come back with 'SESSION STATUS RESULT=OK DESTINATION=someName)\n\n\n");
try {
Socket s = new Socket(host, port);
OutputStream out = s.getOutputStream();
out.write("HELLO VERSION MIN=1.0 MAX=1.0\n".getBytes());
BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = reader.readLine();
_log.debug("line read for valid version: " + line);
String req = "SESSION CREATE STYLE=DATAGRAM DESTINATION=" + destName + " " + conOptions + "\n";
out.write(req.getBytes());
line = reader.readLine();
_log.info("Response to creating the session with destination " + destName + ": " + line);
_log.debug("The above should contain SESSION STATUS RESULT=OK\n\n\n");
String lookup = "NAMING LOOKUP NAME=ME\n";
out.write(lookup.getBytes());
line = reader.readLine();
_log.info("Response from the lookup for ME: " + line);
_log.debug("The above should be a NAMING REPLY");
StringTokenizer tok = new StringTokenizer(line);
String maj = tok.nextToken();
String min = tok.nextToken();
Properties props = SAMUtils.parseParams(tok);
String value = props.getProperty("VALUE");
if (value == null) {
_log.error("No value for ME found! [" + line + "]");
return;
} else {
_log.info("Alice is located at " + value);
}
String send = "DATAGRAM SEND DESTINATION=" + value + " SIZE=3\nYo!";
out.write(send.getBytes());
line = reader.readLine();
tok = new StringTokenizer(line);
maj = tok.nextToken();
min = tok.nextToken();
props = SAMUtils.parseParams(tok);
String size = props.getProperty("SIZE");
String from = props.getProperty("DESTINATION");
if ( (value == null) || (size == null) ||
(!from.equals(value)) || (!size.equals("3")) ) {
_log.error("Reply of the datagram is incorrect: [" + line + "]");
return;
}
char buf[] = new char[3];
int read = reader.read(buf);
if (read != 3) {
_log.error("Unable to read the full datagram");
return;
}
if (new String(buf).equals("Yo!")) {
_log.info("Received payload successfully");
} else {
_log.error("Payload is incorrect! [" + new String(buf) + "]");
}
try { Thread.sleep(5*1000); } catch (InterruptedException ie) {}
s.close();
} catch (Exception e) {
_log.error("Error testing for valid version", e);
}
}
public static void main(String args[]) {
// "i2cp.tcp.host=www.i2p.net i2cp.tcp.port=7765";
// "i2cp.tcp.host=localhost i2cp.tcp.port=7654 tunnels.inboundDepth=0";
String conOptions = "i2cp.tcp.host=localhost i2cp.tcp.port=7654 tunnels.inboundDepth=0"; // "i2cp.tcp.host=dev.i2p.net i2cp.tcp.port=7002 tunnels.inboundDepth=0";
if (args.length > 0) {
conOptions = "";
for (int i = 0; i < args.length; i++)
conOptions = conOptions + " " + args[i];
}
try {
TestUtil.startupBridge(6000);
runTest("localhost", 6000, conOptions);
} catch (Throwable t) {
_log.error("Error running test", t);
}
try { Thread.sleep(5*1000); } catch (InterruptedException ie) {}
System.exit(0);
}
}

View File

@@ -0,0 +1,109 @@
package net.i2p.sam;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.util.StringTokenizer;
import java.util.Properties;
import net.i2p.util.Log;
import net.i2p.sam.SAMUtils;
public class TestRawTransfer {
private static Log _log = new Log(TestCreateSessionDatagram.class);
private static void runTest(String samHost, int samPort, String conOptions) {
testTransfer(samHost, samPort, conOptions);
}
private static void testTransfer(String host, int port, String conOptions) {
String destName = "TRANSIENT";
_log.info("\n\nTesting creating a new destination (should come back with 'SESSION STATUS RESULT=OK DESTINATION=someName)\n\n\n");
try {
Socket s = new Socket(host, port);
OutputStream out = s.getOutputStream();
out.write("HELLO VERSION MIN=1.0 MAX=1.0\n".getBytes());
BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
String line = reader.readLine();
_log.debug("line read for valid version: " + line);
String req = "SESSION CREATE STYLE=RAW DESTINATION=" + destName + " " + conOptions + "\n";
out.write(req.getBytes());
line = reader.readLine();
_log.info("Response to creating the session with destination " + destName + ": " + line);
_log.debug("The above should contain SESSION STATUS RESULT=OK\n\n\n");
String lookup = "NAMING LOOKUP NAME=ME\n";
out.write(lookup.getBytes());
line = reader.readLine();
_log.info("Response from the lookup for ME: " + line);
_log.debug("The above should be a NAMING REPLY");
StringTokenizer tok = new StringTokenizer(line);
String maj = tok.nextToken();
String min = tok.nextToken();
Properties props = SAMUtils.parseParams(tok);
String value = props.getProperty("VALUE");
if (value == null) {
_log.error("No value for ME found! [" + line + "]");
return;
} else {
_log.info("Alice is located at " + value);
}
String send = "RAW SEND DESTINATION=" + value + " SIZE=3\nYo!";
out.write(send.getBytes());
line = reader.readLine();
try {
tok = new StringTokenizer(line);
maj = tok.nextToken();
min = tok.nextToken();
props = SAMUtils.parseParams(tok);
} catch (Exception e) {
_log.error("Error parsing response line: [" + line + "]", e);
return;
}
String size = props.getProperty("SIZE");
if ( (size == null) || (!size.equals("3")) ) {
_log.error("Reply of the datagram is incorrect: [" + line + "]");
return;
}
char buf[] = new char[3];
int read = reader.read(buf);
if (read != 3) {
_log.error("Unable to read the full datagram");
return;
}
if (new String(buf).equals("Yo!")) {
_log.info("Rec8eived payload successfully");
} else {
_log.error("Payload is incorrect! [" + new String(buf) + "]");
}
try { Thread.sleep(5*1000); } catch (InterruptedException ie) {}
s.close();
} catch (Exception e) {
_log.error("Error testing for valid version", e);
}
}
public static void main(String args[]) {
// "i2cp.tcp.host=www.i2p.net i2cp.tcp.port=7765";
// "i2cp.tcp.host=localhost i2cp.tcp.port=7654 tunnels.inboundDepth=0";
String conOptions = "i2cp.tcp.host=dev.i2p.net i2cp.tcp.port=7002 tunnels.inboundDepth=0";
if (args.length > 0) {
conOptions = "";
for (int i = 0; i < args.length; i++)
conOptions = conOptions + " " + args[i];
}
try {
TestUtil.startupBridge(6000);
runTest("localhost", 6000, conOptions);
} catch (Throwable t) {
_log.error("Error running test", t);
}
try { Thread.sleep(5*1000); } catch (InterruptedException ie) {}
System.exit(0);
}
}

321
apps/sam/perl/Net/SAM.pm Normal file
View File

@@ -0,0 +1,321 @@
#!/usr/bin/perl
## Copyright 2004 Brian Ristuccia. This program is Free Software;
## You can redistribute it and/or modify it under the same terms as
## Perl itself.
package Net::SAM;
@ISA = ( "IO::Socket::INET" );
use strict;
use POSIX;
use Switch;
use IO::Socket;
use IO::Select;
#use Net::SAM::StreamSession;
#use Net::SAM::DatagramSession;
#use Net::SAM::RawSession;
sub new {
my ($class) = shift;
my $type = ref($class) || $class;
my $self = $type->SUPER::new("127.0.0.1:7656");
${*$self}->{incomingraw} = [];
# Connect us to the local SAM proxy.
# my $samsock = IO::Socket::INET->new('127.0.0.1:7657');
#$self->{samsock}=$samsock;
# Say hello, read response.
$self->SUPER::send("HELLO VERSION MIN=1.0 MAX=1.0\n");
while (! ${*$self}->{greeted}) {
$self->readprocess();
}
print "Created SAM object\n";
return $self;
}
sub lookup {
my $self = shift;
my $name= shift;
$self->SUPER::send("NAMING LOOKUP NAME=$name\n");
undef ${*$self}->{RESULT};
while (! ${*$self}->{RESULT}) {
$self->readprocess();
}
if ( ${*$self}->{RESULT} == "OK" ) {
return ${*$self}->{VALUE};
} else {
return undef;
}
}
#sub createsession {
# my ($self) = shift;
# my ($sesstype) = shift;
# print $self->{samsock} "SESSION CREATE STYLE=$SESSTYPE DESTINATION=$DEST, DIRECTION=
#}
#sub waitfor {
# my ($self) = shift;
# my ($prefix) = shift;
# my ($response) = <$samsock>;#
# if $response =~
#}
sub readprocesswrite {
my $self = shift;
$self->readprocess();
$self->dowrite();
}
sub doread {
my $self = shift;
my $rv;
my $data;
$rv = $self->recv($data, $POSIX::BUFSIZE, 0);
if ( defined($rv) && ( length($data) >= 1 ) ) {
# We received some data. Put it in our buffer.
${*$self}->{inbuffer} += $data;
} else {
# No data. Either we're on a non-blocking socket, or there
# was an error or EOF
if ( $!{EAGAIN} ) {
return 1;
} else {
# I suppose caller can look at $! for details
return undef;
}
}
}
sub dowrite {
my $self = shift;
my $rv;
my $data;
$rv = $self->send(${*$self}->{outbuffer}, 0);
if ( ! defined($rv) ) {
warn "SAM::dowrite - Couldn't write for no apparent reason.\n";
return undef;
}
if ( $rv == length(${*$self}->{outbuffer}) || $!{EWOULDBLOCK} ) {
substr(${*$self}->{outbuffer},0, $rv) = ''; # Remove from buffer
# Nuke buffer if empty
delete ${*$self}->{outbuffer} unless length(${*$self}->{outbuffer});
} else {
# Socket closed on us or something?
return undef;
}
}
sub messages {
my $self = shift;
return @{ ${*$self}->{messages} };
}
sub queuemessage {
my $self = shift;
my $message = shift;
push @{ ${*$self}->{messages} } , $message;
}
sub unqueuemessage {
my $self = shift;
return unshift(@{ ${*$self}->{messages} } );
}
sub readprocess {
my $self = shift;
$self->doread();
$self->process();
}
sub process {
my $self = shift;
my %tvhash;
my $payload;
# Before we can read any new messages, if an existing message has payload
# we must read it in. Otherwise we'll create garbage messages containing
# the payload of previous messages.
if ( ${*$self}->{payloadrequired} >= 1 ) {
if ( length( ${*$self}->{inbuffer} ) >= ${*$self}->{payloadrequired} ) {
# Scarf payload from inbuffer into $payload
$payload = substr(${*$self}->{inbuffer}, 0,
${*$self}->{payloadrequired});
# Nuke payload from inbuffer
substr(${*$self}->{inbuffer}, 0,
${*$self}->{payloadrequired} ) = '';
# Put message with payload into spool
push @{ ${*$self}->{messages} } ,
${*$self}->{messagerequiringpayload}.$payload;
# Delete the saved message requiring payload
delete ${*$self}->{messagerequiringpayload};
} else {
# Insufficient payload in inbuffer. Try again later.
return 1;
}
}
if ( ${*$self}->{inbuffer} =~ s/(.*\n)// ) {
%tvhash = $self->_hashtv($1); # Returns a tag/value hash
if ( $tvhash{SIZE} ) {
# We've got a message with payload on our hands. :(
${*$self}->{payloadrequired} = $tvhash{SIZE};
${*$self}->{messagerequiringpayload} = $1;
return 1; # Could call ourself here, but we'll get called again.
} else {
push @{ ${*$self}->{messages} } , $1;
}
}
return 1;
}
# sub junk {
# print "readprocess: " . $self->connected() . "\n";
# # May block if the SAM bridge gets hosed
# my $response = <$self>;
# print "readprocess: $!" . $self->connected() . "\n";
# chomp $response;
# my ($primative, $more, $extra) = split (' ', $response, 3);
# $primative = uc($primative);
# print "readprocess: " . $self->connected() . " -- $primative -- $more -- $extra\n";
# switch ($primative) {
# case "HELLO" {
# if ($more !~ m/REPLY/ ) { die ("Bogus HELLO response") }
# if ($extra =~ m/NOVERSION/ ) {
# die("SAM Bridge Doesn't support my version") ;
# }
# $self->_hashtv($extra);
# ${*$self}->{greeted} = 1;
# };
# case "SESSION" {
# if ( $more !~ m/STATUS/ ) {
# die("Bogus SESSION response");
# }
# $self->_hashtv($extra);
# }
# case "STREAM" {};
# case "DATAGRAM" {
# if ( $more !~ m/RECEIVE/ ) {
# die("Bogus DATAGRAM response.");
# }
# $self->_hashtv($extra);
# push @{ ${*$self}->{incomingdatagram } },
# [ ${*$self}->{DESTINATION},
# $self->_readblock(${*$self}->{SIZE}) ];
# };
# case "RAW" {
# if ( $more !~ m/RECEIVE/ ) {
# die("Bogus RAW response.");
# }
# $self->_hashtv($extra);
# push @{ $self->{incomingraw} }, $self->_readblock($self->{SIZE});
# };
# case "NAMING" {
# if ( $more !~ m/REPLY/ ) {
# die("Bogus NAMING response");
# }
# $self->_hashtv($extra);
# };
# case "DEST" {};
# }
# return 1;
# }
sub getfh {
# Return the FH of the SAM socket so apps can select() or poll() on it
my $self = shift;
return $self->{samsock};
}
sub _readblock {
my $self = shift;
my $size = shift;
my $chunk;
my $payload;
while ( $size > 1 ) {
# XXX: May block. No error checking.
print "readblock: $size\n";
$size -= $self->SUPER::recv($chunk, $size);
$payload .= $chunk;
}
return $payload;
}
sub _hashtv {
my $self = shift;
my $tvstring = shift;
my $tvhash;
while ( $tvstring =~ m/(\S+)=(\S+)/sg ) {
$tvhash->{$1}=$2;
print "hashtv: $1=$2\n"
}
return $tvhash;
}
sub DESTROY {
# Do nothing yet.
}
#sub StreamSession {
# my $self = shift;
# return Net::SAM::StreamSession->new($self);
#}
#sub DatagramSession {
# return Net::SAM::DatagramSession->new($self);
#}
#sub RawSession {
# return Net::SAM::RawSession->new($self);
#}
1;

View File

@@ -0,0 +1,48 @@
#!/usr/bin/perl
package Net::SAM::DatagramSession;
use Net::SAM;
@ISA = ("Net::SAM");
sub new {
my ($class) = shift;
my ($dest , $direction, $options) = shift;
my $self = $class->SUPER::new(@_);
$self->SUPER::send("SESSION CREATE STYLE=DATAGRAM DESTINATION=$dest DIRECTION=$direction $options\n");
undef ${*$self}->{RESULT};
while ( ! ${*$self}->{RESULT} ) {
$self->readprocess() || return undef;
}
if ( ${*$self}->{RESULT} == "OK" ) {
return $self;
} else {
return undef; # sorry.
}
}
sub send {
my $self = shift;
my $destination = shift;
my $message = shift;
my $size = length($message);
$self->SUPER::send("DATAGRAM SEND DESTINATION=$destination SIZE=$size\n$message");
}
sub receive {
my $self = shift;
# Shift one off the fifo array. Returns undef if none wait.
return shift @{ $self->{incomingdatagram} };
}
1;

View File

@@ -0,0 +1,45 @@
#!/usr/bin/perl
package Net::SAM::RawSession;
use Net::SAM;
@ISA = ("Net::SAM");
sub new {
my ($class) = shift;
my ($dest , $direction, $options) = shift;
my $self = $class->SUPER::new(@_);
$self->send("SESSION CREATE STYLE=RAW DESTINATION=$dest DIRECTION=$direction $options\n");
undef $self->{result};
while ( ! $self->{RESULT} ) {
$self->readprocess();
}
if ( $self->{RESULT} == "OK" ) {
return $self;
} else {
return 0; # sorry.
}
}
sub send {
my $self = shift;
my $destination = shift;
my $message = shift;
my $samsock = $self->{samsock};
my $size = length($message);
print $samsock "RAW SEND DESTINATION=$destination SIZE=$size\n$message";
}
sub receive {
my $self = shift;
# Shift one off the fifo array. Returns undef if none wait.
return shift @{ $self->{incomingraw} };
}
1;

View File

@@ -0,0 +1,3 @@
#!/usr/bin/perl
1;

18
apps/sam/perl/samcat.pl Normal file
View File

@@ -0,0 +1,18 @@
#!/usr/bin/perl
use Net::SAM::RawSession;
use Net::SAM::DatagramSession;
$sam=Net::SAM::DatagramSession->new($ARGV[0], "BOTH", "tunnels.depthInbound=0");
print "Connected? " . $sam->connected() . "\n";
$me = $sam->lookup("ME");
print "Sending to $me.\n";
$sam->send($me,"fooquux");
$sam->readprocess();
($source, $message) = @{ $sam->receive() };
print "$source -- $message";

View File

@@ -1,10 +1,10 @@
package net.i2p.time;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.text.DecimalFormat;
/**
@@ -79,7 +79,13 @@ public class NtpClient {
// Get response
packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);
socket.setSoTimeout(10*1000);
try {
socket.receive(packet);
} catch (InterruptedIOException iie) {
socket.close();
return -1;
}
// Immediately record the incoming timestamp
double destinationTimestamp = (System.currentTimeMillis()/1000.0) + SECONDS_1900_TO_EPOCH;

View File

@@ -384,7 +384,7 @@ public class NtpMessage {
// low order bits of the timestamp with a random, unbiased
// bitstring, both to avoid systematic roundoff errors and as
// a means of loop detection and replay detection.
array[7] = (byte) (Math.random()*255.0);
array[7+pointer] = (byte) (Math.random()*255.0);
}

View File

@@ -1,15 +1,14 @@
package net.i2p.time;
import net.i2p.util.Log;
import net.i2p.util.I2PThread;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.net.URL;
import java.net.MalformedURLException;
import java.io.IOException;
import net.i2p.util.I2PThread;
import net.i2p.util.Log;
/**
* Periodically query a series of NTP servers and post the offset
@@ -47,18 +46,22 @@ public class Timestamper implements Runnable {
public void run() {
if (_log.shouldLog(Log.INFO))
_log.info("Starting up timestamper");
while (true) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Querying servers " + _serverList);
long now = NtpClient.currentTime(_serverList);
if (now < 0) {
_log.error("Unable to contact any of the NTP servers - network disconnect?");
} else {
try {
while (true) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Stamp time");
stampTime(now);
_log.debug("Querying servers " + _serverList);
long now = NtpClient.currentTime(_serverList);
if (now < 0) {
_log.error("Unable to contact any of the NTP servers - network disconnect?");
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Stamp time");
stampTime(now);
}
try { Thread.sleep(DELAY_MS); } catch (InterruptedException ie) {}
}
try { Thread.sleep(DELAY_MS); } catch (InterruptedException ie) {}
} catch (Throwable t) {
_log.log(Log.CRIT, "Timestamper died!", t);
}
}
@@ -67,7 +70,10 @@ public class Timestamper implements Runnable {
*/
private void stampTime(long now) {
try {
URL url = new URL(_targetURL + "&now=" + getNow(now));
String toRequest = _targetURL + "&now=" + getNow(now);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Stamping [" + toRequest + "]");
URL url = new URL(toRequest);
Object o = url.getContent();
// ignore the content
} catch (MalformedURLException mue) {

View File

@@ -14,8 +14,8 @@ package net.i2p;
*
*/
public class CoreVersion {
public final static String ID = "$Revision: 1.4 $ $Date: 2004/04/30 18:04:13 $";
public final static String VERSION = "0.3.1.1";
public final static String ID = "$Revision: 1.6 $ $Date: 2004/05/13 18:49:08 $";
public final static String VERSION = "0.3.1.3";
public static void main(String args[]) {
System.out.println("I2P Core version: " + VERSION);

View File

@@ -1,26 +1,26 @@
package net.i2p;
import net.i2p.stat.StatManager;
import net.i2p.crypto.SessionKeyManager;
import net.i2p.crypto.PersistentSessionKeyManager;
import net.i2p.crypto.ElGamalAESEngine;
import net.i2p.crypto.ElGamalEngine;
import net.i2p.crypto.DummyElGamalEngine;
import net.i2p.crypto.SHA256Generator;
import net.i2p.crypto.HMACSHA256Generator;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import net.i2p.client.naming.NamingService;
import net.i2p.crypto.AESEngine;
import net.i2p.crypto.CryptixAESEngine;
import net.i2p.crypto.DSAEngine;
import net.i2p.client.naming.NamingService;
import net.i2p.util.LogManager;
import net.i2p.util.Clock;
import net.i2p.util.RandomSource;
import net.i2p.data.RoutingKeyGenerator;
import net.i2p.crypto.DummyElGamalEngine;
import net.i2p.crypto.ElGamalAESEngine;
import net.i2p.crypto.ElGamalEngine;
import net.i2p.crypto.HMACSHA256Generator;
import net.i2p.crypto.KeyGenerator;
import java.util.Properties;
import java.util.HashSet;
import java.util.Set;
import net.i2p.crypto.PersistentSessionKeyManager;
import net.i2p.crypto.SHA256Generator;
import net.i2p.crypto.SessionKeyManager;
import net.i2p.data.RoutingKeyGenerator;
import net.i2p.stat.StatManager;
import net.i2p.util.Clock;
import net.i2p.util.LogManager;
import net.i2p.util.RandomSource;
/**
* <p>Provide a base scope for accessing singletons that I2P exposes. Rather than

View File

@@ -24,14 +24,13 @@ import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
import net.i2p.I2PAppContext;
import net.i2p.I2PException;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
import net.i2p.util.Clock;
import net.i2p.util.I2PThread;
import net.i2p.util.Log;
import net.i2p.util.LogManager;
import net.i2p.I2PAppContext;
/**
* ATalk - anonymous talk, demonstrating a trivial I2P usage scenario.

View File

@@ -9,9 +9,9 @@ package net.i2p.client;
*
*/
import net.i2p.I2PAppContext;
import net.i2p.data.i2cp.DisconnectMessage;
import net.i2p.data.i2cp.I2CPMessage;
import net.i2p.I2PAppContext;
/**
* Handle I2CP disconnect messages from the router

View File

@@ -9,8 +9,8 @@ package net.i2p.client;
*
*/
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
import net.i2p.util.Log;
/**
* Base class for handling I2CP messages

View File

@@ -12,7 +12,7 @@ package net.i2p.client;
import java.util.HashSet;
import java.util.Set;
import net.i2p.crypto.ElGamalAESEngine;
import net.i2p.I2PAppContext;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
import net.i2p.data.LeaseSet;
@@ -32,7 +32,6 @@ import net.i2p.data.i2cp.SendMessageMessage;
import net.i2p.data.i2cp.SessionConfig;
import net.i2p.util.Log;
import net.i2p.util.RandomSource;
import net.i2p.I2PAppContext;
/**
* Produce the various messages the session needs to send to the router.

View File

@@ -14,6 +14,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.util.Properties;
import net.i2p.I2PAppContext;
import net.i2p.I2PException;
import net.i2p.crypto.KeyGenerator;
import net.i2p.data.Certificate;
@@ -22,7 +23,6 @@ import net.i2p.data.PrivateKey;
import net.i2p.data.PublicKey;
import net.i2p.data.SigningPrivateKey;
import net.i2p.data.SigningPublicKey;
import net.i2p.I2PAppContext;
/**
* Base client implementation

View File

@@ -12,6 +12,7 @@ package net.i2p.client;
import java.util.HashMap;
import java.util.Map;
import net.i2p.I2PAppContext;
import net.i2p.data.i2cp.DisconnectMessage;
import net.i2p.data.i2cp.MessagePayloadMessage;
import net.i2p.data.i2cp.MessageStatusMessage;
@@ -19,7 +20,6 @@ import net.i2p.data.i2cp.RequestLeaseSetMessage;
import net.i2p.data.i2cp.SessionStatusMessage;
import net.i2p.data.i2cp.SetDateMessage;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
* Contains a map of message handlers that a session will want to use

View File

@@ -23,6 +23,7 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import net.i2p.I2PAppContext;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
import net.i2p.data.LeaseSet;
@@ -36,10 +37,8 @@ import net.i2p.data.i2cp.I2CPMessageException;
import net.i2p.data.i2cp.I2CPMessageReader;
import net.i2p.data.i2cp.MessagePayloadMessage;
import net.i2p.data.i2cp.SessionId;
import net.i2p.util.Clock;
import net.i2p.util.I2PThread;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
* Implementation of an I2P session running over TCP. This class is NOT thread safe -
@@ -148,7 +147,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
_portNum = Integer.parseInt(portNum);
} catch (NumberFormatException nfe) {
if (_log.shouldLog(Log.WARN))
_log.warn("Invalid port number specified, defaulting to "
_log.warn(getPrefix() + "Invalid port number specified, defaulting to "
+ TestServer.LISTEN_PORT, nfe);
_portNum = TestServer.LISTEN_PORT;
}
@@ -173,7 +172,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
if (_log.shouldLog(Log.DEBUG)) _log.debug("Skipping line.* property: " + key);
} else if ((key.length() > 255) || (val.length() > 255)) {
if (_log.shouldLog(Log.WARN))
_log.warn("Not passing on property ["
_log.warn(getPrefix() + "Not passing on property ["
+ key
+ "] in the session configuration as the value is too long (max = 255): "
+ val);
@@ -223,7 +222,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
_closed = false;
long startConnect = _context.clock().now();
try {
if (_log.shouldLog(Log.DEBUG)) _log.debug("connect begin to " + _hostname + ":" + _portNum);
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "connect begin to " + _hostname + ":" + _portNum);
_socket = new Socket(_hostname, _portNum);
_out = _socket.getOutputStream();
synchronized (_out) {
@@ -231,12 +230,12 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
}
InputStream in = _socket.getInputStream();
_reader = new I2CPMessageReader(in, this);
if (_log.shouldLog(Log.DEBUG)) _log.debug("before startReading");
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "before startReading");
_reader.startReading();
if (_log.shouldLog(Log.DEBUG)) _log.debug("Before getDate");
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "Before getDate");
sendMessage(new GetDateMessage());
if (_log.shouldLog(Log.DEBUG)) _log.debug("After getDate / begin waiting for a response");
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "After getDate / begin waiting for a response");
while (!_dateReceived) {
try {
synchronized (_dateReceivedLock) {
@@ -245,11 +244,11 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
} catch (InterruptedException ie) {
}
}
if (_log.shouldLog(Log.DEBUG)) _log.debug("After received a SetDate response");
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "After received a SetDate response");
if (_log.shouldLog(Log.DEBUG)) _log.debug("Before producer.connect()");
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "Before producer.connect()");
_producer.connect(this);
if (_log.shouldLog(Log.DEBUG)) _log.debug("After producer.connect()");
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "After producer.connect()");
// wait until we have created a lease set
while (_leaseSet == null) {
@@ -262,15 +261,15 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
}
long connected = _context.clock().now();
if (_log.shouldLog(Log.INFO))
_log.info("Lease set created with inbound tunnels after "
+ (connected - startConnect)
+ "ms - ready to participate in the network!");
_log.info(getPrefix() + "Lease set created with inbound tunnels after "
+ (connected - startConnect)
+ "ms - ready to participate in the network!");
} catch (UnknownHostException uhe) {
_closed = true;
throw new I2PSessionException("Invalid session configuration", uhe);
throw new I2PSessionException(getPrefix() + "Invalid session configuration", uhe);
} catch (IOException ioe) {
_closed = true;
throw new I2PSessionException("Problem connecting to " + _hostname + " on port " + _portNum, ioe);
throw new I2PSessionException(getPrefix() + "Problem connecting to " + _hostname + " on port " + _portNum, ioe);
}
}
@@ -289,7 +288,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
* Report abuse with regards to the given messageId
*/
public void reportAbuse(int msgId, int severity) throws I2PSessionException {
if (isClosed()) throw new I2PSessionException("Already closed");
if (isClosed()) throw new I2PSessionException(getPrefix() + "Already closed");
_producer.reportAbuse(this, msgId, severity);
}
@@ -329,7 +328,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
byte data[] = msg.getPayload().getUnencryptedData();
if ((data == null) || (data.length <= 0)) {
if (_log.shouldLog(Log.ERROR))
_log.error("addNewMessage of a message with no unencrypted data",
_log.error(getPrefix() + "addNewMessage of a message with no unencrypted data",
new Exception("Empty message"));
} else {
final long size = data.length;
@@ -344,7 +343,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
notifier.setDaemon(true);
notifier.start();
if (_log.shouldLog(Log.INFO))
_log.info("Notifier " + nid + " is for session " + _sessionId + ", message " + id + "]");
_log.info(getPrefix() + "Notifier " + nid + " is for session " + _sessionId + ", message " + id + "]");
}
}
@@ -356,11 +355,11 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
I2CPMessageHandler handler = _handlerMap.getHandler(message.getType());
if (handler == null) {
if (_log.shouldLog(Log.WARN))
_log.warn("Unknown message or unhandleable message received: type = "
_log.warn(getPrefix() + "Unknown message or unhandleable message received: type = "
+ message.getType());
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Message received of type " + message.getType()
_log.debug(getPrefix() + "Message received of type " + message.getType()
+ " to be handled by " + handler);
handler.handleMessage(message, this);
}
@@ -425,11 +424,11 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
message.writeMessage(_out);
_out.flush();
}
if (_log.shouldLog(Log.DEBUG)) _log.debug("Message written out and flushed");
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "Message written out and flushed");
} catch (I2CPMessageException ime) {
throw new I2PSessionException("Error writing out the message", ime);
throw new I2PSessionException(getPrefix() + "Error writing out the message", ime);
} catch (IOException ioe) {
throw new I2PSessionException("Error writing out the message", ioe);
throw new I2PSessionException(getPrefix() + "Error writing out the message", ioe);
}
}
@@ -437,7 +436,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
* Pass off the error to the listener
*/
void propogateError(String msg, Throwable error) {
if (_log.shouldLog(Log.ERROR)) _log.error("Error occurred: " + msg, error);
if (_log.shouldLog(Log.ERROR)) _log.error(getPrefix() + "Error occurred: " + msg, error);
if (_sessionListener != null) _sessionListener.errorOccurred(this, msg, error);
}
@@ -451,7 +450,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
public void destroySession(boolean sendDisconnect) {
if (_closed) return;
if (_log.shouldLog(Log.DEBUG)) _log.debug("Destroy the session", new Exception("DestroySession()"));
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "Destroy the session", new Exception("DestroySession()"));
if (sendDisconnect) {
try {
_producer.disconnect(this);
@@ -469,7 +468,7 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
*
*/
private void closeSocket() {
if (_log.shouldLog(Log.DEBUG)) _log.debug("Closing the socket", new Exception("closeSocket"));
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "Closing the socket", new Exception("closeSocket"));
_closed = true;
if (_reader != null) _reader.stopReading();
_reader = null;
@@ -489,24 +488,24 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
* Recieve notification that the I2CP connection was disconnected
*/
public void disconnected(I2CPMessageReader reader) {
if (_log.shouldLog(Log.DEBUG)) _log.debug("Disconnected", new Exception("Disconnected"));
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "Disconnected", new Exception("Disconnected"));
disconnect();
}
protected void disconnect() {
if (_closed) return;
if (_log.shouldLog(Log.DEBUG)) _log.debug("Disconnect() called", new Exception("Disconnect"));
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "Disconnect() called", new Exception("Disconnect"));
if (shouldReconnect()) {
if (reconnect()) {
if (_log.shouldLog(Log.INFO)) _log.info("I2CP reconnection successful");
if (_log.shouldLog(Log.INFO)) _log.info(getPrefix() + "I2CP reconnection successful");
return;
} else {
if (_log.shouldLog(Log.ERROR)) _log.error("I2CP reconnection failed");
if (_log.shouldLog(Log.ERROR)) _log.error(getPrefix() + "I2CP reconnection failed");
}
}
if (_log.shouldLog(Log.ERROR))
_log.error("Disconned from the router, and not trying to reconnect further. I hope you're not hoping anything else will happen");
_log.error(getPrefix() + "Disconned from the router, and not trying to reconnect further. I hope you're not hoping anything else will happen");
if (_sessionListener != null) _sessionListener.disconnected(this);
_closed = true;
@@ -526,19 +525,21 @@ abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2CPMessa
_totalReconnectAttempts++;
} else {
if (_log.shouldLog(Log.CRIT))
_log.log(Log.CRIT, "Max number of reconnects exceeded ["
_log.log(Log.CRIT, getPrefix() + "Max number of reconnects exceeded ["
+ _totalReconnectAttempts + "], we give up!");
return false;
}
if (_log.shouldLog(Log.INFO)) _log.info("Reconnecting...");
if (_log.shouldLog(Log.INFO)) _log.info(getPrefix() + "Reconnecting...");
for (int i = 0; i < MAX_RECONNECT_ATTEMPTS; i++) {
try {
connect();
return true;
} catch (I2PSessionException ise) {
if (_log.shouldLog(Log.ERROR)) _log.error("Error reconnecting on attempt " + i, ise);
if (_log.shouldLog(Log.ERROR)) _log.error(getPrefix() + "Error reconnecting on attempt " + i, ise);
}
}
return false;
}
protected String getPrefix() { return "[" + (_sessionId == null ? -1 : _sessionId.getSessionId()) + "]: "; }
}

View File

@@ -15,18 +15,14 @@ import java.util.Iterator;
import java.util.Properties;
import java.util.Set;
import net.i2p.crypto.KeyGenerator;
import net.i2p.crypto.SessionKeyManager;
import net.i2p.I2PAppContext;
import net.i2p.data.DataHelper;
import net.i2p.data.Destination;
import net.i2p.data.SessionKey;
import net.i2p.data.SessionTag;
import net.i2p.data.i2cp.MessageId;
import net.i2p.data.i2cp.MessageStatusMessage;
import net.i2p.util.Clock;
import net.i2p.util.Log;
import net.i2p.util.RandomSource;
import net.i2p.I2PAppContext;
/**
* Thread safe implementation of an I2P session running over TCP.
@@ -107,19 +103,19 @@ class I2PSessionImpl2 extends I2PSessionImpl {
} else if (_context.sessionKeyManager().getAvailableTimeLeft(dest.getPublicKey(), key) < 30 * 1000) {
// if we have > 10 tags, but they expire in under 30 seconds, we want more
sentTags = createNewTags(50);
if (_log.shouldLog(Log.DEBUG)) _log.debug("Tags are almost expired, adding 50 new ones");
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "Tags are almost expired, adding 50 new ones");
}
SessionKey newKey = null;
if (false) // rekey
newKey = _context.keyGenerator().generateSessionKey();
long nonce = (long)_context.random().nextInt(Integer.MAX_VALUE);
MessageState state = new MessageState(nonce);
MessageState state = new MessageState(nonce, getPrefix());
state.setKey(key);
state.setTags(sentTags);
state.setNewKey(newKey);
state.setTo(dest);
if (_log.shouldLog(Log.DEBUG)) _log.debug("Setting key = " + key);
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "Setting key = " + key);
if (keyUsed != null) {
if (newKey != null)
@@ -137,7 +133,7 @@ class I2PSessionImpl2 extends I2PSessionImpl {
_sendingStates.add(state);
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("Adding sending state " + state.getMessageId() + " / "
_log.debug(getPrefix() + "Adding sending state " + state.getMessageId() + " / "
+ state.getNonce());
_producer.sendMessage(this, dest, nonce, payload, tag, key, sentTags, newKey);
state.waitFor(MessageStatusMessage.STATUS_SEND_ACCEPTED,
@@ -147,18 +143,18 @@ class I2PSessionImpl2 extends I2PSessionImpl {
}
boolean found = state.received(MessageStatusMessage.STATUS_SEND_ACCEPTED);
if (_log.shouldLog(Log.DEBUG))
_log.debug("After waitFor sending state " + state.getMessageId().getMessageId()
_log.debug(getPrefix() + "After waitFor sending state " + state.getMessageId().getMessageId()
+ " / " + state.getNonce() + " found = " + found);
if (found) {
if (_log.shouldLog(Log.INFO))
_log.info("Message sent after " + state.getElapsed() + "ms with "
_log.info(getPrefix() + "Message sent after " + state.getElapsed() + "ms with "
+ payload.length + " bytes");
} else {
if (_log.shouldLog(Log.INFO))
_log.info("Message send failed after " + state.getElapsed() + "ms with "
_log.info(getPrefix() + "Message send failed after " + state.getElapsed() + "ms with "
+ payload.length + " bytes");
if (_log.shouldLog(Log.ERROR))
_log.error("Never received *accepted* from the router! dropping and reconnecting");
_log.error(getPrefix() + "Never received *accepted* from the router! dropping and reconnecting");
disconnect();
return false;
}
@@ -176,19 +172,19 @@ class I2PSessionImpl2 extends I2PSessionImpl {
} else if (_context.sessionKeyManager().getAvailableTimeLeft(dest.getPublicKey(), key) < 30 * 1000) {
// if we have > 10 tags, but they expire in under 30 seconds, we want more
sentTags = createNewTags(50);
if (_log.shouldLog(Log.DEBUG)) _log.debug("Tags are almost expired, adding 50 new ones");
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "Tags are almost expired, adding 50 new ones");
}
SessionKey newKey = null;
if (false) // rekey
newKey = _context.keyGenerator().generateSessionKey();
long nonce = (long)_context.random().nextInt(Integer.MAX_VALUE);
MessageState state = new MessageState(nonce);
MessageState state = new MessageState(nonce, getPrefix());
state.setKey(key);
state.setTags(sentTags);
state.setNewKey(newKey);
state.setTo(dest);
if (_log.shouldLog(Log.DEBUG)) _log.debug("Setting key = " + key);
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "Setting key = " + key);
if (keyUsed != null) {
if (newKey != null)
@@ -206,7 +202,7 @@ class I2PSessionImpl2 extends I2PSessionImpl {
_sendingStates.add(state);
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("Adding sending state " + state.getMessageId() + " / "
_log.debug(getPrefix() + "Adding sending state " + state.getMessageId() + " / "
+ state.getNonce());
_producer.sendMessage(this, dest, nonce, payload, tag, key, sentTags, newKey);
if (isGuaranteed())
@@ -223,7 +219,7 @@ class I2PSessionImpl2 extends I2PSessionImpl {
if ((!accepted) || (state.getMessageId() == null)) {
if (_log.shouldLog(Log.ERROR))
_log.error("State with nonce " + state.getNonce()
_log.error(getPrefix() + "State with nonce " + state.getNonce()
+ " was not accepted? (no messageId!! found=" + found
+ " msgId=" + state.getMessageId() + ")",
new Exception("Race on accept/success status messages, or reconnected?"));
@@ -235,16 +231,16 @@ class I2PSessionImpl2 extends I2PSessionImpl {
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("After waitFor sending state " + state.getMessageId().getMessageId()
_log.debug(getPrefix() + "After waitFor sending state " + state.getMessageId().getMessageId()
+ " / " + state.getNonce() + " found = " + found);
if (found) {
if (_log.shouldLog(Log.INFO))
_log.info("Message sent after " + state.getElapsed() + "ms with "
_log.info(getPrefix() + "Message sent after " + state.getElapsed() + "ms with "
+ payload.length + " bytes");
ackTags(state);
} else {
if (_log.shouldLog(Log.INFO))
_log.info("Message send failed after " + state.getElapsed() + "ms with "
_log.info(getPrefix() + "Message send failed after " + state.getElapsed() + "ms with "
+ payload.length + " bytes");
nackTags(state);
}
@@ -253,7 +249,7 @@ class I2PSessionImpl2 extends I2PSessionImpl {
private void ackTags(MessageState state) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("ack tags for msgId " + state.getMessageId() + " / "
_log.debug(getPrefix() + "ack tags for msgId " + state.getMessageId() + " / "
+ state.getNonce() + " key = " + state.getKey() + ", tags = "
+ state.getTags());
if ((state.getTags() != null) && (state.getTags().size() > 0)) {
@@ -266,26 +262,26 @@ class I2PSessionImpl2 extends I2PSessionImpl {
private void nackTags(MessageState state) {
if (_log.shouldLog(Log.INFO))
_log.info("nack tags for msgId " + state.getMessageId() + " / " + state.getNonce()
_log.info(getPrefix() + "nack tags for msgId " + state.getMessageId() + " / " + state.getNonce()
+ " key = " + state.getKey());
_context.sessionKeyManager().failTags(state.getTo().getPublicKey());
}
public void receiveStatus(int msgId, long nonce, int status) {
if (_log.shouldLog(Log.DEBUG)) _log.debug("Received status " + status + " for msgId " + msgId + " / " + nonce);
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "Received status " + status + " for msgId " + msgId + " / " + nonce);
MessageState state = null;
synchronized (_sendingStates) {
for (Iterator iter = _sendingStates.iterator(); iter.hasNext();) {
state = (MessageState) iter.next();
if (_log.shouldLog(Log.DEBUG)) _log.debug("State " + state.getMessageId() + " / " + state.getNonce());
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "State " + state.getMessageId() + " / " + state.getNonce());
if (state.getNonce() == nonce) {
if (_log.shouldLog(Log.DEBUG)) _log.debug("Found a matching state");
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "Found a matching state");
break;
} else if ((state.getMessageId() != null) && (state.getMessageId().getMessageId() == msgId)) {
if (_log.shouldLog(Log.DEBUG)) _log.debug("Found a matching state by msgId");
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "Found a matching state by msgId");
break;
} else {
if (_log.shouldLog(Log.DEBUG)) _log.debug("State does not match");
if (_log.shouldLog(Log.DEBUG)) _log.debug(getPrefix() + "State does not match");
state = null;
}
}
@@ -300,7 +296,7 @@ class I2PSessionImpl2 extends I2PSessionImpl {
state.receive(status);
} else {
if (_log.shouldLog(Log.INFO))
_log.info("No matching state for messageId " + msgId + " / " + nonce
_log.info(getPrefix() + "No matching state for messageId " + msgId + " / " + nonce
+ " w/ status = " + status);
}
}
@@ -323,7 +319,7 @@ class I2PSessionImpl2 extends I2PSessionImpl {
MessageState state = (MessageState) iter.next();
state.cancel();
}
if (_log.shouldLog(Log.INFO)) _log.info("Disconnecting " + _sendingStates.size() + " states");
if (_log.shouldLog(Log.INFO)) _log.info(getPrefix() + "Disconnecting " + _sendingStates.size() + " states");
_sendingStates.clear();
}
}

View File

@@ -9,14 +9,13 @@ package net.i2p.client;
*
*/
import net.i2p.crypto.ElGamalAESEngine;
import net.i2p.I2PAppContext;
import net.i2p.data.DataFormatException;
import net.i2p.data.Payload;
import net.i2p.data.i2cp.I2CPMessage;
import net.i2p.data.i2cp.MessageId;
import net.i2p.data.i2cp.MessagePayloadMessage;
import net.i2p.data.i2cp.ReceiveMessageEndMessage;
import net.i2p.I2PAppContext;
/**
* Handle I2CP MessagePayloadMessages from the router delivering the contents

View File

@@ -20,6 +20,7 @@ import net.i2p.util.Log;
class MessageState {
private final static Log _log = new Log(MessageState.class);
private long _nonce;
private String _prefix;
private MessageId _id;
private Set _receivedStatus;
private SessionKey _key;
@@ -30,8 +31,9 @@ class MessageState {
private long _created;
private Object _lock = new Object();
public MessageState(long nonce) {
public MessageState(long nonce, String prefix) {
_nonce = nonce;
_prefix = prefix;
_id = null;
_receivedStatus = new HashSet();
_cancelled = false;
@@ -64,7 +66,8 @@ class MessageState {
}
public void setKey(SessionKey key) {
if (_log.shouldLog(Log.DEBUG)) _log.debug("Setting key [" + _key + "] to [" + key + "]");
if (_log.shouldLog(Log.DEBUG))
_log.debug(_prefix + "Setting key [" + _key + "] to [" + key + "]");
_key = key;
}
@@ -105,11 +108,13 @@ class MessageState {
if (_cancelled) return;
long timeToWait = expiration - Clock.getInstance().now();
if (timeToWait <= 0) {
if (_log.shouldLog(Log.WARN)) _log.warn("Expired waiting for the status [" + status + "]");
if (_log.shouldLog(Log.WARN))
_log.warn(_prefix + "Expired waiting for the status [" + status + "]");
return;
}
if (isSuccess(status) || isFailure(status)) {
if (_log.shouldLog(Log.DEBUG)) _log.debug("Received a confirm (one way or the other)");
if (_log.shouldLog(Log.DEBUG))
_log.debug(_prefix + "Received a confirm (one way or the other)");
return;
}
if (timeToWait > 5000) {
@@ -133,21 +138,22 @@ class MessageState {
boolean rv = false;
if (_log.shouldLog(Log.DEBUG)) _log.debug("isSuccess(" + wantedStatus + "): " + received);
if (_log.shouldLog(Log.DEBUG))
_log.debug(_prefix + "isSuccess(" + wantedStatus + "): " + received);
for (Iterator iter = received.iterator(); iter.hasNext();) {
Integer val = (Integer) iter.next();
int recv = val.intValue();
switch (recv) {
case MessageStatusMessage.STATUS_SEND_BEST_EFFORT_FAILURE:
if (_log.shouldLog(Log.WARN))
_log.warn("Received best effort failure after " + getElapsed() + " from "
+ this.toString());
_log.warn(_prefix + "Received best effort failure after " + getElapsed() + " from "
+ toString());
rv = false;
break;
case MessageStatusMessage.STATUS_SEND_GUARANTEED_FAILURE:
if (_log.shouldLog(Log.WARN))
_log.warn("Received guaranteed failure after " + getElapsed() + " from "
+ this.toString());
_log.warn(_prefix + "Received guaranteed failure after " + getElapsed() + " from "
+ toString());
rv = false;
break;
case MessageStatusMessage.STATUS_SEND_ACCEPTED:
@@ -155,35 +161,36 @@ class MessageState {
return true; // if we're only looking for accepted, take it directly (don't let any GUARANTEED_* override it)
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Got accepted, but we're waiting for more from "
+ this.toString());
_log.debug(_prefix + "Got accepted, but we're waiting for more from "
+ toString());
continue;
// ignore accepted, as we want something better
}
case MessageStatusMessage.STATUS_SEND_BEST_EFFORT_SUCCESS:
if (_log.shouldLog(Log.DEBUG))
_log.debug("Received best effort success after " + getElapsed()
+ " from " + this.toString());
_log.debug(_prefix + "Received best effort success after " + getElapsed()
+ " from " + toString());
if (wantedStatus == recv) {
rv = true;
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Not guaranteed success, but best effort after "
+ getElapsed() + " will do... from " + this.toString());
_log.debug(_prefix + "Not guaranteed success, but best effort after "
+ getElapsed() + " will do... from " + toString());
rv = true;
}
break;
case MessageStatusMessage.STATUS_SEND_GUARANTEED_SUCCESS:
if (_log.shouldLog(Log.DEBUG))
_log.debug("Received guaranteed success after " + getElapsed() + " from "
+ this.toString());
_log.debug(_prefix + "Received guaranteed success after " + getElapsed() + " from "
+ toString());
// even if we're waiting for best effort success, guaranteed is good enough
rv = true;
break;
case -1:
continue;
default:
if (_log.shouldLog(Log.DEBUG)) _log.debug("Received something else [" + recv + "]...");
if (_log.shouldLog(Log.DEBUG))
_log.debug(_prefix + "Received something else [" + recv + "]...");
}
}
return rv;
@@ -197,21 +204,22 @@ class MessageState {
}
boolean rv = false;
if (_log.shouldLog(Log.DEBUG)) _log.debug("isFailure(" + wantedStatus + "): " + received);
if (_log.shouldLog(Log.DEBUG))
_log.debug(_prefix + "isFailure(" + wantedStatus + "): " + received);
for (Iterator iter = received.iterator(); iter.hasNext();) {
Integer val = (Integer) iter.next();
int recv = val.intValue();
switch (recv) {
case MessageStatusMessage.STATUS_SEND_BEST_EFFORT_FAILURE:
if (_log.shouldLog(Log.DEBUG))
_log.warn("Received best effort failure after " + getElapsed() + " from "
+ this.toString());
_log.warn(_prefix + "Received best effort failure after " + getElapsed() + " from "
+ toString());
rv = true;
break;
case MessageStatusMessage.STATUS_SEND_GUARANTEED_FAILURE:
if (_log.shouldLog(Log.DEBUG))
_log.warn("Received guaranteed failure after " + getElapsed() + " from "
+ this.toString());
_log.warn(_prefix + "Received guaranteed failure after " + getElapsed() + " from "
+ toString());
rv = true;
break;
case MessageStatusMessage.STATUS_SEND_ACCEPTED:
@@ -219,36 +227,37 @@ class MessageState {
rv = false;
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Got accepted, but we're waiting for more from "
+ this.toString());
_log.debug(_prefix + "Got accepted, but we're waiting for more from "
+ toString());
continue;
// ignore accepted, as we want something better
}
break;
case MessageStatusMessage.STATUS_SEND_BEST_EFFORT_SUCCESS:
if (_log.shouldLog(Log.DEBUG))
_log.debug("Received best effort success after " + getElapsed()
+ " from " + this.toString());
_log.debug(_prefix + "Received best effort success after " + getElapsed()
+ " from " + toString());
if (wantedStatus == recv) {
rv = false;
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Not guaranteed success, but best effort after "
+ getElapsed() + " will do... from " + this.toString());
_log.debug(_prefix + "Not guaranteed success, but best effort after "
+ getElapsed() + " will do... from " + toString());
rv = false;
}
break;
case MessageStatusMessage.STATUS_SEND_GUARANTEED_SUCCESS:
if (_log.shouldLog(Log.DEBUG))
_log.debug("Received guaranteed success after " + getElapsed() + " from "
+ this.toString());
_log.debug(_prefix + "Received guaranteed success after " + getElapsed() + " from "
+ toString());
// even if we're waiting for best effort success, guaranteed is good enough
rv = false;
break;
case -1:
continue;
default:
if (_log.shouldLog(Log.DEBUG)) _log.debug("Received something else [" + recv + "]...");
if (_log.shouldLog(Log.DEBUG))
_log.debug(_prefix + "Received something else [" + recv + "]...");
}
}
return rv;

View File

@@ -9,10 +9,10 @@ package net.i2p.client;
*
*/
import net.i2p.I2PAppContext;
import net.i2p.data.i2cp.I2CPMessage;
import net.i2p.data.i2cp.MessageStatusMessage;
import net.i2p.data.i2cp.ReceiveMessageBeginMessage;
import net.i2p.I2PAppContext;
/**
* Handle I2CP MessageStatusMessages from the router. This currently only takes

View File

@@ -12,6 +12,7 @@ package net.i2p.client;
import java.util.HashMap;
import java.util.Map;
import net.i2p.I2PAppContext;
import net.i2p.crypto.KeyGenerator;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
@@ -25,7 +26,6 @@ import net.i2p.data.SigningPublicKey;
import net.i2p.data.i2cp.I2CPMessage;
import net.i2p.data.i2cp.RequestLeaseSetMessage;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
* Handle I2CP RequestLeaseSetMessage from the router by granting all leases

View File

@@ -9,9 +9,9 @@ package net.i2p.client;
*
*/
import net.i2p.I2PAppContext;
import net.i2p.data.i2cp.I2CPMessage;
import net.i2p.data.i2cp.SessionStatusMessage;
import net.i2p.I2PAppContext;
/**
* Handle I2CP SessionStatusMessagese from the router, updating the session as

View File

@@ -9,10 +9,10 @@ package net.i2p.client;
*
*/
import net.i2p.I2PAppContext;
import net.i2p.data.i2cp.I2CPMessage;
import net.i2p.data.i2cp.SetDateMessage;
import net.i2p.util.Clock;
import net.i2p.I2PAppContext;
/**
* Handle I2CP time messages from the router

View File

@@ -9,7 +9,6 @@ package net.i2p.client.datagram;
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import net.i2p.crypto.DSAEngine;
@@ -17,7 +16,6 @@ import net.i2p.crypto.SHA256Generator;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
import net.i2p.data.Signature;
import net.i2p.util.HexDump;
import net.i2p.util.Log;
/**

View File

@@ -7,8 +7,8 @@
*/
package net.i2p.client.naming;
import net.i2p.data.Destination;
import net.i2p.I2PAppContext;
import net.i2p.data.Destination;
/**
* A Dummy naming service that can only handle base64 destinations.

View File

@@ -12,9 +12,9 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import net.i2p.I2PAppContext;
import net.i2p.data.Destination;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
* A naming service based on the "hosts.txt" file.

View File

@@ -7,12 +7,12 @@
*/
package net.i2p.client.naming;
import java.lang.reflect.Constructor;
import net.i2p.I2PAppContext;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
import java.lang.reflect.Constructor;
/**
* Naming services create a subclass of this class.

View File

@@ -13,13 +13,13 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import net.i2p.I2PAppContext;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.data.SessionKey;
import net.i2p.util.Log;
import net.i2p.util.RandomSource;
import net.i2p.I2PAppContext;
/**
* Dummy wrapper for AES cipher operation.

View File

@@ -17,6 +17,7 @@ import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;
import net.i2p.I2PAppContext;
import net.i2p.data.Base64;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
@@ -24,7 +25,6 @@ import net.i2p.data.SessionKey;
import net.i2p.util.Clock;
import net.i2p.util.Log;
import net.i2p.util.RandomSource;
import net.i2p.I2PAppContext;
/**
* This reads an underlying stream as written by AESOutputStream - AES256 encrypted

View File

@@ -15,10 +15,10 @@ import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import net.i2p.data.SessionKey;
import net.i2p.data.DataHelper;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
import net.i2p.data.DataHelper;
import net.i2p.data.SessionKey;
import net.i2p.util.Log;
/**
* This writes everything as CBC with PKCS#5 padding, but each block is padded

View File

@@ -11,9 +11,9 @@ package net.i2p.crypto;
import java.security.InvalidKeyException;
import net.i2p.I2PAppContext;
import net.i2p.data.SessionKey;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
* Wrapper for AES cypher operation using Cryptix's Rijndael implementation. Implements

View File

@@ -13,6 +13,7 @@ import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import net.i2p.I2PAppContext;
import net.i2p.data.ByteArray;
import net.i2p.data.SessionKey;
import net.i2p.util.Clock;
@@ -20,7 +21,6 @@ import net.i2p.util.I2PThread;
import net.i2p.util.Log;
import net.i2p.util.NativeBigInteger;
import net.i2p.util.RandomSource;
import net.i2p.I2PAppContext;
/**
* Generate a new session key through a diffie hellman exchange. This uses the

View File

@@ -31,15 +31,13 @@ package net.i2p.crypto;
import java.math.BigInteger;
import net.i2p.I2PAppContext;
import net.i2p.data.Hash;
import net.i2p.data.Signature;
import net.i2p.data.SigningPrivateKey;
import net.i2p.data.SigningPublicKey;
import net.i2p.util.Clock;
import net.i2p.util.Log;
import net.i2p.util.NativeBigInteger;
import net.i2p.util.RandomSource;
import net.i2p.I2PAppContext;
public class DSAEngine {
private Log _log;

View File

@@ -12,12 +12,12 @@ package net.i2p.crypto;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import net.i2p.I2PAppContext;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.data.PrivateKey;
import net.i2p.data.PublicKey;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
* Fake ElG E and D, useful for when performance isn't being tested

View File

@@ -18,6 +18,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
import net.i2p.I2PAppContext;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
@@ -25,11 +26,7 @@ import net.i2p.data.PrivateKey;
import net.i2p.data.PublicKey;
import net.i2p.data.SessionKey;
import net.i2p.data.SessionTag;
import net.i2p.stat.StatManager;
import net.i2p.util.Clock;
import net.i2p.util.Log;
import net.i2p.util.RandomSource;
import net.i2p.I2PAppContext;
/**
* Handles the actual ElGamal+AES encryption and decryption scenarios using the

View File

@@ -33,17 +33,16 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.math.BigInteger;
import net.i2p.I2PAppContext;
import net.i2p.data.Base64;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.data.PrivateKey;
import net.i2p.data.PublicKey;
import net.i2p.stat.StatManager;
import net.i2p.util.Clock;
import net.i2p.util.Log;
import net.i2p.util.NativeBigInteger;
import net.i2p.util.RandomSource;
import net.i2p.I2PAppContext;
/**
* Wrapper for ElGamal encryption/signature schemes.

View File

@@ -1,9 +1,9 @@
package net.i2p.crypto;
import net.i2p.I2PAppContext;
import net.i2p.data.DataHelper;
import net.i2p.data.Hash;
import net.i2p.data.SessionKey;
import net.i2p.I2PAppContext;
/**
* Calculate the HMAC-SHA256 of a key+message. Currently FAKE - returns a stupid

View File

@@ -11,6 +11,7 @@ package net.i2p.crypto;
import java.math.BigInteger;
import net.i2p.I2PAppContext;
import net.i2p.data.DataHelper;
import net.i2p.data.PrivateKey;
import net.i2p.data.PublicKey;
@@ -22,7 +23,6 @@ import net.i2p.util.Clock;
import net.i2p.util.Log;
import net.i2p.util.NativeBigInteger;
import net.i2p.util.RandomSource;
import net.i2p.I2PAppContext;
/** Define a way of generating asymetrical key pairs as well as symetrical keys
* @author jrandom

View File

@@ -21,13 +21,13 @@ import java.util.Iterator;
import java.util.List;
import java.util.Set;
import net.i2p.I2PAppContext;
import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.PublicKey;
import net.i2p.data.SessionKey;
import net.i2p.data.SessionTag;
import net.i2p.util.Log;
import net.i2p.I2PAppContext;
/**
* Expose the functionality to allow people to write out and read in the

View File

@@ -29,8 +29,8 @@ package net.i2p.crypto;
* POSSIBILITY OF SUCH DAMAGE.
*/
import net.i2p.data.Hash;
import net.i2p.I2PAppContext;
import net.i2p.data.Hash;
/** Defines a wrapper for SHA-256 operation
*

View File

@@ -11,10 +11,10 @@ package net.i2p.crypto;
import java.util.Set;
import net.i2p.I2PAppContext;
import net.i2p.data.PublicKey;
import net.i2p.data.SessionKey;
import net.i2p.data.SessionTag;
import net.i2p.I2PAppContext;
/**
* Manage the session keys and session tags used for encryption and decryption.

View File

@@ -13,12 +13,12 @@ import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import net.i2p.I2PAppContext;
import net.i2p.util.Clock;
import net.i2p.util.I2PThread;
import net.i2p.util.Log;
import net.i2p.util.NativeBigInteger;
import net.i2p.util.RandomSource;
import net.i2p.I2PAppContext;
/**
* Precalculate the Y and K for ElGamal encryption operations.

View File

@@ -26,7 +26,6 @@ import java.util.TreeMap;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import net.i2p.util.Log;
import net.i2p.util.OrderedProperties;
/**

View File

@@ -69,10 +69,10 @@ public class PrivateKey extends DataStructureImpl {
buf.append("null key");
} else {
buf.append("size: ").append(_data.length);
int len = 32;
if (len > _data.length) len = _data.length;
buf.append(" first ").append(len).append(" bytes: ");
buf.append(DataHelper.toString(_data, len));
//int len = 32;
//if (len > _data.length) len = _data.length;
//buf.append(" first ").append(len).append(" bytes: ");
//buf.append(DataHelper.toString(_data, len));
}
buf.append("]");
return buf.toString();

View File

@@ -68,10 +68,10 @@ public class PublicKey extends DataStructureImpl {
buf.append("null key");
} else {
buf.append("size: ").append(_data.length);
int len = 32;
if (len > _data.length) len = _data.length;
buf.append(" first ").append(len).append(" bytes: ");
buf.append(DataHelper.toString(_data, len));
//int len = 32;
//if (len > _data.length) len = _data.length;
//buf.append(" first ").append(len).append(" bytes: ");
//buf.append(DataHelper.toString(_data, len));
}
buf.append("]");
return buf.toString();

View File

@@ -422,7 +422,7 @@ public class RouterInfo extends DataStructureImpl {
public String toString() {
if (_stringified != null) return _stringified;
StringBuffer buf = new StringBuffer(128);
StringBuffer buf = new StringBuffer(5*1024);
buf.append("[RouterInfo: ");
buf.append("\n\tIdentity: ").append(getIdentity());
buf.append("\n\tSignature: ").append(getSignature());

View File

@@ -15,11 +15,10 @@ import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import net.i2p.I2PAppContext;
import net.i2p.crypto.SHA256Generator;
import net.i2p.util.Clock;
import net.i2p.util.Log;
import net.i2p.util.RandomSource;
import net.i2p.I2PAppContext;
/**
* Component to manage the munging of hashes into routing keys - given a hash,

View File

@@ -67,10 +67,10 @@ public class SessionKey extends DataStructureImpl {
buf.append("null key");
} else {
buf.append("size: ").append(_data.length);
int len = 32;
if (len > _data.length) len = _data.length;
buf.append(" first ").append(len).append(" bytes: ");
buf.append(DataHelper.toString(_data, len));
//int len = 32;
//if (len > _data.length) len = _data.length;
//buf.append(" first ").append(len).append(" bytes: ");
//buf.append(DataHelper.toString(_data, len));
}
buf.append("]");
return buf.toString();

Some files were not shown because too many files have changed in this diff Show More