<commit_before>package net.i2p.router.tunnelmanager;
/*
 * free (adj.): unencumbered; not under the control of others
 * Written by jrandom in 2003 and released into the public domain 
 * with no warranty of any kind, either expressed or implied.  
 * It probably won't make your computer catch on fire, or eat 
 * your children, but it might.  Use at your own risk.
 *
 */

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import net.i2p.crypto.KeyGenerator;
import net.i2p.crypto.SessionKeyManager;
import net.i2p.data.Certificate;
import net.i2p.data.DataFormatException;
import net.i2p.data.Hash;
import net.i2p.data.PublicKey;
import net.i2p.data.RouterInfo;
import net.i2p.data.SessionKey;
import net.i2p.data.SessionTag;
import net.i2p.data.TunnelId;
import net.i2p.data.i2np.DeliveryInstructions;
import net.i2p.data.i2np.DeliveryStatusMessage;
import net.i2p.data.i2np.GarlicMessage;
import net.i2p.data.i2np.I2NPMessage;
import net.i2p.data.i2np.SourceRouteBlock;
import net.i2p.data.i2np.TunnelCreateMessage;
import net.i2p.data.i2np.TunnelCreateStatusMessage;
import net.i2p.router.Job;
import net.i2p.router.JobImpl;
import net.i2p.router.JobQueue;
import net.i2p.router.MessageHistory;
import net.i2p.router.MessageSelector;
import net.i2p.router.NetworkDatabaseFacade;
import net.i2p.router.PeerManagerFacade;
import net.i2p.router.PeerSelectionCriteria;
import net.i2p.router.ProfileManager;
import net.i2p.router.ReplyJob;
import net.i2p.router.Router;
import net.i2p.router.TunnelInfo;
import net.i2p.router.TunnelManagerFacade;
import net.i2p.router.TunnelSelectionCriteria;
import net.i2p.router.message.GarlicConfig;
import net.i2p.router.message.GarlicMessageBuilder;
import net.i2p.router.message.PayloadGarlicConfig;
import net.i2p.router.message.SendTunnelMessageJob;
import net.i2p.stat.StatManager;
import net.i2p.util.Clock;
import net.i2p.util.Log;
import net.i2p.util.RandomSource;
import net.i2p.router.RouterContext;

/**
 * Request the creation of a new tunnel
 *
 */
public class RequestTunnelJob extends JobImpl {
    private Log _log;
    private TunnelPool _pool;
    private boolean _complete;
    private long _timeoutMs;
    private long _expiration;
    private TunnelInfo _tunnelGateway;
    private List _toBeRequested;            // list of participants, from endpoint to gateway
    private Set _failedTunnelParticipants;  // set of Hash of the RouterIdentity of participants who timed out or rejected
    private boolean _isInbound;
    
    private final static int PRIORITY = 300; // high since we are creating tunnels for a client
    
