use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class I2PSocketManagerFactory method createDisconnectedManager.
/**
* Create a disconnected socket manager using the destination loaded from the given private key
* stream, or null for a transient destination.
*
* Non-blocking. Does not connect to the router or build tunnels.
* For servers, caller MUST call getSession().connect() to build tunnels and start listening.
* For clients, caller may do that to build tunnels in advance;
* otherwise, the first call to connect() will initiate a connection to the router,
* with significant delay for tunnel building.
*
* @param myPrivateKeyStream private key stream, format is specified in {@link net.i2p.data.PrivateKeyFile PrivateKeyFile}
* or null for a transient destination. Caller must close.
* @param i2cpHost I2CP host null to use default, ignored if in router context
* @param i2cpPort I2CP port <= 0 to use default, ignored if in router context
* @param opts Streaming and I2CP options, may be null
* @return the newly created socket manager, non-null (throws on error)
* @since 0.9.8
*/
public static I2PSocketManager createDisconnectedManager(InputStream myPrivateKeyStream, String i2cpHost, int i2cpPort, Properties opts) throws I2PSessionException {
if (myPrivateKeyStream == null) {
I2PClient client = I2PClientFactory.createClient();
ByteArrayOutputStream keyStream = new ByteArrayOutputStream(1024);
try {
client.createDestination(keyStream, getSigType(opts));
} catch (I2PException e) {
throw new I2PSessionException("Error creating keys", e);
} catch (IOException e) {
throw new I2PSessionException("Error creating keys", e);
}
myPrivateKeyStream = new ByteArrayInputStream(keyStream.toByteArray());
}
return createManager(myPrivateKeyStream, i2cpHost, i2cpPort, opts, false);
}
use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class I2PTunnelUDPServerBase method init.
private void init(boolean verify, InputStream privData, String privkeyname, Logging l) {
this.l = l;
// create i2pclient
I2PClient client = I2PClientFactory.createClient();
try {
// FIXME this may not pick up non-default I2CP host/port settings from tunnel
_session = client.createSession(privData, getTunnel().getClientOptions());
connected(_session);
} catch (I2PSessionException exc) {
throw new RuntimeException("failed to create session", exc);
}
// Setup the source. Always expect repliable datagrams, optionally verify
_i2pSource = new I2PSource(_session, verify, false);
// Setup the sink. Always send raw datagrams.
_i2pSink = new I2PSinkAnywhere(_session, true);
}
use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class I2PSocketManagerFull method destroySocketManager.
/**
* Destroy the socket manager, freeing all the associated resources. This
* method will block until all the managed sockets are closed.
*
* CANNOT be restarted.
*/
public void destroySocketManager() {
if (!_isDestroyed.compareAndSet(false, true)) {
// shouldn't happen, log a stack trace to find out why it happened
_log.logCloseLoop("I2PSocketManager", getName());
return;
}
_connectionManager.setAllowIncomingConnections(false);
_connectionManager.shutdown();
if (!_subsessions.isEmpty()) {
for (I2PSession sess : _subsessions) {
removeSubsession(sess);
}
}
// yes, since the old lib did (and SAM wants it to, and i dont know why not)
if ((_session != null) && (!_session.isClosed())) {
try {
_session.destroySession();
} catch (I2PSessionException ise) {
_log.warn("Unable to destroy the session", ise);
}
PcapWriter pcap = null;
synchronized (_pcapInitLock) {
pcap = pcapWriter;
}
if (pcap != null)
pcap.flush();
}
}
use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class PacketQueue method enqueue.
/**
* Add a new packet to be sent out ASAP.
* This updates the acks.
*
* keys and tags disabled since dropped in I2PSession
* @return true if sent
*/
public boolean enqueue(PacketLocal packet) {
if (_dead)
return false;
if (packet.getAckTime() > 0) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Not resending " + packet);
return false;
}
Connection con = packet.getConnection();
if (con != null) {
// this updates the ack/nack fields
con.getInputStream().updateAcks(packet);
}
ByteArray ba = _cache.acquire();
byte[] buf = ba.getData();
long begin = 0;
long end = 0;
boolean sent = false;
try {
int size = 0;
// long beforeWrite = System.currentTimeMillis();
if (packet.shouldSign())
size = packet.writeSignedPacket(buf, 0);
else
size = packet.writePacket(buf, 0);
// last chance to short circuit...
if (packet.getAckTime() > 0)
return false;
// this should not block!
begin = _context.clock().now();
long expires = 0;
Connection.ResendPacketEvent rpe = (Connection.ResendPacketEvent) packet.getResendEvent();
if (rpe != null)
// we want the router to expire it a little before we do,
// so if we retransmit it will use a new tunnel/lease combo
expires = rpe.getNextSendTime() - 500;
SendMessageOptions options = new SendMessageOptions();
if (expires > 0)
options.setDate(expires);
boolean listenForStatus = false;
// FINAL trumps INITIAL, in the case of SYN+CLOSE
if (packet.isFlagSet(FLAGS_FINAL_TAGS)) {
if (packet.isFlagSet(Packet.FLAG_ECHO)) {
// Send LS for PING, not for PONG
if (// pong
packet.getSendStreamId() <= 0)
options.setSendLeaseSet(false);
} else {
options.setSendLeaseSet(false);
}
int sendTags = FINAL_TAGS_TO_SEND;
int tagThresh = FINAL_TAG_THRESHOLD;
if (con != null) {
ConnectionOptions copts = con.getOptions();
int cSendTags = copts.getTagsToSend();
int cTagThresh = copts.getTagThreshold();
if (cSendTags < sendTags)
sendTags = cSendTags;
if (cTagThresh < tagThresh)
tagThresh = cTagThresh;
}
options.setTagsToSend(sendTags);
options.setTagThreshold(tagThresh);
} else if (packet.isFlagSet(FLAGS_INITIAL_TAGS)) {
if (con != null) {
if (con.isInbound())
options.setSendLeaseSet(false);
else if (ENABLE_STATUS_LISTEN)
listenForStatus = true;
}
int sendTags = INITIAL_TAGS_TO_SEND;
int tagThresh = MIN_TAG_THRESHOLD;
if (con != null) {
ConnectionOptions copts = con.getOptions();
int cSendTags = copts.getTagsToSend();
int cTagThresh = copts.getTagThreshold();
if (cSendTags < sendTags)
sendTags = cSendTags;
if (cTagThresh < tagThresh)
tagThresh = cTagThresh;
}
options.setTagsToSend(sendTags);
options.setTagThreshold(tagThresh);
} else {
if (con != null) {
if (con.isInbound() && con.getLifetime() < 2 * 60 * 1000)
options.setSendLeaseSet(false);
// increase threshold with higher window sizes to prevent stalls
// after tag delivery failure
ConnectionOptions copts = con.getOptions();
int wdw = copts.getWindowSize();
int thresh = Math.max(MIN_TAG_THRESHOLD, wdw * TAG_WINDOW_FACTOR);
int cTagThresh = copts.getTagThreshold();
if (cTagThresh < thresh)
thresh = cTagThresh;
options.setTagThreshold(thresh);
}
}
I2PSession session = packet.getSession();
if (listenForStatus) {
long id = session.sendMessage(packet.getTo(), buf, 0, size, I2PSession.PROTO_STREAMING, packet.getLocalPort(), packet.getRemotePort(), options, this);
_messageStatusMap.put(Long.valueOf(id), con);
sent = true;
} else {
sent = session.sendMessage(packet.getTo(), buf, 0, size, I2PSession.PROTO_STREAMING, packet.getLocalPort(), packet.getRemotePort(), options);
}
end = _context.clock().now();
if ((end - begin > 1000) && (_log.shouldLog(Log.WARN)))
_log.warn("Took " + (end - begin) + "ms to sendMessage(...) " + packet);
_context.statManager().addRateData("stream.con.sendMessageSize", size, packet.getLifetime());
if (packet.getNumSends() > 1)
_context.statManager().addRateData("stream.con.sendDuplicateSize", size, packet.getLifetime());
if (con != null) {
con.incrementBytesSent(size);
if (packet.getNumSends() > 1)
con.incrementDupMessagesSent(1);
}
} catch (I2PSessionException ise) {
if (_log.shouldLog(Log.WARN))
_log.warn("Unable to send the packet " + packet, ise);
}
_cache.release(ba);
if (!sent) {
if (_log.shouldLog(Log.WARN))
_log.warn("Send failed for " + packet);
if (// handle race on b0rk
con != null)
con.disconnect(false);
} else {
// packet.setKeyUsed(keyUsed);
// packet.setTagsSent(tagsSent);
packet.incrementSends();
if (con != null && _log.shouldDebug()) {
String suffix = "wsize " + con.getOptions().getWindowSize() + " rto " + con.getOptions().getRTO();
con.getConnectionManager().getPacketHandler().displayPacket(packet, "SEND", suffix);
}
if (I2PSocketManagerFull.pcapWriter != null && _context.getBooleanProperty(I2PSocketManagerFull.PROP_PCAP))
packet.logTCPDump();
}
if ((packet.getSequenceNum() == 0) && (!packet.isFlagSet(Packet.FLAG_SYNCHRONIZE))) {
// ack only, so release it asap
packet.releasePayload();
} else if (packet.isFlagSet(Packet.FLAG_ECHO) && !packet.isFlagSet(Packet.FLAG_SIGNATURE_INCLUDED)) {
// pong
packet.releasePayload();
} else if (packet.isFlagSet(Packet.FLAG_RESET)) {
// reset
packet.releasePayload();
}
return sent;
}
use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class I2PTunnel method destFromName.
/**
* @param i2cpHost may be null
* @param i2cpPort may be null
* @param user may be null
* @param pw may be null
* @since 0.9.11
*/
private static Destination destFromName(String name, String i2cpHost, String i2cpPort, boolean isSSL, String user, String pw) throws DataFormatException {
if ((name == null) || (name.trim().length() <= 0))
throw new DataFormatException("Empty destination provided");
I2PAppContext ctx = I2PAppContext.getGlobalContext();
Log log = ctx.logManager().getLog(I2PTunnel.class);
if (name.startsWith("file:")) {
Destination result = new Destination();
byte[] content = null;
FileInputStream in = null;
try {
in = new FileInputStream(name.substring("file:".length()));
byte[] buf = new byte[1024];
int read = DataHelper.read(in, buf);
content = new byte[read];
System.arraycopy(buf, 0, content, 0, read);
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
return null;
} finally {
if (in != null)
try {
in.close();
} catch (IOException io) {
}
}
try {
result.fromByteArray(content);
return result;
} catch (RuntimeException ex) {
if (log.shouldLog(Log.INFO))
log.info("File is not a binary destination - trying base64");
try {
byte[] decoded = Base64.decode(new String(content));
result.fromByteArray(decoded);
return result;
} catch (DataFormatException dfe) {
if (log.shouldLog(Log.WARN))
log.warn("File is not a base64 destination either - failing!");
return null;
}
}
} else {
// ask naming service
name = name.trim();
NamingService inst = ctx.namingService();
boolean b32 = name.length() == 60 && name.toLowerCase(Locale.US).endsWith(".b32.i2p");
Destination d = null;
if (ctx.isRouterContext() || !b32) {
// Local lookup.
// Even though we could do b32 outside router ctx here,
// we do it below instead so we can set the host and port,
// which we can't do with lookup()
d = inst.lookup(name);
if (d != null || ctx.isRouterContext() || name.length() >= 516)
return d;
}
// Outside router context only,
// try simple session to ask the router.
I2PClient client = new I2PSimpleClient();
Properties opts = new Properties();
if (i2cpHost != null)
opts.put(I2PClient.PROP_TCP_HOST, i2cpHost);
if (i2cpPort != null)
opts.put(I2PClient.PROP_TCP_PORT, i2cpPort);
opts.put("i2cp.SSL", Boolean.toString(isSSL));
if (user != null)
opts.put("i2cp.username", user);
if (pw != null)
opts.put("i2cp.password", pw);
I2PSession session = null;
try {
session = client.createSession(null, opts);
session.connect();
d = session.lookupDest(name);
} catch (I2PSessionException ise) {
if (log.shouldLog(Log.WARN))
log.warn("Lookup via router failed", ise);
} finally {
if (session != null) {
try {
session.destroySession();
} catch (I2PSessionException ise) {
}
}
}
return d;
}
}
Aggregations