Search in sources :

Example 21 with I2PSession

use of net.i2p.client.I2PSession in project i2p.i2p by i2p.

the class PacketQueue method enqueue.

/**
 * Add a new packet to be sent out ASAP.
 * This updates the acks.
 *
 * keys and tags disabled since dropped in I2PSession
 * @return true if sent
 */
public boolean enqueue(PacketLocal packet) {
    if (_dead)
        return false;
    if (packet.getAckTime() > 0) {
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("Not resending " + packet);
        return false;
    }
    Connection con = packet.getConnection();
    if (con != null) {
        // this updates the ack/nack fields
        con.getInputStream().updateAcks(packet);
    }
    ByteArray ba = _cache.acquire();
    byte[] buf = ba.getData();
    long begin = 0;
    long end = 0;
    boolean sent = false;
    try {
        int size = 0;
        // long beforeWrite = System.currentTimeMillis();
        if (packet.shouldSign())
            size = packet.writeSignedPacket(buf, 0);
        else
            size = packet.writePacket(buf, 0);
        // last chance to short circuit...
        if (packet.getAckTime() > 0)
            return false;
        // this should not block!
        begin = _context.clock().now();
        long expires = 0;
        Connection.ResendPacketEvent rpe = (Connection.ResendPacketEvent) packet.getResendEvent();
        if (rpe != null)
            // we want the router to expire it a little before we do,
            // so if we retransmit it will use a new tunnel/lease combo
            expires = rpe.getNextSendTime() - 500;
        SendMessageOptions options = new SendMessageOptions();
        if (expires > 0)
            options.setDate(expires);
        boolean listenForStatus = false;
        // FINAL trumps INITIAL, in the case of SYN+CLOSE
        if (packet.isFlagSet(FLAGS_FINAL_TAGS)) {
            if (packet.isFlagSet(Packet.FLAG_ECHO)) {
                // Send LS for PING, not for PONG
                if (// pong
                packet.getSendStreamId() <= 0)
                    options.setSendLeaseSet(false);
            } else {
                options.setSendLeaseSet(false);
            }
            int sendTags = FINAL_TAGS_TO_SEND;
            int tagThresh = FINAL_TAG_THRESHOLD;
            if (con != null) {
                ConnectionOptions copts = con.getOptions();
                int cSendTags = copts.getTagsToSend();
                int cTagThresh = copts.getTagThreshold();
                if (cSendTags < sendTags)
                    sendTags = cSendTags;
                if (cTagThresh < tagThresh)
                    tagThresh = cTagThresh;
            }
            options.setTagsToSend(sendTags);
            options.setTagThreshold(tagThresh);
        } else if (packet.isFlagSet(FLAGS_INITIAL_TAGS)) {
            if (con != null) {
                if (con.isInbound())
                    options.setSendLeaseSet(false);
                else if (ENABLE_STATUS_LISTEN)
                    listenForStatus = true;
            }
            int sendTags = INITIAL_TAGS_TO_SEND;
            int tagThresh = MIN_TAG_THRESHOLD;
            if (con != null) {
                ConnectionOptions copts = con.getOptions();
                int cSendTags = copts.getTagsToSend();
                int cTagThresh = copts.getTagThreshold();
                if (cSendTags < sendTags)
                    sendTags = cSendTags;
                if (cTagThresh < tagThresh)
                    tagThresh = cTagThresh;
            }
            options.setTagsToSend(sendTags);
            options.setTagThreshold(tagThresh);
        } else {
            if (con != null) {
                if (con.isInbound() && con.getLifetime() < 2 * 60 * 1000)
                    options.setSendLeaseSet(false);
                // increase threshold with higher window sizes to prevent stalls
                // after tag delivery failure
                ConnectionOptions copts = con.getOptions();
                int wdw = copts.getWindowSize();
                int thresh = Math.max(MIN_TAG_THRESHOLD, wdw * TAG_WINDOW_FACTOR);
                int cTagThresh = copts.getTagThreshold();
                if (cTagThresh < thresh)
                    thresh = cTagThresh;
                options.setTagThreshold(thresh);
            }
        }
        I2PSession session = packet.getSession();
        if (listenForStatus) {
            long id = session.sendMessage(packet.getTo(), buf, 0, size, I2PSession.PROTO_STREAMING, packet.getLocalPort(), packet.getRemotePort(), options, this);
            _messageStatusMap.put(Long.valueOf(id), con);
            sent = true;
        } else {
            sent = session.sendMessage(packet.getTo(), buf, 0, size, I2PSession.PROTO_STREAMING, packet.getLocalPort(), packet.getRemotePort(), options);
        }
        end = _context.clock().now();
        if ((end - begin > 1000) && (_log.shouldLog(Log.WARN)))
            _log.warn("Took " + (end - begin) + "ms to sendMessage(...) " + packet);
        _context.statManager().addRateData("stream.con.sendMessageSize", size, packet.getLifetime());
        if (packet.getNumSends() > 1)
            _context.statManager().addRateData("stream.con.sendDuplicateSize", size, packet.getLifetime());
        if (con != null) {
            con.incrementBytesSent(size);
            if (packet.getNumSends() > 1)
                con.incrementDupMessagesSent(1);
        }
    } catch (I2PSessionException ise) {
        if (_log.shouldLog(Log.WARN))
            _log.warn("Unable to send the packet " + packet, ise);
    }
    _cache.release(ba);
    if (!sent) {
        if (_log.shouldLog(Log.WARN))
            _log.warn("Send failed for " + packet);
        if (// handle race on b0rk
        con != null)
            con.disconnect(false);
    } else {
        // packet.setKeyUsed(keyUsed);
        // packet.setTagsSent(tagsSent);
        packet.incrementSends();
        if (con != null && _log.shouldDebug()) {
            String suffix = "wsize " + con.getOptions().getWindowSize() + " rto " + con.getOptions().getRTO();
            con.getConnectionManager().getPacketHandler().displayPacket(packet, "SEND", suffix);
        }
        if (I2PSocketManagerFull.pcapWriter != null && _context.getBooleanProperty(I2PSocketManagerFull.PROP_PCAP))
            packet.logTCPDump();
    }
    if ((packet.getSequenceNum() == 0) && (!packet.isFlagSet(Packet.FLAG_SYNCHRONIZE))) {
        // ack only, so release it asap
        packet.releasePayload();
    } else if (packet.isFlagSet(Packet.FLAG_ECHO) && !packet.isFlagSet(Packet.FLAG_SIGNATURE_INCLUDED)) {
        // pong
        packet.releasePayload();
    } else if (packet.isFlagSet(Packet.FLAG_RESET)) {
        // reset
        packet.releasePayload();
    }
    return sent;
}
Also used : SendMessageOptions(net.i2p.client.SendMessageOptions) ByteArray(net.i2p.data.ByteArray) I2PSession(net.i2p.client.I2PSession) I2PSessionException(net.i2p.client.I2PSessionException)