    RequestTunnelJob(RouterContext context, TunnelPool pool, TunnelInfo tunnelGateway, boolean isInbound, long timeoutMs) {
        super(context);
        _log = context.logManager().getLog(RequestTunnelJob.class);
        context.statManager().createFrequencyStat("tunnel.buildFrequency", "How often does the router build a tunnel?", "Tunnels", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l });
        context.statManager().createFrequencyStat("tunnel.buildFailFrequency", "How often does a peer in the tunnel fail to join??", "Tunnels", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l });

        _pool = pool;
        _tunnelGateway = tunnelGateway;
        _toBeRequested = new ArrayList();
        _timeoutMs = timeoutMs;
        _expiration = -1;
        _isInbound = isInbound;
        _failedTunnelParticipants = new HashSet();
        _complete = false;
            
        List participants = new ArrayList();
        TunnelInfo cur = _tunnelGateway;
        while (cur != null) {
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("Tunnel " + cur.getTunnelId() + " includes " + cur.getThisHop().toBase64());
            participants.add(cur);
            cur = cur.getNextHopInfo();
        }
        if (isInbound) {
            if (_log.shouldLog(Log.INFO))
                _log.info("Requesting inbound tunnel " + _tunnelGateway.getTunnelId() + " with " 
                          + participants.size() + " participants in it");
        } else {
            if (_log.shouldLog(Log.INFO))
                _log.info("Requesting outbound tunnel " + _tunnelGateway.getTunnelId() + " with " + participants.size() + " participants in it");
        }

        // since we request serially, we need to up the timeout serially
        // change this once we go parallel
        _timeoutMs *= participants.size()+1;

        // work backwards (end point, then the router pointing at the endpoint, then the router pointing at that, etc, until the gateway
        _toBeRequested = new ArrayList(participants.size());
        for (int i = participants.size()-1; i >= 0; i--) 
            _toBeRequested.add(participants.get(i));
    }
    
    public String getName() { return "Request Tunnel"; }
    public void runJob() {
        if (_expiration < 0) _expiration = _timeoutMs + _context.clock().now();
        if (_context.clock().now() > _expiration) {
            if (_log.shouldLog(Log.WARN))
                _log.warn("Timeout reached building tunnel (timeout = " + _timeoutMs + " expiration = " + new Date(_expiration) + ")");
            fail();
            return;
        }

        TunnelInfo peer = null;
        synchronized (_toBeRequested) {<commit_msg>make sure we only try to request from people we know about (*cough*)<commit_after>package net.i2p.router.tunnelmanager;
/*
 * free (adj.): unencumbered; not under the control of others
 * Written by jrandom in 2003 and released into the public domain 
 * with no warranty of any kind, either expressed or implied.  
 * It probably won't make your computer catch on fire, or eat 
 * your children, but it might.  Use at your own risk.
 *
 */

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import net.i2p.crypto.KeyGenerator;
import net.i2p.crypto.SessionKeyManager;
import net.i2p.data.Certificate;
import net.i2p.data.DataFormatException;
import net.i2p.data.Hash;
import net.i2p.data.PublicKey;
import net.i2p.data.RouterInfo;
import net.i2p.data.SessionKey;
import net.i2p.data.SessionTag;
import net.i2p.data.TunnelId;
import net.i2p.data.i2np.DeliveryInstructions;
import net.i2p.data.i2np.DeliveryStatusMessage;
import net.i2p.data.i2np.GarlicMessage;
import net.i2p.data.i2np.I2NPMessage;
import net.i2p.data.i2np.SourceRouteBlock;
import net.i2p.data.i2np.TunnelCreateMessage;
import net.i2p.data.i2np.TunnelCreateStatusMessage;
import net.i2p.router.Job;
import net.i2p.router.JobImpl;
import net.i2p.router.JobQueue;
import net.i2p.router.MessageHistory;
import net.i2p.router.MessageSelector;
import net.i2p.router.NetworkDatabaseFacade;
import net.i2p.router.PeerManagerFacade;
import net.i2p.router.PeerSelectionCriteria;
import net.i2p.router.ProfileManager;
import net.i2p.router.ReplyJob;
import net.i2p.router.Router;
import net.i2p.router.TunnelInfo;
import net.i2p.router.TunnelManagerFacade;
import net.i2p.router.TunnelSelectionCriteria;
import net.i2p.router.message.GarlicConfig;
import net.i2p.router.message.GarlicMessageBuilder;
import net.i2p.router.message.PayloadGarlicConfig;
import net.i2p.router.message.SendTunnelMessageJob;
import net.i2p.stat.StatManager;
import net.i2p.util.Clock;
import net.i2p.util.Log;
import net.i2p.util.RandomSource;
import net.i2p.router.RouterContext;

/**
 * Request the creation of a new tunnel
 *
 */
public class RequestTunnelJob extends JobImpl {
    private Log _log;
    private TunnelPool _pool;
    private boolean _complete;
    private long _timeoutMs;
    private long _expiration;
    private TunnelInfo _tunnelGateway;
    private List _toBeRequested;            // list of participants, from endpoint to gateway
    private Set _failedTunnelParticipants;  // set of Hash of the RouterIdentity of participants who timed out or rejected
    private boolean _isInbound;
    
    private final static int PRIORITY = 300; // high since we are creating tunnels for a client
    
    RequestTunnelJob(RouterContext context, TunnelPool pool, TunnelInfo tunnelGateway, boolean isInbound, long timeoutMs) {
        super(context);
        _log = context.logManager().getLog(RequestTunnelJob.class);
        context.statManager().createFrequencyStat("tunnel.buildFrequency", "How often does the router build a tunnel?", "Tunnels", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l });
        context.statManager().createFrequencyStat("tunnel.buildFailFrequency", "How often does a peer in the tunnel fail to join??", "Tunnels", new long[] { 60*1000l, 60*60*1000l, 24*60*60*1000l });

        _pool = pool;
        _tunnelGateway = tunnelGateway;
        _timeoutMs = timeoutMs;
        _expiration = -1;
        _isInbound = isInbound;
        _failedTunnelParticipants = new HashSet();
        _complete = false;
            
        List participants = new ArrayList();
        TunnelInfo cur = _tunnelGateway;
        while (cur != null) {
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("Tunnel " + cur.getTunnelId() + " includes " + cur.getThisHop().toBase64());
            participants.add(cur);
            cur = cur.getNextHopInfo();
        }
        if (isInbound) {
            if (_log.shouldLog(Log.INFO))
                _log.info("Requesting inbound tunnel " + _tunnelGateway.getTunnelId() + " with " 
                          + participants.size() + " participants in it");
        } else {
            if (_log.shouldLog(Log.INFO))
                _log.info("Requesting outbound tunnel " + _tunnelGateway.getTunnelId() + " with " + participants.size() + " participants in it");
        }

        // since we request serially, we need to up the timeout serially
        // change this once we go parallel
        _timeoutMs *= participants.size()+1;

        // work backwards (end point, then the router pointing at the endpoint, then the router pointing at that, etc, until the gateway
        _toBeRequested = new ArrayList(participants.size());
        for (int i = participants.size()-1; i >= 0; i--) {
            TunnelInfo peer = (TunnelInfo)participants.get(i);
            if (null != _context.netDb().lookupRouterInfoLocally(peer.getThisHop())) {
                _toBeRequested.add(participants.get(i));
            } else {
                if (_log.shouldLog(Log.WARN))
                    _log.warn("ok who the fuck requested someone we don't know about? (dont answer that");
            }
        }
    }
    
    public String getName() { return "Request Tunnel"; }
    public void runJob() {
        if (_expiration < 0) _expiration = _timeoutMs + _context.clock().now();
        if (_context.clock().now() > _expiration) {
            if (_log.shouldLog(Log.WARN))
                _log.warn("Timeout reached building tunnel (timeout = " + _timeoutMs + " expiration = " + new Date(_expiration) + ")");
            fail();
            return;
        }

        TunnelInfo peer = null;
        synchronized (_toBeRequested) {
{'fraction_non_alphanumeric': 0.10512683101107538, 'fraction_numerical': 0.01982851018220793, 'mean_word_length': 3.170204841713222, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 1, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7660397', 'n_tokens_mistral': 3563, 'n_tokens_neox': 3411, 'n_words': 863}