use of net.i2p.data.i2cp.SessionId in project i2p.i2p by i2p.
the class I2CPMessageProducer method createLeaseSet.
/**
* Create a new signed leaseSet in response to a request to do so and send it
* to the router
*/
public void createLeaseSet(I2PSessionImpl session, LeaseSet leaseSet, SigningPrivateKey signingPriv, PrivateKey priv) throws I2PSessionException {
CreateLeaseSetMessage msg = new CreateLeaseSetMessage();
msg.setLeaseSet(leaseSet);
msg.setPrivateKey(priv);
msg.setSigningPrivateKey(signingPriv);
SessionId sid = session.getSessionId();
if (sid == null) {
_log.error(session.toString() + " create LS w/o session", new Exception());
return;
}
msg.setSessionId(sid);
session.sendMessage_unchecked(msg);
}
use of net.i2p.data.i2cp.SessionId 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.9.2
*/
public void sendMessage(I2PSessionImpl session, Destination dest, long nonce, byte[] payload, SendMessageOptions options) throws I2PSessionException {
long expires = options.getTime();
if (!updateBps(payload.length, expires))
// drop the message... send fail notification?
return;
SendMessageMessage msg = new SendMessageExpiresMessage(options);
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);
}
use of net.i2p.data.i2cp.SessionId in project i2p.i2p by i2p.
the class ClientConnectionRunner method updateMessageDeliveryStatus.
/**
* Send a notification to the client that their message (id specified) was
* delivered (or failed delivery)
* Note that this sends the Guaranteed status codes, even though we only support best effort.
* Doesn't do anything if i2cp.messageReliability = "none"
*
* Do not use for status = STATUS_SEND_ACCEPTED; use ackSendMessage() for that.
*
* @param dest the client
* @param id the router's ID for this message
* @param messageNonce the client's ID for this message
* @param status see I2CP MessageStatusMessage for success/failure codes
*/
void updateMessageDeliveryStatus(Destination dest, MessageId id, long messageNonce, int status) {
if (_dead || messageNonce <= 0)
return;
SessionParams sp = _sessions.get(dest.calculateHash());
if (sp == null)
return;
SessionId sid = sp.sessionId;
if (sid == null)
// sid = new SessionId(foo) ???
return;
_context.jobQueue().addJob(new MessageDeliveryStatusUpdate(sid, id, messageNonce, status));
}
use of net.i2p.data.i2cp.SessionId in project i2p.i2p by i2p.
the class ClientManager method unregisterConnection.
/**
* Remove all sessions for this runner.
*/
public void unregisterConnection(ClientConnectionRunner runner) {
synchronized (_pendingRunners) {
_pendingRunners.remove(runner);
}
List<SessionId> ids = runner.getSessionIds();
List<Destination> dests = runner.getDestinations();
if (_log.shouldLog(Log.WARN))
_log.warn("Unregistering (dropping) a client connection with ids: " + ids);
synchronized (_runners) {
for (SessionId id : ids) {
_runnerSessionIds.remove(id);
}
for (Destination dest : dests) {
_runners.remove(dest);
_runnersByHash.remove(dest.calculateHash());
}
// just in case
for (Iterator<ClientConnectionRunner> iter = _runners.values().iterator(); iter.hasNext(); ) {
ClientConnectionRunner r = iter.next();
if (r.equals(runner))
iter.remove();
}
for (Iterator<ClientConnectionRunner> iter = _runnersByHash.values().iterator(); iter.hasNext(); ) {
ClientConnectionRunner r = iter.next();
if (r.equals(runner))
iter.remove();
}
}
}
use of net.i2p.data.i2cp.SessionId in project i2p.i2p by i2p.
the class ClientMessageEventListener method handleCreateSession.
/**
* Handle a CreateSessionMessage.
* On errors, we could perhaps send a SessionStatusMessage with STATUS_INVALID before
* sending the DisconnectMessage... but right now the client will send _us_ a
* DisconnectMessage in return, and not wait around for our DisconnectMessage.
* So keep it simple.
*
* Defaults in SessionConfig options are, in general, NOT honored.
* In-JVM client side must promote defaults to the primary map.
*/
private void handleCreateSession(CreateSessionMessage message) {
SessionConfig in = message.getSessionConfig();
Destination dest = in.getDestination();
if (in.verifySignature()) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Signature verified correctly on create session message");
} else {
// For now, we do NOT send a SessionStatusMessage - see javadoc above
int itype = dest.getCertificate().getCertificateType();
SigType stype = SigType.getByCode(itype);
if (stype == null || !stype.isAvailable()) {
_log.error("Client requested unsupported signature type " + itype);
_runner.disconnectClient("Unsupported signature type " + itype);
} else if (in.tooOld()) {
long skew = _context.clock().now() - in.getCreationDate().getTime();
String msg = "Create session message client clock skew? ";
if (skew >= 0)
msg += DataHelper.formatDuration(skew) + " in the past";
else
msg += DataHelper.formatDuration(0 - skew) + " in the future";
_log.error(msg);
_runner.disconnectClient(msg);
} else {
_log.error("Signature verification failed on a create session message");
_runner.disconnectClient("Invalid signature on CreateSessionMessage");
}
return;
}
// Auth, since 0.8.2
Properties inProps = in.getOptions();
if (!checkAuth(inProps))
return;
SessionId id = _runner.getSessionId(dest.calculateHash());
if (id != null) {
_runner.disconnectClient("Already have session " + id);
return;
}
// Copy over the whole config structure so we don't later corrupt it on
// the client side if we change settings or later get a
// ReconfigureSessionMessage
SessionConfig cfg = new SessionConfig(dest);
cfg.setSignature(in.getSignature());
Properties props = new Properties();
boolean isPrimary = _runner.getSessionIds().isEmpty();
if (!isPrimary) {
// all the primary options, then the overrides from the alias
SessionConfig pcfg = _runner.getPrimaryConfig();
if (pcfg != null) {
props.putAll(pcfg.getOptions());
} else {
_log.error("no primary config?");
}
}
props.putAll(inProps);
cfg.setOptions(props);
// this sets the session id
int status = _runner.sessionEstablished(cfg);
if (status != SessionStatusMessage.STATUS_CREATED) {
// For now, we do NOT send a SessionStatusMessage - see javadoc above
if (_log.shouldLog(Log.ERROR))
_log.error("Session establish failed: code = " + status);
String msg;
if (status == SessionStatusMessage.STATUS_INVALID)
msg = "duplicate destination";
else if (status == SessionStatusMessage.STATUS_REFUSED)
msg = "session limit exceeded";
else
msg = "unknown error";
_runner.disconnectClient(msg);
return;
}
// get the new session ID
id = _runner.getSessionId(dest.calculateHash());
if (_log.shouldLog(Log.INFO))
_log.info("Session " + id + " established for " + dest.calculateHash());
if (isPrimary) {
sendStatusMessage(id, status);
startCreateSessionJob(cfg);
} else {
SessionConfig pcfg = _runner.getPrimaryConfig();
if (pcfg != null) {
ClientTunnelSettings settings = new ClientTunnelSettings(dest.calculateHash());
settings.readFromProperties(props);
// addAlias() sends the create lease set msg, so we have to send the SMS first
sendStatusMessage(id, status);
boolean ok = _context.tunnelManager().addAlias(dest, settings, pcfg.getDestination());
if (!ok) {
_log.error("Add alias failed");
// FIXME cleanup
}
} else {
_log.error("no primary config?");
status = SessionStatusMessage.STATUS_INVALID;
sendStatusMessage(id, status);
// FIXME cleanup
}
}
}
Aggregations