use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class SAMv3Handler method execSessionMessage.
/* Parse and execute a SESSION message */
@Override
protected boolean execSessionMessage(String opcode, Properties props) {
String dest = "BUG!";
boolean ok = false;
String nick = (String) props.remove("ID");
if (nick == null)
return writeString(SESSION_ERROR, "ID not specified");
String style = (String) props.remove("STYLE");
if (style == null && !opcode.equals("REMOVE"))
return writeString(SESSION_ERROR, "No SESSION STYLE specified");
try {
if (opcode.equals("CREATE")) {
if ((this.getRawSession() != null) || (this.getDatagramSession() != null) || (this.getStreamSession() != 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");
}
if (dest.equals("TRANSIENT")) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("TRANSIENT destination requested");
String sigTypeStr = (String) props.remove("SIGNATURE_TYPE");
SigType sigType;
if (sigTypeStr != null) {
sigType = SigType.parseSigType(sigTypeStr);
if (sigType == null) {
return writeString(SESSION_ERROR, "SIGNATURE_TYPE " + sigTypeStr + " unsupported");
}
} else {
sigType = SigType.DSA_SHA1;
}
ByteArrayOutputStream priv = new ByteArrayOutputStream(663);
SAMUtils.genRandomKey(priv, null, sigType);
dest = Base64.encode(priv.toByteArray());
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Custom destination specified [" + dest + "]");
if (!SAMUtils.checkPrivateDestination(dest))
return writeString("SESSION STATUS RESULT=INVALID_KEY\n");
}
// 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
i2cpProps.setProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_NONE);
i2cpProps.setProperty("i2cp.fastReceive", "true");
// Record the session in the database sSessionsHash
Properties allProps = new Properties();
allProps.putAll(i2cpProps);
allProps.putAll(props);
if (style.equals("MASTER")) {
// We must put these here, as SessionRecord.getProps() makes a copy,
// and the socket manager is instantiated in the
// SAMStreamSession constructor.
allProps.setProperty("i2p.streaming.enforceProtocol", "true");
allProps.setProperty("i2cp.dontPublishLeaseSet", "false");
}
try {
sSessionsHash.put(nick, new SessionRecord(dest, allProps, this));
} catch (SessionsDB.ExistingIdException e) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("SESSION ID parameter already in use");
return writeString("SESSION STATUS RESULT=DUPLICATED_ID\n");
} catch (SessionsDB.ExistingDestException e) {
return writeString("SESSION STATUS RESULT=DUPLICATED_DEST\n");
}
if (style.equals("RAW")) {
SAMv3DatagramServer dgs = bridge.getV3DatagramServer(props);
SAMv3RawSession v3 = new SAMv3RawSession(nick, dgs);
rawSession = v3;
this.session = v3;
v3.start();
} else if (style.equals("DATAGRAM")) {
SAMv3DatagramServer dgs = bridge.getV3DatagramServer(props);
SAMv3DatagramSession v3 = new SAMv3DatagramSession(nick, dgs);
datagramSession = v3;
this.session = v3;
v3.start();
} else if (style.equals("STREAM")) {
SAMv3StreamSession v3 = newSAMStreamSession(nick);
streamSession = v3;
this.session = v3;
v3.start();
} else if (style.equals("MASTER")) {
SAMv3DatagramServer dgs = bridge.getV3DatagramServer(props);
MasterSession v3 = new MasterSession(nick, dgs, this, allProps);
streamSession = v3;
datagramSession = v3;
rawSession = v3;
this.session = v3;
v3.start();
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Unrecognized SESSION STYLE: \"" + style + "\"");
return writeString(SESSION_ERROR, "Unrecognized SESSION STYLE");
}
ok = true;
return writeString("SESSION STATUS RESULT=OK DESTINATION=" + dest + "\n");
} else if (opcode.equals("ADD") || opcode.equals("REMOVE")) {
// prevent trouble in finally block
ok = true;
if (streamSession == null || datagramSession == null || rawSession == null)
return writeString(SESSION_ERROR, "Not a MASTER session");
MasterSession msess = (MasterSession) session;
String msg;
if (opcode.equals("ADD")) {
msg = msess.add(nick, style, props);
} else {
msg = msess.remove(nick, props);
}
if (msg == null)
return writeString("SESSION STATUS RESULT=OK ID=\"" + nick + '"', opcode + ' ' + nick);
else
return writeString(SESSION_ERROR + " ID=\"" + nick + '"', msg);
} 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());
} finally {
// unregister the session if it has not been created
if (!ok && nick != null) {
sSessionsHash.del(nick);
session = null;
}
}
}
use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class MasterSession method add.
/**
* Add a session
* @return null for success, or error message
*/
public synchronized String add(String nick, String style, Properties props) {
if (props.containsKey("DESTINATION"))
return "SESSION ADD may not contain DESTINATION";
SessionRecord rec = SAMv3Handler.sSessionsHash.get(nick);
if (rec != null || sessions.containsKey(nick))
return "Duplicate ID " + nick;
int listenPort = I2PSession.PORT_ANY;
String slp = (String) props.remove("LISTEN_PORT");
if (slp == null)
slp = props.getProperty("FROM_PORT");
if (slp != null) {
try {
listenPort = Integer.parseInt(slp);
if (listenPort < 0 || listenPort > 65535)
return "Bad LISTEN_PORT " + slp;
// TODO enforce streaming listen port must be 0 or from port
} catch (NumberFormatException nfe) {
return "Bad LISTEN_PORT " + slp;
}
}
int listenProtocol;
SAMMessageSess sess;
SAMv3Handler subhandler;
try {
I2PSession isess = socketMgr.getSession();
subhandler = new SAMv3Handler(handler.getClientSocket(), handler.verMajor, handler.verMinor, handler.getBridge());
if (style.equals("RAW")) {
if (!props.containsKey("PORT"))
return "RAW subsession must specify PORT";
listenProtocol = I2PSession.PROTO_DATAGRAM_RAW;
String spr = (String) props.remove("LISTEN_PROTOCOL");
if (spr == null)
spr = props.getProperty("PROTOCOL");
if (spr != null) {
try {
listenProtocol = Integer.parseInt(spr);
// RAW can't listen on streaming protocol
if (listenProtocol < 0 || listenProtocol > 255 || listenProtocol == I2PSession.PROTO_STREAMING)
return "Bad RAW LISTEN_PPROTOCOL " + spr;
} catch (NumberFormatException nfe) {
return "Bad LISTEN_PROTOCOL " + spr;
}
}
SAMv3RawSession ssess = new SAMv3RawSession(nick, props, handler, isess, listenProtocol, listenPort, dgs);
subhandler.setSession(ssess);
sess = ssess;
} else if (style.equals("DATAGRAM")) {
if (!props.containsKey("PORT"))
return "DATAGRAM subsession must specify PORT";
listenProtocol = I2PSession.PROTO_DATAGRAM;
SAMv3DatagramSession ssess = new SAMv3DatagramSession(nick, props, handler, isess, listenPort, dgs);
subhandler.setSession(ssess);
sess = ssess;
} else if (style.equals("STREAM")) {
listenProtocol = I2PSession.PROTO_STREAMING;
// FIXME need something that hangs off an existing dest
SAMv3StreamSession ssess = new SAMv3StreamSession(nick, props, handler, socketMgr, listenPort);
subhandler.setSession(ssess);
sess = ssess;
} else {
return "Unrecognized SESSION STYLE " + style;
}
} catch (IOException e) {
return e.toString();
} catch (DataFormatException e) {
return e.toString();
} catch (SAMException e) {
return e.toString();
} catch (I2PSessionException e) {
return e.toString();
}
for (SAMMessageSess s : sessions.values()) {
if (listenProtocol == s.getListenProtocol() && listenPort == s.getListenPort())
return "Duplicate protocol " + listenProtocol + " and port " + listenPort;
}
rec = new SessionRecord(getDestination().toBase64(), props, subhandler);
try {
SAMv3Handler.sSessionsHash.putDupDestOK(nick, rec);
sessions.put(nick, sess);
} catch (SessionsDB.ExistingIdException e) {
return "Duplicate ID " + nick;
}
if (_log.shouldWarn())
_log.warn("added " + style + " proto " + listenProtocol + " port " + listenPort);
sess.start();
// all ok
return null;
}
use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class BWLimits method getBWLimits.
public static int[] getBWLimits(String host, int port) {
int[] rv = null;
try {
I2PClient client = new I2PSimpleClient();
Properties opts = new Properties();
opts.put(I2PClient.PROP_TCP_HOST, host);
opts.put(I2PClient.PROP_TCP_PORT, "" + port);
I2PSession session = client.createSession(null, opts);
session.connect();
rv = session.bandwidthLimits();
session.destroySession();
} catch (I2PSessionException ise) {
}
return rv;
}
use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class I2CPMessageProducer method updateTunnels.
/**
* Update number of tunnels
*
* @param tunnels 0 for original configured number
*/
public void updateTunnels(I2PSessionImpl session, int tunnels) throws I2PSessionException {
ReconfigureSessionMessage msg = new ReconfigureSessionMessage();
SessionConfig cfg = new SessionConfig(session.getMyDestination());
Properties props = session.getOptions();
if (tunnels > 0) {
Properties newprops = new Properties();
newprops.putAll(props);
props = newprops;
props.setProperty("inbound.quantity", "" + tunnels);
props.setProperty("outbound.quantity", "" + tunnels);
props.setProperty("inbound.backupQuantity", "0");
props.setProperty("outbound.backupQuantity", "0");
}
cfg.setOptions(props);
try {
cfg.signSessionConfig(session.getPrivateKey());
} catch (DataFormatException dfe) {
throw new I2PSessionException("Unable to sign the session config", dfe);
}
msg.setSessionConfig(cfg);
SessionId sid = session.getSessionId();
if (sid == null) {
_log.error(session.toString() + " update config w/o session", new Exception());
return;
}
msg.setSessionId(sid);
session.sendMessage(msg);
}
use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.
the class I2CPMessageProducer method sendMessage.
/**
* Package up and send the payload to the router for delivery
*
* @param nonce 0 to 0xffffffff; if 0, the router will not reply with a MessageStatusMessage
* @since 0.8.4
*/
public void sendMessage(I2PSessionImpl session, Destination dest, long nonce, byte[] payload, long expires, int flags) throws I2PSessionException {
if (!updateBps(payload.length, expires))
// drop the message... send fail notification?
return;
SendMessageMessage msg;
if (expires > 0 || flags > 0) {
SendMessageExpiresMessage smsg = new SendMessageExpiresMessage();
smsg.setExpiration(expires);
smsg.setFlags(flags);
msg = smsg;
} else
msg = new SendMessageMessage();
msg.setDestination(dest);
SessionId sid = session.getSessionId();
if (sid == null) {
_log.error(session.toString() + " send message w/o session", new Exception());
return;
}
msg.setSessionId(sid);
msg.setNonce(nonce);
Payload data = createPayload(dest, payload, null, null, null, null);
msg.setPayload(data);
session.sendMessage(msg);
}
Aggregations