Example 22 with I2PSession

use of net.i2p.client.I2PSession in project i2p.i2p by i2p.

the class PingIT method test.

@Test
public void test() throws Exception {
    I2PAppContext context = I2PAppContext.getGlobalContext();
    I2PSession session = createSession();
    ConnectionManager mgr = new ConnectionManager(context, session, new ConnectionOptions());
    for (int i = 0; i < 10; i++) {
        boolean ponged = mgr.ping(session.getMyDestination(), 2 * 1000);
        assertTrue(ponged);
    }
}
Also used : I2PAppContext(net.i2p.I2PAppContext) I2PSession(net.i2p.client.I2PSession) Test(org.junit.Test)

Example 23 with I2PSession

use of net.i2p.client.I2PSession in project i2p.i2p by i2p.

the class I2PTunnel method destFromName.

/**
 *  @param i2cpHost may be null
 *  @param i2cpPort may be null
 *  @param user may be null
 *  @param pw may be null
 *  @since 0.9.11
 */
private static Destination destFromName(String name, String i2cpHost, String i2cpPort, boolean isSSL, String user, String pw) throws DataFormatException {
    if ((name == null) || (name.trim().length() <= 0))
        throw new DataFormatException("Empty destination provided");
    I2PAppContext ctx = I2PAppContext.getGlobalContext();
    Log log = ctx.logManager().getLog(I2PTunnel.class);
    if (name.startsWith("file:")) {
        Destination result = new Destination();
        byte[] content = null;
        FileInputStream in = null;
        try {
            in = new FileInputStream(name.substring("file:".length()));
            byte[] buf = new byte[1024];
            int read = DataHelper.read(in, buf);
            content = new byte[read];
            System.arraycopy(buf, 0, content, 0, read);
        } catch (IOException ioe) {
            System.out.println(ioe.getMessage());
            return null;
        } finally {
            if (in != null)
                try {
                    in.close();
                } catch (IOException io) {
                }
        }
        try {
            result.fromByteArray(content);
            return result;
        } catch (RuntimeException ex) {
            if (log.shouldLog(Log.INFO))
                log.info("File is not a binary destination - trying base64");
            try {
                byte[] decoded = Base64.decode(new String(content));
                result.fromByteArray(decoded);
                return result;
            } catch (DataFormatException dfe) {
                if (log.shouldLog(Log.WARN))
                    log.warn("File is not a base64 destination either - failing!");
                return null;
            }
        }
    } else {
        // ask naming service
        name = name.trim();
        NamingService inst = ctx.namingService();
        boolean b32 = name.length() == 60 && name.toLowerCase(Locale.US).endsWith(".b32.i2p");
        Destination d = null;
        if (ctx.isRouterContext() || !b32) {
            // Local lookup.
            // Even though we could do b32 outside router ctx here,
            // we do it below instead so we can set the host and port,
            // which we can't do with lookup()
            d = inst.lookup(name);
            if (d != null || ctx.isRouterContext() || name.length() >= 516)
                return d;
        }
        // Outside router context only,
        // try simple session to ask the router.
        I2PClient client = new I2PSimpleClient();
        Properties opts = new Properties();
        if (i2cpHost != null)
            opts.put(I2PClient.PROP_TCP_HOST, i2cpHost);
        if (i2cpPort != null)
            opts.put(I2PClient.PROP_TCP_PORT, i2cpPort);
        opts.put("i2cp.SSL", Boolean.toString(isSSL));
        if (user != null)
            opts.put("i2cp.username", user);
        if (pw != null)
            opts.put("i2cp.password", pw);
        I2PSession session = null;
        try {
            session = client.createSession(null, opts);
            session.connect();
            d = session.lookupDest(name);
        } catch (I2PSessionException ise) {
            if (log.shouldLog(Log.WARN))
                log.warn("Lookup via router failed", ise);
        } finally {
            if (session != null) {
                try {
                    session.destroySession();
                } catch (I2PSessionException ise) {
                }
            }
        }
        return d;
    }
}
Also used : Destination(net.i2p.data.Destination) I2PAppContext(net.i2p.I2PAppContext) Log(net.i2p.util.Log) IOException(java.io.IOException) OrderedProperties(net.i2p.util.OrderedProperties) Properties(java.util.Properties) FileInputStream(java.io.FileInputStream) DataFormatException(net.i2p.data.DataFormatException) NamingService(net.i2p.client.naming.NamingService) I2PSimpleClient(net.i2p.client.I2PSimpleClient) I2PSession(net.i2p.client.I2PSession) I2PSessionException(net.i2p.client.I2PSessionException) I2PClient(net.i2p.client.I2PClient)

