Search in sources :

Example 1 with SessionConfig

use of net.i2p.data.i2cp.SessionConfig in project i2p.i2p by i2p.

the class I2CPMessageProducer method connect.

/**
 * Send all the messages that a client needs to send to a router to establish
 * a new session.
 */
public void connect(I2PSessionImpl session) throws I2PSessionException {
    updateBandwidth(session);
    CreateSessionMessage msg = new CreateSessionMessage();
    SessionConfig cfg = new SessionConfig(session.getMyDestination());
    cfg.setOptions(session.getOptions());
    if (_log.shouldLog(Log.DEBUG))
        _log.debug("config created");
    try {
        cfg.signSessionConfig(session.getPrivateKey());
    } catch (DataFormatException dfe) {
        throw new I2PSessionException("Unable to sign the session config", dfe);
    }
    if (_log.shouldLog(Log.DEBUG))
        _log.debug("config signed");
    msg.setSessionConfig(cfg);
    if (_log.shouldLog(Log.DEBUG))
        _log.debug("config loaded into message");
    session.sendMessage_unchecked(msg);
    if (_log.shouldLog(Log.DEBUG))
        _log.debug("config message sent");
}
Also used : DataFormatException(net.i2p.data.DataFormatException) SessionConfig(net.i2p.data.i2cp.SessionConfig) I2PSessionException(net.i2p.client.I2PSessionException) CreateSessionMessage(net.i2p.data.i2cp.CreateSessionMessage)

Example 2 with SessionConfig

use of net.i2p.data.i2cp.SessionConfig in project i2p.i2p by i2p.

the class ClientManager method distributeMessage.

/**
 * Distribute message to a local or remote destination.
 * @param msgId the router's ID for this message
 * @param messageNonce the client's ID for this message
 * @param flags ignored for local
 */
void distributeMessage(Destination fromDest, Destination toDest, Payload payload, MessageId msgId, long messageNonce, long expiration, int flags) {
    // check if there is a runner for it
    ClientConnectionRunner runner = getRunner(toDest);
    if (runner != null) {
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("Message " + msgId + " is targeting a local destination.  distribute it as such");
        ClientConnectionRunner sender = getRunner(fromDest);
        if (sender == null) {
            // sender went away
            return;
        }
        // run this inline so we don't clog up the job queue
        Job j = new DistributeLocal(toDest, runner, sender, fromDest, payload, msgId, messageNonce);
        // _ctx.jobQueue().addJob(j);
        j.runJob();
    } else {
        // remote.  w00t
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("Message " + msgId + " is targeting a REMOTE destination!  Added to the client message pool");
        runner = getRunner(fromDest);
        if (runner == null) {
            // sender went away
            return;
        }
        SessionConfig config = runner.getConfig(fromDest.calculateHash());
        if (config == null)
            return;
        ClientMessage msg = new ClientMessage(toDest, payload, config, fromDest, msgId, messageNonce, expiration, flags);
        _ctx.clientMessagePool().add(msg, true);
    }
}
Also used : SessionConfig(net.i2p.data.i2cp.SessionConfig) ClientMessage(net.i2p.router.ClientMessage) Job(net.i2p.router.Job)

Example 3 with SessionConfig

use of net.i2p.data.i2cp.SessionConfig 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
        }
    }
}
Also used : Destination(net.i2p.data.Destination) ClientTunnelSettings(net.i2p.router.ClientTunnelSettings) SessionConfig(net.i2p.data.i2cp.SessionConfig) Properties(java.util.Properties) SessionId(net.i2p.data.i2cp.SessionId) SigType(net.i2p.crypto.SigType)

Example 4 with SessionConfig

use of net.i2p.data.i2cp.SessionConfig in project i2p.i2p by i2p.

the class ClientMessageEventListener method handleSendMessage.

/**
 * Handle a SendMessageMessage: give it a message Id, have the ClientManager distribute
 * it, and send the client an ACCEPTED message
 */
private void handleSendMessage(SendMessageMessage message) {
    SessionId sid = message.getSessionId();
    SessionConfig cfg = _runner.getConfig(sid);
    if (cfg == null) {
        List<SessionId> current = _runner.getSessionIds();
        String msg = "SendMessage invalid session: " + sid + " current: " + current;
        if (_log.shouldLog(Log.ERROR))
            _log.error(msg);
        // do this instead:
        if (sid != null && message.getNonce() > 0) {
            MessageStatusMessage status = new MessageStatusMessage();
            status.setMessageId(_runner.getNextMessageId());
            status.setSessionId(sid.getSessionId());
            status.setSize(0);
            status.setNonce(message.getNonce());
            status.setStatus(MessageStatusMessage.STATUS_SEND_FAILURE_BAD_SESSION);
            try {
                _runner.doSend(status);
            } catch (I2CPMessageException ime) {
                if (_log.shouldLog(Log.WARN))
                    _log.warn("Error writing out the message status message", ime);
            }
        }
        return;
    }
    if (_log.shouldLog(Log.DEBUG))
        _log.debug("handleSendMessage called");
    long beforeDistribute = _context.clock().now();
    MessageId id = _runner.distributeMessage(message);
    long timeToDistribute = _context.clock().now() - beforeDistribute;
    // TODO validate session id
    _runner.ackSendMessage(sid, id, message.getNonce());
    _context.statManager().addRateData("client.distributeTime", timeToDistribute);
    if ((timeToDistribute > 50) && (_log.shouldLog(Log.DEBUG)))
        _log.debug("Took too long to distribute the message (which holds up the ack): " + timeToDistribute);
}
Also used : I2CPMessageException(net.i2p.data.i2cp.I2CPMessageException) SessionConfig(net.i2p.data.i2cp.SessionConfig) MessageStatusMessage(net.i2p.data.i2cp.MessageStatusMessage) SessionId(net.i2p.data.i2cp.SessionId) MessageId(net.i2p.data.i2cp.MessageId)

Example 5 with SessionConfig

use of net.i2p.data.i2cp.SessionConfig 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);
}
Also used : ReconfigureSessionMessage(net.i2p.data.i2cp.ReconfigureSessionMessage) DataFormatException(net.i2p.data.DataFormatException) SessionConfig(net.i2p.data.i2cp.SessionConfig) I2PSessionException(net.i2p.client.I2PSessionException) Properties(java.util.Properties) SessionId(net.i2p.data.i2cp.SessionId) DataFormatException(net.i2p.data.DataFormatException) I2PSessionException(net.i2p.client.I2PSessionException)

Aggregations

SessionConfig (net.i2p.data.i2cp.SessionConfig)8 SessionId (net.i2p.data.i2cp.SessionId)5 Properties (java.util.Properties)3 I2PSessionException (net.i2p.client.I2PSessionException)2 DataFormatException (net.i2p.data.DataFormatException)2 Destination (net.i2p.data.Destination)2 ClientTunnelSettings (net.i2p.router.ClientTunnelSettings)2 SigType (net.i2p.crypto.SigType)1 Hash (net.i2p.data.Hash)1 PublicKey (net.i2p.data.PublicKey)1 CreateSessionMessage (net.i2p.data.i2cp.CreateSessionMessage)1 I2CPMessageException (net.i2p.data.i2cp.I2CPMessageException)1 MessageId (net.i2p.data.i2cp.MessageId)1 MessageStatusMessage (net.i2p.data.i2cp.MessageStatusMessage)1 ReconfigureSessionMessage (net.i2p.data.i2cp.ReconfigureSessionMessage)1 ClientMessage (net.i2p.router.ClientMessage)1 Job (net.i2p.router.Job)1 LeaseSetKeys (net.i2p.router.LeaseSetKeys)1