use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class I2PSocketManagerFull method addSubsession.
/**
* For a server, you must call connect() on the returned object.
* Connecting the primary session does NOT connect any subsessions.
* If the primary session is not connected, connecting a subsession will connect the primary session first.
*
* @return a new subsession, non-null
* @param privateKeyStream null for transient, if non-null must have same encryption keys as primary session
* and different signing keys
* @param opts subsession options if any, may be null
* @since 0.9.21
*/
public I2PSession addSubsession(InputStream privateKeyStream, Properties opts) throws I2PSessionException {
if (privateKeyStream == null) {
// We don't actually need the same pubkey in the dest, just in the LS.
// The dest one is unused. But this is how we find the LS keys
// to reuse in RequestLeaseSetMessageHandler.
ByteArrayOutputStream keyStream = new ByteArrayOutputStream(1024);
try {
SigType type = getSigType(opts);
if (type != SigType.DSA_SHA1) {
// hassle, have to set up the padding and cert, see I2PClientImpl
throw new I2PSessionException("type " + type + " unsupported");
}
PublicKey pub = _session.getMyDestination().getPublicKey();
PrivateKey priv = _session.getDecryptionKey();
SimpleDataStructure[] keys = _context.keyGenerator().generateSigningKeys(type);
pub.writeBytes(keyStream);
// signing pub
keys[0].writeBytes(keyStream);
Certificate.NULL_CERT.writeBytes(keyStream);
priv.writeBytes(keyStream);
// signing priv
keys[1].writeBytes(keyStream);
} catch (GeneralSecurityException e) {
throw new I2PSessionException("Error creating keys", e);
} catch (I2PException e) {
throw new I2PSessionException("Error creating keys", e);
} catch (IOException e) {
throw new I2PSessionException("Error creating keys", e);
} catch (RuntimeException e) {
throw new I2PSessionException("Error creating keys", e);
}
privateKeyStream = new ByteArrayInputStream(keyStream.toByteArray());
}
I2PSession rv = _session.addSubsession(privateKeyStream, opts);
boolean added = _subsessions.add(rv);
if (!added) {
// shouldn't happen
_session.removeSubsession(rv);
throw new I2PSessionException("dup");
}
ConnectionOptions defaultOptions = new ConnectionOptions(opts);
int protocol = defaultOptions.getEnforceProtocol() ? I2PSession.PROTO_STREAMING : I2PSession.PROTO_ANY;
rv.addMuxedSessionListener(_connectionManager.getMessageHandler(), protocol, defaultOptions.getLocalPort());
if (_log.shouldLog(Log.WARN))
_log.warn("Added subsession " + rv);
return rv;
}
use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class SAMv1Handler method execSessionMessage.
/* Parse and execute a SESSION message */
protected boolean execSessionMessage(String opcode, Properties props) {
String dest = "BUG!";
try {
if (opcode.equals("CREATE")) {
if ((rawSession != null) || (datagramSession != null) || (streamSession != null)) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Trying to create a session, but one still exists");
return writeString(SESSION_ERROR, "Session already exists");
}
if (props.isEmpty()) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("No parameters specified in SESSION CREATE message");
return writeString(SESSION_ERROR, "No parameters for SESSION CREATE");
}
dest = (String) props.remove("DESTINATION");
if (dest == null) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("SESSION DESTINATION parameter not specified");
return writeString(SESSION_ERROR, "DESTINATION not specified");
}
String destKeystream = null;
if (dest.equals("TRANSIENT")) {
_log.debug("TRANSIENT destination requested");
ByteArrayOutputStream priv = new ByteArrayOutputStream(640);
SAMUtils.genRandomKey(priv, null);
destKeystream = Base64.encode(priv.toByteArray());
} else {
destKeystream = bridge.getKeystream(dest);
if (destKeystream == null) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Custom destination specified [" + dest + "] but it isn't known, creating a new one");
ByteArrayOutputStream baos = new ByteArrayOutputStream(640);
SAMUtils.genRandomKey(baos, null);
destKeystream = Base64.encode(baos.toByteArray());
bridge.addKeystream(dest, destKeystream);
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Custom destination specified [" + dest + "] and it is already known");
}
}
String style = (String) props.remove("STYLE");
if (style == null) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("SESSION STYLE parameter not specified");
return writeString(SESSION_ERROR, "No SESSION STYLE specified");
}
// Unconditionally override what the client may have set
// (iMule sets BestEffort) as None is more efficient
// and the client has no way to access delivery notifications
props.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_NONE);
if (style.equals("RAW")) {
rawSession = new SAMRawSession(destKeystream, props, this);
rawSession.start();
} else if (style.equals("DATAGRAM")) {
datagramSession = new SAMDatagramSession(destKeystream, props, this);
datagramSession.start();
} else if (style.equals("STREAM")) {
String dir = (String) props.remove("DIRECTION");
if (dir == null) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("No DIRECTION parameter in STREAM session, defaulting to BOTH");
dir = "BOTH";
} else if (!dir.equals("CREATE") && !dir.equals("RECEIVE") && !dir.equals("BOTH")) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Unknown DIRECTION parameter value: [" + dir + "]");
return writeString(SESSION_ERROR, "Unknown DIRECTION parameter");
}
streamSession = newSAMStreamSession(destKeystream, dir, props);
streamSession.start();
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Unrecognized SESSION STYLE: \"" + style + "\"");
return writeString(SESSION_ERROR, "Unrecognized SESSION STYLE");
}
return writeString("SESSION STATUS RESULT=OK DESTINATION=" + dest + "\n");
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Unrecognized SESSION message opcode: \"" + opcode + "\"");
return writeString(SESSION_ERROR, "Unrecognized opcode");
}
} catch (DataFormatException e) {
_log.error("Invalid SAM destination specified", e);
return writeString("SESSION STATUS RESULT=INVALID_KEY", e.getMessage());
} catch (I2PSessionException e) {
_log.error("Failed to start SAM session", e);
return writeString(SESSION_ERROR, e.getMessage());
} catch (SAMException e) {
_log.error("Failed to start SAM session", e);
return writeString(SESSION_ERROR, e.getMessage());
} catch (IOException e) {
_log.error("Failed to start SAM session", e);
return writeString(SESSION_ERROR, e.getMessage());
}
}
use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class I2PTunnelServer method connectManager.
/**
* Warning, blocks while connecting to router and building tunnels;
*
* @throws IllegalArgumentException if the I2CP configuration is b0rked so
* badly that we cant create a socketManager
* @since 0.9.8
*/
private void connectManager() {
int retries = 0;
while (sockMgr.getSession().isClosed()) {
try {
sockMgr.getSession().connect();
// Now connect the subsessions, if any
List<I2PSession> subs = sockMgr.getSubsessions();
if (!subs.isEmpty()) {
for (I2PSession sub : subs) {
try {
sub.connect();
if (_log.shouldInfo())
_log.info("Connected subsession " + sub);
} catch (I2PSessionException ise) {
// not fatal?
String msg = "Unable to connect subsession " + sub;
this.l.log(msg);
_log.error(msg, ise);
}
}
}
} catch (I2PSessionException ise) {
// try to make this error sensible as it will happen...
String portNum = getTunnel().port;
if (portNum == null)
portNum = "7654";
String msg;
if (getTunnel().getContext().isRouterContext())
msg = "Unable to build tunnels for the server at " + remoteHost.getHostAddress() + ':' + remotePort;
else
msg = "Unable to connect to the router at " + getTunnel().host + ':' + portNum + " and build tunnels for the server at " + remoteHost.getHostAddress() + ':' + remotePort;
if (++retries < MAX_RETRIES) {
msg += ", retrying in " + (RETRY_DELAY / 1000) + " seconds";
this.l.log(msg);
_log.error(msg);
} else {
msg += ", giving up";
this.l.log(msg);
_log.log(Log.CRIT, msg, ise);
throw new IllegalArgumentException(msg, ise);
}
try {
Thread.sleep(RETRY_DELAY);
} catch (InterruptedException ie) {
}
}
}
l.log("Tunnels ready for server at " + remoteHost.getHostAddress() + ':' + remotePort);
notifyEvent("openServerResult", "ok");
open = true;
}
use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class I2PTunnelServer method createManager.
/**
* @throws IllegalArgumentException if the I2CP configuration is b0rked so
* badly that we cant create a socketManager
* @since 0.9.8
*/
private I2PSocketManager createManager(InputStream privData) {
Properties props = new Properties();
props.putAll(getTunnel().getClientOptions());
int portNum = 7654;
if (getTunnel().port != null) {
try {
portNum = Integer.parseInt(getTunnel().port);
} catch (NumberFormatException nfe) {
_log.error("Invalid port specified [" + getTunnel().port + "], reverting to " + portNum);
}
}
try {
I2PSocketManager rv = I2PSocketManagerFactory.createDisconnectedManager(privData, getTunnel().host, portNum, props);
rv.setName("I2PTunnel Server");
getTunnel().addSession(rv.getSession());
String alt = props.getProperty(PROP_ALT_PKF);
if (alt != null)
addSubsession(rv, alt);
return rv;
} catch (I2PSessionException ise) {
throw new IllegalArgumentException("Can't create socket manager", ise);
} finally {
try {
privData.close();
} catch (IOException ioe) {
}
}
}
use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class KRPC method sendMessage.
/**
* Lowest-level send message call.
* @param repliable true for all but announce
* @return success
*/
private boolean sendMessage(Destination dest, int toPort, Map<String, Object> map, boolean repliable) {
if (_session.isClosed()) {
// Don't allow DHT to open a closed session
if (_log.shouldLog(Log.WARN))
_log.warn("Not sending message, session is closed");
return false;
}
if (dest.calculateHash().equals(_myNodeInfo.getHash()))
throw new IllegalArgumentException("don't send to ourselves");
byte[] payload = BEncoder.bencode(map);
if (_log.shouldLog(Log.DEBUG)) {
ByteArrayInputStream bais = new ByteArrayInputStream(payload);
try {
_log.debug("Sending to: " + dest.calculateHash() + ' ' + BDecoder.bdecode(bais).toString());
} catch (IOException ioe) {
}
}
// Always send query port, peer will increment for unsigned replies
int fromPort = _qPort;
if (repliable) {
I2PDatagramMaker dgMaker = new I2PDatagramMaker(_session);
payload = dgMaker.makeI2PDatagram(payload);
if (payload == null) {
if (_log.shouldLog(Log.WARN))
_log.warn("DGM fail");
return false;
}
}
SendMessageOptions opts = new SendMessageOptions();
opts.setDate(_context.clock().now() + 60 * 1000);
opts.setTagsToSend(SEND_CRYPTO_TAGS);
opts.setTagThreshold(LOW_CRYPTO_TAGS);
if (!repliable)
opts.setSendLeaseSet(false);
try {
boolean success = _session.sendMessage(dest, payload, 0, payload.length, repliable ? I2PSession.PROTO_DATAGRAM : I2PSession.PROTO_DATAGRAM_RAW, fromPort, toPort, opts);
if (success) {
_txPkts.incrementAndGet();
_txBytes.addAndGet(payload.length);
} else {
if (_log.shouldLog(Log.WARN))
_log.warn("sendMessage fail");
}
return success;
} catch (I2PSessionException ise) {
if (_log.shouldLog(Log.WARN))
_log.warn("sendMessage fail", ise);
return false;
}
}
Aggregations