Example 24 with I2PSession

use of net.i2p.client.I2PSession in project i2p.i2p by i2p.

the class I2PTunnelClientBase method getSocketManager.

/**
 * This is ONLY for shared clients.
 * As of 0.9.20 this is fast, and does NOT connect the manager to the router.
 * Call verifySocketManager() for that.
 *
 * @return non-null
 * @throws IllegalArgumentException if the I2CP configuration is b0rked so
 *                                  badly that we cant create a socketManager
 */
protected static synchronized I2PSocketManager getSocketManager(I2PTunnel tunnel, String pkf) {
    // shadows instance _log
    Log _log = tunnel.getContext().logManager().getLog(I2PTunnelClientBase.class);
    if (socketManager != null && !socketManager.isDestroyed()) {
        I2PSession s = socketManager.getSession();
        if (s.isClosed() && _socketManagerState != SocketManagerState.INIT) {
            if (_log.shouldLog(Log.INFO))
                _log.info(tunnel.getClientOptions().getProperty("inbound.nickname") + ": Building a new socket manager since the old one closed [s=" + s + "]");
            tunnel.removeSession(s);
            // make sure the old one is closed
            socketManager.destroySocketManager();
            _socketManagerState = SocketManagerState.INIT;
            // We could be here a LONG time, holding the lock
            socketManager = buildSocketManager(tunnel, pkf);
            // FIXME may not be the right place for this
            I2PSession sub = addSubsession(tunnel);
            if (sub != null && _log.shouldLog(Log.WARN))
                _log.warn("Added subsession " + sub);
        } else {
            if (_log.shouldLog(Log.INFO))
                _log.info(tunnel.getClientOptions().getProperty("inbound.nickname") + ": Not building a new socket manager since the old one is open [s=" + s + "]");
            // If some other tunnel created the session, we need to add it
            // as our session too.
            // It's a Set in I2PTunnel
            tunnel.addSession(s);
        }
    } else {
        if (_log.shouldLog(Log.INFO))
            _log.info(tunnel.getClientOptions().getProperty("inbound.nickname") + ": Building a new socket manager since there is no other one");
        socketManager = buildSocketManager(tunnel, pkf);
        I2PSession sub = addSubsession(tunnel);
        if (sub != null && _log.shouldLog(Log.WARN))
            _log.warn("Added subsession " + sub);
    }
    return socketManager;
}
Also used : Log(net.i2p.util.Log) I2PSession(net.i2p.client.I2PSession)

