use of net.i2p.data.i2cp.SessionId in project i2p.i2p by i2p.
the class ClientManager method destinationEstablished.
/**
* Add to the clients list. Check for a dup destination.
* Side effect: Sets the session ID of the runner.
* Caller must call runner.disconnectClient() on failure.
*
* @return SessionStatusMessage return code, 1 for success, != 1 for failure
*/
public int destinationEstablished(ClientConnectionRunner runner, Destination dest) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("DestinationEstablished called for destination " + dest.toBase32());
synchronized (_pendingRunners) {
_pendingRunners.remove(runner);
}
int rv;
synchronized (_runners) {
boolean fail = _runnersByHash.containsKey(dest.calculateHash());
if (fail) {
rv = SessionStatusMessage.STATUS_INVALID;
} else {
SessionId id = locked_getNextSessionId();
if (id != null) {
Hash h = dest.calculateHash();
runner.setSessionId(h, id);
_runners.put(dest, runner);
_runnersByHash.put(h, runner);
rv = SessionStatusMessage.STATUS_CREATED;
} else {
rv = SessionStatusMessage.STATUS_REFUSED;
}
}
}
if (rv == SessionStatusMessage.STATUS_INVALID) {
_log.log(Log.CRIT, "Client attempted to register duplicate destination " + dest.toBase32());
} else if (rv == SessionStatusMessage.STATUS_REFUSED) {
_log.error("Max sessions exceeded " + dest.toBase32());
}
return rv;
}
use of net.i2p.data.i2cp.SessionId in project i2p.i2p by i2p.
the class ClientMessageEventListener method handleCreateLeaseSet.
/**
* override for testing
*/
protected void handleCreateLeaseSet(CreateLeaseSetMessage message) {
if ((message.getLeaseSet() == null) || (message.getPrivateKey() == null) || (message.getSigningPrivateKey() == null)) {
if (_log.shouldLog(Log.ERROR))
_log.error("Null lease set granted: " + message);
_runner.disconnectClient("Invalid CreateLeaseSetMessage");
return;
}
SessionId id = message.getSessionId();
SessionConfig cfg = _runner.getConfig(id);
if (cfg == null) {
List<SessionId> current = _runner.getSessionIds();
String msg = "CreateLeaseSet invalid session: " + id + " current: " + current;
if (_log.shouldLog(Log.ERROR))
_log.error(msg);
_runner.disconnectClient(msg);
return;
}
Destination dest = cfg.getDestination();
Destination ndest = message.getLeaseSet().getDestination();
if (!dest.equals(ndest)) {
if (_log.shouldLog(Log.ERROR))
_log.error("Different destination in LS");
_runner.disconnectClient("Different destination in LS");
return;
}
LeaseSetKeys keys = _context.keyManager().getKeys(dest);
if (keys == null || !message.getPrivateKey().equals(keys.getDecryptionKey())) {
// Verify and register crypto keys if new or if changed
// Private crypto key should never change, and if it does,
// one of the checks below will fail
PublicKey pk;
try {
pk = message.getPrivateKey().toPublic();
} catch (IllegalArgumentException iae) {
if (_log.shouldLog(Log.ERROR))
_log.error("Bad private key in LS");
_runner.disconnectClient("Bad private key in LS");
return;
}
if (!pk.equals(message.getLeaseSet().getEncryptionKey())) {
if (_log.shouldLog(Log.ERROR))
_log.error("Private/public crypto key mismatch in LS");
_runner.disconnectClient("Private/public crypto key mismatch in LS");
return;
}
// just register new SPK, don't verify, unused
_context.keyManager().registerKeys(dest, message.getSigningPrivateKey(), message.getPrivateKey());
} else if (!message.getSigningPrivateKey().equals(keys.getRevocationKey())) {
// just register new SPK, don't verify, unused
_context.keyManager().registerKeys(dest, message.getSigningPrivateKey(), message.getPrivateKey());
}
try {
_context.netDb().publish(message.getLeaseSet());
} catch (IllegalArgumentException iae) {
if (_log.shouldLog(Log.ERROR))
_log.error("Invalid leaseset from client", iae);
_runner.disconnectClient("Invalid leaseset: " + iae);
return;
}
if (_log.shouldLog(Log.INFO))
_log.info("New lease set granted for destination " + dest);
// leaseSetCreated takes care of all the LeaseRequestState stuff (including firing any jobs)
_runner.leaseSetCreated(message.getLeaseSet());
}
use of net.i2p.data.i2cp.SessionId in project i2p.i2p by i2p.
the class ClientMessageEventListener method handleReconfigureSession.
/**
* Message's Session ID ignored. This doesn't support removing previously set options.
* Nor do we bother with message.getSessionConfig().verifySignature() ... should we?
* Nor is the Date checked.
*
* Note that this does NOT update the few options handled in
* ClientConnectionRunner.sessionEstablished(). Those can't be changed later.
*
* Defaults in SessionConfig options are, in general, NOT honored.
* In-JVM client side must promote defaults to the primary map.
*/
private void handleReconfigureSession(ReconfigureSessionMessage message) {
SessionId id = message.getSessionId();
SessionConfig cfg = _runner.getConfig(id);
if (cfg == null) {
List<SessionId> current = _runner.getSessionIds();
String msg = "ReconfigureSession invalid session: " + id + " current: " + current;
if (_log.shouldLog(Log.ERROR))
_log.error(msg);
// sendStatusMessage(id, SessionStatusMessage.STATUS_INVALID);
_runner.disconnectClient(msg);
return;
}
if (_log.shouldLog(Log.INFO))
_log.info("Updating options - old: " + cfg + " new: " + message.getSessionConfig());
if (!message.getSessionConfig().getDestination().equals(cfg.getDestination())) {
_log.error("Dest mismatch");
sendStatusMessage(id, SessionStatusMessage.STATUS_INVALID);
_runner.stopRunning();
return;
}
Hash dest = cfg.getDestination().calculateHash();
cfg.getOptions().putAll(message.getSessionConfig().getOptions());
ClientTunnelSettings settings = new ClientTunnelSettings(dest);
Properties props = new Properties();
props.putAll(cfg.getOptions());
settings.readFromProperties(props);
_context.tunnelManager().setInboundSettings(dest, settings.getInboundSettings());
_context.tunnelManager().setOutboundSettings(dest, settings.getOutboundSettings());
sendStatusMessage(id, SessionStatusMessage.STATUS_UPDATED);
}
use of net.i2p.data.i2cp.SessionId in project i2p.i2p by i2p.
the class MessageReceivedJob method messageAvailable.
/**
* Deliver notification to the client that the given message is available.
*/
private void messageAvailable(MessageId id, long size) throws I2CPMessageException {
// if (_log.shouldLog(Log.DEBUG))
// _log.debug("Sending message available: " + id + " to sessionId " + _runner.getSessionId()
// + " (with nonce=1)", new Exception("available"));
MessageStatusMessage msg = new MessageStatusMessage();
msg.setMessageId(id.getMessageId());
SessionId sid = _runner.getSessionId(_toDest.calculateHash());
if (sid == null) {
if (_log.shouldLog(Log.WARN))
_log.warn("No session for " + _toDest.calculateHash());
return;
}
msg.setSessionId(sid.getSessionId());
msg.setSize(size);
// has to be >= 0, it is initialized to -1
msg.setNonce(1);
msg.setStatus(MessageStatusMessage.STATUS_AVAILABLE);
_runner.doSend(msg);
}
Aggregations