Changeset 05ffa63 for router


Ignore:
Timestamp:
Jun 2, 2018 3:05:24 PM (2 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
b5117ea
Parents:
06106c75
Message:

NTCP: Start NTCP2 implementation, all disabled for now

Location:
router/java/src/net/i2p
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • router/java/src/net/i2p/data/router/RouterInfo.java

    r06106c75 r05ffa63  
    487487        for (RouterAddress addr :  _addresses) {
    488488            if(addr.getTransportStyle().equals(transportStyle))
     489                ret.add(addr);
     490        }
     491        return ret;
     492    }
     493   
     494    /**
     495     *  For multiple addresses per-transport (IPv4 or IPv6)
     496     *  Return addresses matching either of two styles
     497     *
     498     *  @return non-null
     499     *  @since 0.9.35
     500     */
     501    public List<RouterAddress> getTargetAddresses(String transportStyle1, String transportStyle2) {
     502        List<RouterAddress> ret = new ArrayList<RouterAddress>(_addresses.size());
     503        for (RouterAddress addr :  _addresses) {
     504            String style = addr.getTransportStyle();
     505            if (style.equals(transportStyle1) || style.equals(transportStyle2))
    489506                ret.add(addr);
    490507        }
  • router/java/src/net/i2p/router/transport/TransportImpl.java

    r06106c75 r05ffa63  
    661661     */
    662662    protected List<RouterAddress> getTargetAddresses(RouterInfo target) {
    663         List<RouterAddress> rv = target.getTargetAddresses(getStyle());
     663        List<RouterAddress> rv;
     664        String alt = getAltStyle();
     665        if (alt != null)
     666            rv = target.getTargetAddresses(getStyle(), alt);
     667        else
     668            rv = target.getTargetAddresses(getStyle());
    664669        if (rv.isEmpty())
    665670            return rv;
    666         // Shuffle so everybody doesn't use the first one
    667         if (rv.size() > 1)
     671        if (rv.size() > 1) {
     672            // Shuffle so everybody doesn't use the first one
    668673            Collections.shuffle(rv, _context.random());
    669         TransportUtil.IPv6Config config = getIPv6Config();
    670         int adj;
    671         switch (config) {
    672               case IPV6_DISABLED:
    673                 adj = 10;
    674               /**** IPv6 addresses will be rejected in isPubliclyRoutable()
    675                 for (Iterator<RouterAddress> iter = rv.iterator(); iter.hasNext(); ) {
    676                     byte[] ip = iter.next().getIP();
    677                     if (ip != null && ip.length == 16)
    678                         iter.remove();
    679                 }
    680                ****/
    681                 break;
    682               case IPV6_NOT_PREFERRED:
    683                 adj = 1; break;
    684               default:
    685               case IPV6_ENABLED:
    686                 adj = 0; break;
    687               case IPV6_PREFERRED:
    688                 adj = -1; break;
    689               case IPV6_ONLY:
    690                 adj = -10;
    691               /**** IPv6 addresses will be rejected in isPubliclyRoutable()
    692                 for (Iterator<RouterAddress> iter = rv.iterator(); iter.hasNext(); ) {
    693                     byte[] ip = iter.next().getIP();
    694                     if (ip != null && ip.length == 4)
    695                         iter.remove();
    696                 }
    697                ****/
    698                 break;
    699         }
    700         if (rv.size() > 1)
     674            TransportUtil.IPv6Config config = getIPv6Config();
     675            int adj;
     676            switch (config) {
     677                  case IPV6_DISABLED:
     678                    adj = 10;
     679                  /**** IPv6 addresses will be rejected in isPubliclyRoutable()
     680                    for (Iterator<RouterAddress> iter = rv.iterator(); iter.hasNext(); ) {
     681                        byte[] ip = iter.next().getIP();
     682                        if (ip != null && ip.length == 16)
     683                            iter.remove();
     684                    }
     685                   ****/
     686                    break;
     687
     688                  case IPV6_NOT_PREFERRED:
     689                    adj = 1; break;
     690                  default:
     691
     692                  case IPV6_ENABLED:
     693                    adj = 0; break;
     694
     695                  case IPV6_PREFERRED:
     696                    adj = -1; break;
     697
     698                  case IPV6_ONLY:
     699                    adj = -10;
     700                  /**** IPv6 addresses will be rejected in isPubliclyRoutable()
     701                    for (Iterator<RouterAddress> iter = rv.iterator(); iter.hasNext(); ) {
     702                        byte[] ip = iter.next().getIP();
     703                        if (ip != null && ip.length == 4)
     704                            iter.remove();
     705                    }
     706                   ****/
     707                    break;
     708            }
    701709            Collections.sort(rv, new AddrComparator(adj));
     710        }
    702711        return rv;
    703712    }
     
    978987
    979988    /**
     989     * An alternate supported style, or null.
     990     * @return null, override to add support
     991     * @since 0.9.35
     992     */
     993    public String getAltStyle() { return null; }
     994
     995    /**
    980996     *  @since 0.9.3
    981997     */
  • router/java/src/net/i2p/router/transport/ntcp/EstablishBase.java

    r06106c75 r05ffa63  
    227227    }
    228228
     229    /**
     230     *  Get the NTCP version
     231     *  @return 1, 2, or 0 if unknown
     232     *  @since 0.9.35
     233     */
     234    public abstract int getVersion();
     235
    229236    /** Anything left over in the byte buffer after verification is extra
    230237     *
     
    338345        }
    339346
    340         @Override public void prepareOutbound() {
    341             Log log =RouterContext.getCurrentContext().logManager().getLog(VerifiedEstablishState.class);
     347        public int getVersion() { return 1; }
     348
     349        @Override
     350        public void prepareOutbound() {
     351            Log log = RouterContext.getCurrentContext().logManager().getLog(VerifiedEstablishState.class);
    342352            log.warn("prepareOutbound() on verified state, doing nothing!");
    343353        }
    344354
    345         @Override public String toString() { return "VerifiedEstablishState: ";}
     355        @Override
     356        public String toString() { return "VerifiedEstablishState: ";}
    346357    }
    347358
     
    356367        }
    357368
    358         @Override public void prepareOutbound() {
    359             Log log =RouterContext.getCurrentContext().logManager().getLog(VerifiedEstablishState.class);
     369        public int getVersion() { return 1; }
     370
     371        @Override
     372        public void prepareOutbound() {
     373            Log log = RouterContext.getCurrentContext().logManager().getLog(VerifiedEstablishState.class);
    360374            log.warn("prepareOutbound() on verified state, doing nothing!");
    361375        }
    362376
    363         @Override public String toString() { return "FailedEstablishState: ";}
     377        @Override
     378        public String toString() { return "FailedEstablishState: ";}
    364379    }
    365380
  • router/java/src/net/i2p/router/transport/ntcp/EstablishState.java

    r06106c75 r05ffa63  
    5151
    5252    /**
     53     *  Get the NTCP version
     54     *  @return 1, 2, or 0 if unknown
     55     *  @since 0.9.35
     56     */
     57    public int getVersion();
     58
     59    /**
    5360     *  Release resources on timeout.
    5461     *  @param e may be null
  • router/java/src/net/i2p/router/transport/ntcp/InboundEstablishState.java

    r06106c75 r05ffa63  
    2222/**
    2323 *
    24  *  We are Bob
     24 *  NTCP 1 or 2. We are Bob.
    2525 *
    2626 */
     
    6969        receiveInbound(src);
    7070    }
     71
     72    /**
     73     *  Get the NTCP version
     74     *  @return 1, 2, or 0 if unknown
     75     *  @since 0.9.35
     76     */
     77    public int getVersion() { return 1; }
    7178
    7279    /**
  • router/java/src/net/i2p/router/transport/ntcp/NTCPConnection.java

    r06106c75 r05ffa63  
    202202     * Create an outbound unconnected NTCP connection
    203203     *
    204      */
    205     public NTCPConnection(RouterContext ctx, NTCPTransport transport, RouterIdentity remotePeer, RouterAddress remAddr) {
     204     * @param version must be 1 or 2
     205     */
     206    public NTCPConnection(RouterContext ctx, NTCPTransport transport, RouterIdentity remotePeer,
     207                          RouterAddress remAddr, int version) {
    206208        _context = ctx;
    207209        _log = ctx.logManager().getLog(getClass());
     
    217219        _outbound = new PriBlockingQueue<OutNetMessage>(ctx, "NTCP-Connection", 32);
    218220        _isInbound = false;
    219         _establishState = new OutboundEstablishState(ctx, transport, this);
     221        //if (version == 1)
     222            _establishState = new OutboundEstablishState(ctx, transport, this);
     223        //else
     224        //    _establishState = // TODO
    220225        _decryptBlockBuf = new byte[BLOCK_SIZE];
    221226        _curReadState = new ReadState();
  • router/java/src/net/i2p/router/transport/ntcp/NTCPTransport.java

    r06106c75 r05ffa63  
    1515import java.util.Collections;
    1616import java.util.Comparator;
     17import java.util.HashMap;
    1718import java.util.HashSet;
    1819import java.util.Iterator;
     
    2021import java.util.Locale;
    2122import java.util.Map;
     23import java.util.Properties;
    2224import java.util.Set;
    2325import java.util.TreeSet;
     
    2628
    2729import net.i2p.crypto.SigType;
     30import net.i2p.data.Base64;
    2831import net.i2p.data.DataHelper;
    2932import net.i2p.data.Hash;
     
    105108    private static final long[] RATES = { 10*60*1000 };
    106109
    107     // Opera doesn't have the char, TODO check UA
    108     //private static final String THINSP = "&thinsp;/&thinsp;";
    109     private static final String THINSP = " / ";
    110 
    111110    /**
    112111     *  RI sigtypes supported in 0.9.16
     
    114113    public static final String MIN_SIGTYPE_VERSION = "0.9.16";
    115114
     115    // NTCP2 stuff
     116    public static final String STYLE = "NTCP";
     117    private static final String STYLE2 = "NTCP2";
     118    private static final String PROP_NTCP2_ENABLE = "i2np.ntcp2.enable";
     119    private static final boolean DEFAULT_NTCP2_ENABLE = false;
     120    private boolean _enableNTCP2;
     121    private static final String NTCP2_PROTO_SHORT = "NXK2CS";
     122    private static final String OPT_NTCP2_SK = 'N' + NTCP2_PROTO_SHORT + "2s";
     123    private static final int NTCP2_INT_VERSION = 2;
     124    private static final String NTCP2_VERSION = Integer.toString(NTCP2_INT_VERSION);
     125    /** b64 static private key */
     126    private static final String PROP_NTCP2_SP = "i2np.ntcp2.sp";
     127    /** b64 static IV */
     128    private static final String PROP_NTCP2_IV = "i2np.ntcp2.iv";
     129    private static final int NTCP2_IV_LEN = 16;
     130    private static final int NTCP2_KEY_LEN = 32;
     131    private final byte[] _ntcp2StaticPrivkey;
     132    private final byte[] _ntcp2StaticIV;
     133    private final String _b64Ntcp2StaticPubkey;
     134    private final String _b64Ntcp2StaticIV;
    116135
    117136    public NTCPTransport(RouterContext ctx, DHSessionKeyBuilder.Factory dh) {
     
    203222        _nearCapacityCostBid = new SharedBid(105);
    204223        _transientFail = new SharedBid(TransportBid.TRANSIENT_FAIL);
     224
     225        _enableNTCP2 = ctx.getProperty(PROP_NTCP2_ENABLE, DEFAULT_NTCP2_ENABLE);
     226        if (_enableNTCP2) {
     227            boolean shouldSave = false;
     228            byte[] priv = null;
     229            byte[] iv = null;
     230            String b64Pub = null;
     231            String b64IV = null;
     232            String s = ctx.getProperty(PROP_NTCP2_SP);
     233            if (s != null) {
     234                priv = Base64.decode(s);
     235            }
     236            if (priv == null || priv.length != NTCP2_KEY_LEN) {
     237                priv = new byte[NTCP2_KEY_LEN];
     238                ctx.random().nextBytes(priv);
     239                shouldSave = true;
     240            }
     241            s = ctx.getProperty(PROP_NTCP2_IV);
     242            if (s != null) {
     243                iv = Base64.decode(s);
     244                b64IV = s;
     245            }
     246            if (iv == null || iv.length != NTCP2_IV_LEN) {
     247                iv = new byte[NTCP2_IV_LEN];
     248                ctx.random().nextBytes(iv);
     249                shouldSave = true;
     250            }
     251            if (shouldSave) {
     252                Map<String, String> changes = new HashMap<String, String>(2);
     253                String b64Priv = Base64.encode(priv);
     254                b64IV = Base64.encode(iv);
     255                changes.put(PROP_NTCP2_SP, b64Priv);
     256                changes.put(PROP_NTCP2_IV, b64IV);
     257                ctx.router().saveConfig(changes, null);
     258            }
     259            _ntcp2StaticPrivkey = priv;
     260            _ntcp2StaticIV = iv;
     261            _b64Ntcp2StaticPubkey = "TODO"; // priv->pub
     262            _b64Ntcp2StaticIV = b64IV;
     263        } else {
     264            _ntcp2StaticPrivkey = null;
     265            _ntcp2StaticIV = null;
     266            _b64Ntcp2StaticPubkey = null;
     267            _b64Ntcp2StaticIV = null;
     268        }
    205269    }
    206270
     
    243307                    RouterAddress addr = getTargetAddress(target);
    244308                    if (addr != null) {
    245                         con = new NTCPConnection(_context, this, ident, addr);
    246                         //if (_log.shouldLog(Log.DEBUG))
    247                         //    _log.debug("Send on a new con: " + con + " at " + addr + " for " + ih);
    248                         // Note that outbound conns go in the map BEFORE establishment
    249                         _conByIdent.put(ih, con);
     309                        int ver = getNTCPVersion(addr);
     310                        if (ver != 0) {
     311                            con = new NTCPConnection(_context, this, ident, addr, ver);
     312                            //if (_log.shouldLog(Log.DEBUG))
     313                            //    _log.debug("Send on a new con: " + con + " at " + addr + " for " + ih);
     314                            // Note that outbound conns go in the map BEFORE establishment
     315                            _conByIdent.put(ih, con);
     316                        } else {
     317                            fail = true;
     318                        }
    250319                    } else {
    251320                        // race, RI changed out from under us
     
    675744                props.setProperty(RouterAddress.PROP_HOST, ia.getHostAddress());
    676745                props.setProperty(RouterAddress.PROP_PORT, Integer.toString(port));
     746                addNTCP2Options(props);
    677747                int cost = getDefaultCost(ia instanceof Inet6Address);
    678748                myAddress = new RouterAddress(STYLE, props, cost);
     
    787857                    props.setProperty(RouterAddress.PROP_HOST, bindTo);
    788858                    props.setProperty(RouterAddress.PROP_PORT, Integer.toString(port));
     859                    addNTCP2Options(props);
    789860                    int cost = getDefaultCost(false);
    790861                    myAddress = new RouterAddress(STYLE, props, cost);
     
    874945
    875946    /**
     947     * An alternate supported style, or null.
     948     * @return "NTCP2" or null
     949     * @since 0.9.35
     950     */
     951    @Override
     952    public String getAltStyle() {
     953        return _enableNTCP2 ? STYLE2 : null;
     954    }
     955
     956    /**
    876957     *  Hook for NTCPConnection
    877958     */
     
    9831064        props.setProperty(RouterAddress.PROP_HOST, name);
    9841065        props.setProperty(RouterAddress.PROP_PORT, Integer.toString(p));
     1066        addNTCP2Options(props);
    9851067        int cost = getDefaultCost(false);
    9861068        RouterAddress addr = new RouterAddress(STYLE, props, cost);
    9871069        return addr;
     1070    }
     1071
     1072    /**
     1073     * Add the required options to the properties for a NTCP2 address
     1074     *
     1075     * @since 0.9.35
     1076     */
     1077    private void addNTCP2Options(Properties props) {
     1078        if (!_enableNTCP2)
     1079            return;
     1080        props.setProperty("i", _b64Ntcp2StaticIV);
     1081        props.setProperty("n", NTCP2_PROTO_SHORT);
     1082        props.setProperty("s", _b64Ntcp2StaticPubkey);
     1083        props.setProperty("v", NTCP2_VERSION);
     1084    }
     1085
     1086    /**
     1087     * Is NTCP2 enabled?
     1088     *
     1089     * @since 0.9.35
     1090     */
     1091    boolean isNTCP2Enabled() { return _enableNTCP2; }
     1092
     1093    /**
     1094     * Get the valid NTCP version of this NTCP address.
     1095     *
     1096     * @return the valid version 1 or 2, or 0 if unusable
     1097     * @since 0.9.35
     1098     */
     1099    private int getNTCPVersion(RouterAddress addr) {
     1100        int rv;
     1101        String style = addr.getTransportStyle();
     1102        if (style.equals(STYLE)) {
     1103            if (!_enableNTCP2)
     1104                return 1;
     1105            rv = 1;
     1106        } else if (style.equals(STYLE2)) {
     1107            if (!_enableNTCP2)
     1108                return 0;
     1109            rv = 2;
     1110        } else {
     1111            return 0;
     1112        }
     1113        if (addr.getOption("s") == null ||
     1114            addr.getOption("i") == null ||
     1115            !NTCP2_VERSION.equals(addr.getOption("v")) ||
     1116            !NTCP2_PROTO_SHORT.equals(addr.getOption("n"))) {
     1117            return (rv == 1) ? 1 : 0;
     1118        }
     1119        // todo validate s/i b64, or just catch it later?
     1120        return rv;
    9881121    }
    9891122
     
    11721305        if (oldAddr == null) {
    11731306            cost = getDefaultCost(isIPv6);
     1307            addNTCP2Options(newProps);
    11741308        } else {
    11751309            cost = oldAddr.getCost();
     
    14641598    }
    14651599
    1466     public static final String STYLE = "NTCP";
    1467 
    14681600    public void renderStatusHTML(java.io.Writer out, int sortFlags) throws IOException {}
    14691601
  • router/java/src/net/i2p/router/transport/ntcp/OutboundEstablishState.java

    r06106c75 r05ffa63  
    1919/**
    2020 *
    21  *  We are Alice
     21 *  NTCP 1 only. We are Alice.
    2222 *
    2323 */
     
    4848        receiveOutbound(src);
    4949    }
     50
     51    /**
     52     *  Get the NTCP version
     53     *  @return 1
     54     *  @since 0.9.35
     55     */
     56    public int getVersion() { return 1; }
    5057
    5158    /**
Note: See TracChangeset for help on using the changeset viewer.