Example 25 with I2PSession

use of net.i2p.client.I2PSession in project i2p.i2p by i2p.

the class I2PTunnelClientBase method addSubsession.

/**
 *  Add a DSA_SHA1 subsession to the shared client if necessary.
 *
 *  @return subsession, or null if none was added
 *  @since 0.9.20
 */
protected static synchronized I2PSession addSubsession(I2PTunnel tunnel) {
    I2PSession sess = socketManager.getSession();
    if (sess.getMyDestination().getSigType() == SigType.DSA_SHA1)
        return null;
    Properties props = new Properties();
    props.putAll(tunnel.getClientOptions());
    String name = props.getProperty("inbound.nickname");
    if (name != null)
        props.setProperty("inbound.nickname", name + " (DSA)");
    name = props.getProperty("outbound.nickname");
    if (name != null)
        props.setProperty("outbound.nickname", name + " (DSA)");
    props.setProperty(I2PClient.PROP_SIGTYPE, "DSA_SHA1");
    try {
        return socketManager.addSubsession(null, props);
    } catch (I2PSessionException ise) {
        Log log = tunnel.getContext().logManager().getLog(I2PTunnelClientBase.class);
        if (log.shouldLog(Log.WARN))
            log.warn("Failed to add subssession", ise);
        return null;
    }
}
Also used : Log(net.i2p.util.Log) I2PSession(net.i2p.client.I2PSession) I2PSessionException(net.i2p.client.I2PSessionException) Properties(java.util.Properties)

Aggregations

I2PSession (net.i2p.client.I2PSession)37 Properties (java.util.Properties)13 I2PSessionException (net.i2p.client.I2PSessionException)12 ByteArrayInputStream (java.io.ByteArrayInputStream)10 Destination (net.i2p.data.Destination)10 I2PClient (net.i2p.client.I2PClient)9 ByteArrayOutputStream (java.io.ByteArrayOutputStream)8 IOException (java.io.IOException)8 I2PException (net.i2p.I2PException)5 Hash (net.i2p.data.Hash)4 File (java.io.File)3 FileInputStream (java.io.FileInputStream)3 I2PSimpleClient (net.i2p.client.I2PSimpleClient)3 I2PSocket (net.i2p.client.streaming.I2PSocket)3 DataFormatException (net.i2p.data.DataFormatException)3 Log (net.i2p.util.Log)3 InterruptedIOException (java.io.InterruptedIOException)2 URI (java.net.URI)2 URISyntaxException (java.net.URISyntaxException)2 GeneralSecurityException (java.security.GeneralSecurityException)2