Changeset 38b930c for router


Ignore:
Timestamp:
Jun 4, 2016 1:00:36 PM (4 years ago)
Author:
zzz <zzz@…>
Branches:
master
Children:
126a4d8
Parents:
2eb89e93 (diff), 34c611d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

propagate from branch 'i2p.i2p' (head eb2151f9d804ec432bfe97214896ee62da08943e)

to branch 'i2p.i2p.zzz.test2' (head 2ea50c5f22fe1e24d37dff2f283b77feaa9190ee)

Location:
router/java
Files:
7 added
1 deleted
16 edited

Legend:

Unmodified
Added
Removed
  • router/java/build.xml

    r2eb89e93 r38b930c  
    1717            <classpath>
    1818                <pathelement location="../../core/java/build/obj" />
     19                <pathelement location="../../core/java/build/gnu-getopt.jar" />
     20                <pathelement location="../../core/java/build/httpclient.jar" />
     21                <pathelement location="../../core/java/build/httpcore.jar" />
    1922            </classpath>
    2023        </depend>
     
    3942               debuglevel="lines,vars,source"
    4043               includeAntRuntime="false"
    41                destdir="./build/obj" classpath="../../core/java/build/obj:../../core/java/build/i2p.jar" >
     44               destdir="./build/obj" classpath="../../core/java/build/obj:../../core/java/build/i2p.jar:../../core/java/build/gnu-getopt.jar:../../core/java/build/httpclient.jar:../../core/java/build/httpcore.jar" >
    4245            <compilerarg line="${javac.compilerargs}" />
    4346        </javac>
  • router/java/src/net/i2p/data/router/RouterInfo.java

    r2eb89e93 r38b930c  
    504504            if (log.shouldWarn()) {
    505505                log.warn("Sig verify fail: " + toString(), new Exception("from"));
    506             } else {
    507                 log.error("RI Sig verify fail: " + _identity.getHash());
     506            //} else {
     507            //    log.error("RI Sig verify fail: " + _identity.getHash());
    508508            }
    509509        }
  • router/java/src/net/i2p/router/CommandLine.java

    r2eb89e93 r38b930c  
    1515
    1616    protected static final List<String> RCLASSES = Arrays.asList(new String[] {
     17        "net.i2p.data.router.RouterInfo",
    1718        "net.i2p.router.MultiRouter",
    1819        "net.i2p.router.Router",
  • router/java/src/net/i2p/router/RouterVersion.java

    r2eb89e93 r38b930c  
    1919    public final static String ID = "Monotone";
    2020    public final static String VERSION = CoreVersion.VERSION;
    21     public final static long BUILD = 13;
     21    public final static long BUILD = 17;
    2222
    2323    /** for example "-test" */
  • router/java/src/net/i2p/router/client/ClientManager.java

    r2eb89e93 r38b930c  
    1111import java.io.IOException;
    1212import java.io.Writer;
     13import java.lang.reflect.Constructor;
     14import java.lang.reflect.InvocationTargetException;
    1315import java.util.ArrayList;
    1416import java.util.Collections;
     
    124126        ClientListenerRunner listener;
    125127        if (SystemVersion.isAndroid()) {
    126             listener = new DomainClientListenerRunner(_ctx, this);
    127             Thread t = new I2PThread(listener, "DomainClientListener", true);
    128             t.start();
    129             _listeners.add(listener);
     128            try {
     129                Class<? extends ClientListenerRunner> clazz = Class.forName(
     130                        "net.i2p.router.client.DomainClientListenerRunner"
     131                    ).asSubclass(ClientListenerRunner.class);
     132                Constructor<? extends ClientListenerRunner> ctor =
     133                    clazz.getDeclaredConstructor(RouterContext.class,
     134                                                 ClientManager.class);
     135                listener = ctor.newInstance(_ctx, this);
     136                Thread t = new I2PThread(listener, "DomainClientListener", true);
     137                t.start();
     138                _listeners.add(listener);
     139            } catch (ClassNotFoundException e) {
     140                _log.warn("Could not find DomainClientListenerRunner class", e);
     141            } catch (ClassCastException e) {
     142                _log.error("Error creating DomainClientListenerRunner", e);
     143            } catch (NoSuchMethodException e) {
     144                _log.error("Error creating DomainClientListenerRunner", e);
     145            } catch (InstantiationException e) {
     146                _log.error("Error creating DomainClientListenerRunner", e);
     147            } catch (IllegalAccessException e) {
     148                _log.error("Error creating DomainClientListenerRunner", e);
     149            } catch (InvocationTargetException e) {
     150                _log.error("Error creating DomainClientListenerRunner", e);
     151            }
    130152        }
    131153        if (!_ctx.getBooleanProperty(PROP_DISABLE_EXTERNAL)) {
  • router/java/src/net/i2p/router/client/ClientMessageEventListener.java

    r2eb89e93 r38b930c  
    408408     * The client asked for a message, so we send it to them. 
    409409     *
     410     * This is only when not in fast receive mode.
     411     * In the default fast receive mode, data is sent in MessageReceivedJob.
    410412     */
    411413    private void handleReceiveBegin(ReceiveMessageBeginMessage message) {
     
    428430            _runner.doSend(msg);
    429431        } catch (I2CPMessageException ime) {
    430             if (_log.shouldLog(Log.WARN))
    431                 _log.warn("Error delivering the payload", ime);
     432            String emsg = "Error sending data to client " + _runner.getDestHash();
     433            if (_log.shouldWarn())
     434                _log.warn(emsg, ime);
     435            else
     436                _log.logAlways(Log.WARN, emsg);
    432437            _runner.removePayload(new MessageId(message.getMessageId()));
    433438        }
  • router/java/src/net/i2p/router/client/MessageReceivedJob.java

    r2eb89e93 r38b930c  
    6161            }
    6262        } catch (I2CPMessageException ime) {
    63             if (_log.shouldLog(Log.WARN))
    64                 _log.warn("Error writing out the message", ime);
     63            String msg = "Error sending data to client " + _runner.getDestHash();
     64            if (_log.shouldWarn())
     65                _log.warn(msg, ime);
     66            else
     67                _log.logAlways(Log.WARN, msg);
    6568            if (id != null && !_sendDirect)
    6669                _runner.removePayload(id);
  • router/java/src/net/i2p/router/networkdb/reseed/Reseeder.java

    r2eb89e93 r38b930c  
    6464    /** if false, use su3 only, and disable fallback reading directory index and individual dat files */
    6565    private static final boolean ENABLE_NON_SU3 = false;
     66    private static final int MIN_RI_WANTED = 100;
     67    private static final int MIN_RESEED_SERVERS = 2;
    6668
    6769    /**
     
    8486              "";
    8587
    86     /** @since 0.8.2 */
     88    /**
     89     *  The I2P reseed servers are managed by backup (backup@mail.i2p).
     90     *  Please contact him for support, change requests, or issues.
     91     *  See also the reseed forum http://zzz.i2p/forums/18
     92     *  and the reseed setup and testing guide
     93     *  https://geti2p.net/en/get-involved/guides/reseed
     94     *
     95     *  All supported reseed hosts need a corresponding reseed (SU3)
     96     *  signing certificate installed in the router.
     97     *
     98     *  All supported reseed hosts with selfsigned SSL certificates
     99     *  need the corresponding SSL certificate installed in the router.
     100     *
     101     *  While this implementation supports SNI, others may not, so
     102     *  SNI requirements are noted.
     103     *
     104     * @since 0.8.2
     105     */
    87106    public static final String DEFAULT_SSL_SEED_URL =
    88               "https://reseed.i2p-projekt.de/" + "," + // Only HTTPS
    89               "https://i2p.mooo.com/netDb/" + "," +
    90               "https://netdb.i2p2.no/" + "," + // Only SU3 (v3) support, SNI required
    91               "https://us.reseed.i2p2.no:444/" + "," +
    92               "https://uk.reseed.i2p2.no:444/" + "," +
    93               //"https://www.torontocrypto.org:8443/" + "," +
    94               "https://i2p.manas.ca:8443/" + "," +
    95               "https://i2p-0.manas.ca:8443/" + "," +
    96               "https://reseed.i2p.vzaws.com:8443/" + ", " + // Only SU3 (v3) support
    97               "https://user.mx24.eu/" + "," + // Only HTTPS and SU3 (v3) support
    98               "https://download.xxlspeed.com/"; // Only HTTPS and SU3 (v3) support
     107        // newest first, please add new ones at the top
     108        //
     109        // https url:port, ending with "/"              // certificates/reseed/      // certificates/ssl/          // notes
     110        // ----------------------------------           ------------------------     -------------------------     ---------------
     111        "https://i2p.manas.ca:8443/"          + ',' +   // zmx_at_mail.i2p.crt       // CA                         // SNI required
     112        "https://i2p-0.manas.ca:8443/"        + ',' +   // zmx_at_mail.i2p.crt       // CA                         // SNI required
     113        "https://reseed.i2p.vzaws.com:8443/"  + ',' +   // parg_at_mail.i2p.crt      // reseed.i2p.vzaws.com.crt
     114        "https://i2p.mooo.com/netDb/"         + ',' +   // bugme_at_mail.i2p.crt     // i2p.mooo.com.crt
     115        "https://user.mx24.eu/"               + ',' +   // backup_at_mail.i2p.crt    // user.mx24.eu.crt
     116        "https://download.xxlspeed.com/"      + ',' +   // backup_at_mail.i2p.crt    // download.xxlspeed.com.crt  // SNI required
     117        "https://netdb.i2p2.no/"              + ',' +   // meeh_at_mail.i2p.crt      // netdb.i2p2.no.crt          // SNI required
     118        "https://us.reseed.i2p2.no:444/"      + ',' +   // meeh_at_mail.i2p.crt      // us.reseed.i2p2.no.crt
     119        "https://uk.reseed.i2p2.no:444/"      + ',' +   // meeh_at_mail.i2p.crt      // uk.reseed.i2p2.no.crt
     120        "https://reseed.i2p-projekt.de/";               // echelon_at_mail.i2p.crt   // reseed.i2p-projekt.de.crt
    99121
    100122    private static final String SU3_FILENAME = "i2pseeds.su3";
     
    222244     *  which is the lowest Android we support anyway.
    223245     *
     246     *  Not guaranteed to be correct, e.g. FreeBSD:
     247     *  https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=201446
     248     *
    224249     *  @since 0.9.20
    225250     */
     
    481506            if (!isSNISupported()) {
    482507                try {
     508                    URLList.remove(new URI("https://i2p.manas.ca:8443/"));
     509                    URLList.remove(new URI("https://i2p-0.manas.ca:8443/"));
     510                    URLList.remove(new URI("https://download.xxlspeed.com/"));
    483511                    URLList.remove(new URI("https://netdb.i2p2.no/"));
    484512                } catch (URISyntaxException mue) {}
     
    502530        private int reseed(List<URI> URLList, boolean echoStatus) {
    503531            int total = 0;
     532            int fetched_reseed_servers = 0;
    504533            for (int i = 0; i < URLList.size() && _isRunning; i++) {
    505534                if (_context.router().gracefulShutdownInProgress()) {
     
    520549                if (dl > 0) {
    521550                    total += dl;
     551                    fetched_reseed_servers++;
    522552                    // Don't go on to the next URL if we have enough
    523                     if (total >= 100)
     553                    if (total >= MIN_RI_WANTED && fetched_reseed_servers >= MIN_RESEED_SERVERS)
    524554                        break;
    525555                    // remove alternate versions if we haven't tried them yet
  • router/java/src/net/i2p/router/tasks/InstallUpdate.java

    r2eb89e93 r38b930c  
    136136                         osName.contains("linux") || osName.contains("freebsd");
    137137
    138         // only do this on these x86
    139138        File jbigiJar = new File(context.getBaseDir(), "lib/jbigi.jar");
    140         if (isX86 && goodOS && jbigiJar.exists()) {
     139        if (goodOS && jbigiJar.exists()) {
    141140            String libPrefix = (isWin ? "" : "lib");
    142141            String libSuffix = (isWin ? ".dll" : isMac ? ".jnilib" : ".so");
    143142
    144             File jcpuidLib = new File(context.getBaseDir(), libPrefix + "jcpuid" + libSuffix);
    145             if (jcpuidLib.canWrite() && jbigiJar.lastModified() > jcpuidLib.lastModified()) {
    146                 String path = jcpuidLib.getAbsolutePath();
    147                 boolean success = FileUtil.copy(path, path + ".bak", true, true);
    148                 if (success) {
    149                     boolean success2 = jcpuidLib.delete();
    150                     if (success2) {
    151                         System.out.println("New jbigi.jar detected, moved jcpuid library to " +
    152                                            path + ".bak");
    153                         System.out.println("Check logs for successful installation of new library");
    154                     }
    155                 }
    156             }
    157 
    158             File jbigiLib = new File(context.getBaseDir(), libPrefix + "jbigi" + libSuffix);
    159             if (jbigiLib.canWrite() && jbigiJar.lastModified() > jbigiLib.lastModified()) {
    160                 String path = jbigiLib.getAbsolutePath();
    161                 boolean success = FileUtil.copy(path, path + ".bak", true, true);
    162                 if (success) {
    163                     boolean success2 = jbigiLib.delete();
    164                     if (success2) {
    165                         System.out.println("New jbigi.jar detected, moved jbigi library to " +
    166                                            path + ".bak");
    167                         System.out.println("Check logs for successful installation of new library");
     143            if (isX86) {
     144                File jcpuidLib = new File(context.getBaseDir(), libPrefix + "jcpuid" + libSuffix);
     145                if (jcpuidLib.canWrite() && jbigiJar.lastModified() > jcpuidLib.lastModified()) {
     146                    String path = jcpuidLib.getAbsolutePath();
     147                    boolean success = FileUtil.copy(path, path + ".bak", true, true);
     148                    if (success) {
     149                        boolean success2 = jcpuidLib.delete();
     150                        if (success2) {
     151                            System.out.println("New jbigi.jar detected, moved jcpuid library to " +
     152                                               path + ".bak");
     153                            System.out.println("Check logs for successful installation of new library");
     154                        }
     155                    }
     156                }
     157            }
     158
     159            if (isX86 || SystemVersion.isARM()) {
     160                File jbigiLib = new File(context.getBaseDir(), libPrefix + "jbigi" + libSuffix);
     161                if (jbigiLib.canWrite() && jbigiJar.lastModified() > jbigiLib.lastModified()) {
     162                    String path = jbigiLib.getAbsolutePath();
     163                    boolean success = FileUtil.copy(path, path + ".bak", true, true);
     164                    if (success) {
     165                        boolean success2 = jbigiLib.delete();
     166                        if (success2) {
     167                            System.out.println("New jbigi.jar detected, moved jbigi library to " +
     168                                               path + ".bak");
     169                            System.out.println("Check logs for successful installation of new library");
     170                        }
    168171                    }
    169172                }
  • router/java/src/net/i2p/router/time/NtpClient.java

    r2eb89e93 r38b930c  
    3737import java.util.Collections;
    3838
     39import net.i2p.data.DataHelper;
     40import net.i2p.util.HexDump;
     41import net.i2p.util.Log;
    3942
    4043/**
     
    5457class NtpClient {
    5558    /** difference between the unix epoch and jan 1 1900 (NTP uses that) */
    56     private final static double SECONDS_1900_TO_EPOCH = 2208988800.0;
     59    public final static double SECONDS_1900_TO_EPOCH = 2208988800.0;
    5760    private final static int NTP_PORT = 123;
    5861    private static final int DEFAULT_TIMEOUT = 10*1000;
     62    private static final int OFF_ORIGTIME = 24;
     63    private static final int OFF_TXTIME = 40;
     64    private static final int MIN_PKT_LEN = 48;
    5965
    6066    /**
     
    6470     * @throws IllegalArgumentException if none of the servers are reachable
    6571     */
     72/****
    6673    public static long currentTime(String serverNames[]) {
    6774        if (serverNames == null)
     
    7885        throw new IllegalArgumentException("No reachable NTP servers specified");
    7986    }
     87****/
    8088   
    8189    /**
    8290     * Query the ntp servers, returning the current time from first one we find
    8391     * Hack to return time and stratum
     92     *
     93     * @param log may be null
    8494     * @return time in rv[0] and stratum in rv[1]
    8595     * @throws IllegalArgumentException if none of the servers are reachable
    8696     * @since 0.7.12
    8797     */
    88     public static long[] currentTimeAndStratum(String serverNames[], int perServerTimeout) {
     98    public static long[] currentTimeAndStratum(String serverNames[], int perServerTimeout, Log log) {
    8999        if (serverNames == null)
    90100            throw new IllegalArgumentException("No NTP servers specified");
     
    94104        Collections.shuffle(names);
    95105        for (int i = 0; i < names.size(); i++) {
    96             long[] rv = currentTimeAndStratum(names.get(i), perServerTimeout);
     106            long[] rv = currentTimeAndStratum(names.get(i), perServerTimeout, log);
    97107            if (rv != null && rv[0] > 0)
    98108                return rv;
     
    106116     * @return milliseconds since january 1, 1970 (UTC), or -1 on error
    107117     */
     118/****
    108119    public static long currentTime(String serverName) {
    109120         long[] la = currentTimeAndStratum(serverName, DEFAULT_TIMEOUT);
     
    112123         return -1;
    113124    }
     125****/
    114126
    115127    /**
    116128     * Hack to return time and stratum
     129     *
     130     * @param log may be null
    117131     * @return time in rv[0] and stratum in rv[1], or null for error
    118132     * @since 0.7.12
    119133     */
    120     private static long[] currentTimeAndStratum(String serverName, int timeout) {
     134    private static long[] currentTimeAndStratum(String serverName, int timeout, Log log) {
    121135        DatagramSocket socket = null;
    122136        try {
     
    126140            byte[] buf = new NtpMessage().toByteArray();
    127141            DatagramPacket packet = new DatagramPacket(buf, buf.length, address, NTP_PORT);
     142            byte[] txtime = new byte[8];
    128143
    129144            // Set the transmit timestamp *just* before sending the packet
    130145            // ToDo: Does this actually improve performance or not?
    131             NtpMessage.encodeTimestamp(packet.getData(), 40,
     146            NtpMessage.encodeTimestamp(packet.getData(), OFF_TXTIME,
    132147                                       (System.currentTimeMillis()/1000.0)
    133148                                       + SECONDS_1900_TO_EPOCH);
    134149
    135150            socket.send(packet);
     151            // save for check
     152            System.arraycopy(packet.getData(), OFF_TXTIME, txtime, 0, 8);
     153            if (log != null && log.shouldDebug())
     154                log.debug("Sent:\n" + HexDump.dump(buf));
    136155
    137156            // Get response
     
    143162            double destinationTimestamp = (System.currentTimeMillis()/1000.0) + SECONDS_1900_TO_EPOCH;
    144163
     164            if (packet.getLength() < MIN_PKT_LEN) {
     165                if (log != null && log.shouldWarn())
     166                    log.warn("Short packet length " + packet.getLength());
     167                return null;
     168            }
     169
    145170            // Process response
    146171            NtpMessage msg = new NtpMessage(packet.getData());
    147172
    148             //double roundTripDelay = (destinationTimestamp-msg.originateTimestamp) -
    149             //                        (msg.receiveTimestamp-msg.transmitTimestamp);
    150             double localClockOffset = ((msg.receiveTimestamp - msg.originateTimestamp) +
    151                                        (msg.transmitTimestamp - destinationTimestamp)) / 2;
     173            if (log != null && log.shouldDebug())
     174                log.debug("Received from: " + packet.getAddress().getHostAddress() +
     175                          '\n' + msg + '\n' + HexDump.dump(packet.getData()));
    152176
    153177            // Stratum must be between 1 (atomic) and 15 (maximum defined value)
    154178            // Anything else is right out, treat such responses like errors
    155179            if ((msg.stratum < 1) || (msg.stratum > 15)) {
    156                 //System.out.println("Response from NTP server of unacceptable stratum " + msg.stratum + ", failing.");
     180                if (log != null && log.shouldWarn())
     181                    log.warn("Response from NTP server of unacceptable stratum " + msg.stratum + ", failing.");
    157182                return null;
    158183            }
     184
     185            if (!DataHelper.eq(txtime, 0, packet.getData(), OFF_ORIGTIME, 8)) {
     186                if (log != null && log.shouldWarn())
     187                    log.warn("Origin time mismatch sent:\n" + HexDump.dump(txtime) +
     188                             "rcvd:\n" + HexDump.dump(packet.getData(), OFF_ORIGTIME, 8));
     189                return null;
     190            }
     191
     192
     193            double localClockOffset = ((msg.receiveTimestamp - msg.originateTimestamp) +
     194                                       (msg.transmitTimestamp - destinationTimestamp)) / 2;
    159195           
    160196            long[] rv = new long[2];
    161197            rv[0] = (long)(System.currentTimeMillis() + localClockOffset*1000);
    162198            rv[1] = msg.stratum;
    163             //System.out.println("host: " + address.getHostAddress() + " rtt: " + roundTripDelay + " offset: " + localClockOffset + " seconds");
     199            if (log != null && log.shouldInfo()) {
     200                double roundTripDelay = (destinationTimestamp-msg.originateTimestamp) -
     201                                        (msg.receiveTimestamp-msg.transmitTimestamp);
     202                log.info("host: " + packet.getAddress().getHostAddress() + " rtt: " +
     203                         roundTripDelay + " offset: " + localClockOffset + " seconds");
     204            }
    164205            return rv;
    165206        } catch (IOException ioe) {
    166             //ioe.printStackTrace();
     207            if (log != null && log.shouldWarn())
     208                log.warn("NTP failure from " + serverName, ioe);
    167209            return null;
    168210        } finally {
     
    172214    }
    173215   
    174 /****
    175216    public static void main(String[] args) throws IOException {
    176217        // Process command-line args
    177218        if(args.length <= 0) {
    178             printUsage();
    179             return;
    180             // args = new String[] { "ntp1.sth.netnod.se", "ntp2.sth.netnod.se" };
     219           args = new String[] { "pool.ntp.org" };
    181220        }
    182221
    183         long now = currentTime(args);
    184         System.out.println("Current time: " + new java.util.Date(now));
    185     }
    186    
    187     static void printUsage() {
     222        Log log = new Log(NtpClient.class);
     223        long[] rv = currentTimeAndStratum(args, DEFAULT_TIMEOUT, log);
     224        System.out.println("Current time: " + new java.util.Date(rv[0]) + " (stratum " + rv[1] + ')');
     225    }
     226   
     227/****
     228    private static void printUsage() {
    188229        System.out.println(
    189230        "NtpClient - an NTP client for Java.\n" +
  • router/java/src/net/i2p/router/time/NtpMessage.java

    r2eb89e93 r38b930c  
    3232import java.text.DecimalFormat;
    3333import java.text.SimpleDateFormat;
     34import java.util.Arrays;
    3435import java.util.Date;
    3536
     
    118119     * multicast mode, the server sets this field to 5 (broadcast).
    119120     */
    120     public byte mode = 0;
     121    public final byte mode;
    121122   
    122123   
     
    234235     * in seconds since 00:00 1-Jan-1900.
    235236     */
    236     public double transmitTimestamp = 0;
     237    public final double transmitTimestamp;
    237238   
    238239   
     
    240241    /**
    241242     * Constructs a new NtpMessage from an array of bytes.
     243     *
     244     * @param array 48 bytes minimum
    242245     */
    243246    public NtpMessage(byte[] array) {
     
    281284        // appropriate default values.
    282285        this.mode = 3;
    283         this.transmitTimestamp = (System.currentTimeMillis()/1000.0) + 2208988800.0;
     286        this.transmitTimestamp = (System.currentTimeMillis()/1000.0) + NtpClient.SECONDS_1900_TO_EPOCH;
    284287    }
    285288   
     
    288291    /**
    289292     * This method constructs the data bytes of a raw NTP packet.
     293     *
     294     * @return 48 bytes
    290295     */
    291296    public byte[] toByteArray() {
     
    369374     * and return it as a double, according to the NTP 64-bit timestamp
    370375     * format.
     376     *
     377     * @param array 8 bytes starting at pointer
     378     * @param pointer the offset
     379     * @return the time since 1900 (NOT Java time)
    371380     */
    372381    public static double decodeTimestamp(byte[] array, int pointer) {
     
    384393    /**
    385394     * Encodes a timestamp in the specified position in the message
     395     *
     396     * @param array output 8 bytes starting at pointer
     397     * @param pointer the offset
     398     * @param timestamp the time to encode (since 1900, NOT Java time)
    386399     */
    387400    public static void encodeTimestamp(byte[] array, int pointer, double timestamp) {
     401        if (timestamp == 0.0) {
     402            // don't put in random data
     403            Arrays.fill(array, pointer, pointer + 8, (byte) 0);
     404            return;
     405        }
     406
    388407        // Converts a double into a 64-bit fixed point
    389         for(int i=0; i<8; i++) {
     408        // 6 bytes of real data
     409        for(int i=0; i<7; i++) {
    390410            // 2^24, 2^16, 2^8, .. 2^-32
    391411            double base = Math.pow(2, (3-i)*8);
     
    402422        // bitstring, both to avoid systematic roundoff errors and as
    403423        // a means of loop detection and replay detection.
    404         array[7+pointer] = (byte) (RandomSource.getInstance().nextInt());
     424        // 2 bytes of random data
     425        RandomSource.getInstance().nextBytes(array, pointer + 6, 2);
    405426    }
    406427   
     
    416437        // timestamp is relative to 1900, utc is used by Java and is relative
    417438        // to 1970
    418         double utc = timestamp - (2208988800.0);
     439        double utc = timestamp - NtpClient.SECONDS_1900_TO_EPOCH;
    419440       
    420441        // milliseconds
     
    426447        // fraction
    427448        double fraction = timestamp - ((long) timestamp);
    428         String fractionSting = new DecimalFormat(".000000").format(fraction);
     449        String fractionSting = new DecimalFormat(".000000000").format(fraction);
    429450       
    430451        return date + fractionSting;
  • router/java/src/net/i2p/router/time/RouterTimestamper.java

    r2eb89e93 r38b930c  
    274274            //    try { Thread.sleep(2*1000); } catch (InterruptedException ie) {}
    275275            //}
    276             long[] timeAndStratum = NtpClient.currentTimeAndStratum(serverList, perServerTimeout);
     276            long[] timeAndStratum = NtpClient.currentTimeAndStratum(serverList, perServerTimeout, _log);
    277277            now = timeAndStratum[0];
    278278            stratum = (int) timeAndStratum[1];
  • router/java/src/net/i2p/router/transport/GeoIP.java

    r2eb89e93 r38b930c  
    1717import java.util.concurrent.atomic.AtomicBoolean;
    1818
     19import com.maxmind.geoip.InvalidDatabaseException;
     20import com.maxmind.geoip.LookupService;
     21
    1922import net.i2p.I2PAppContext;
    2023import net.i2p.data.DataHelper;
     
    2528import net.i2p.util.ConcurrentHashSet;
    2629import net.i2p.util.Log;
     30import net.i2p.util.SystemVersion;
    2731
    2832/**
     
    5761    private int _lookupRunCount;
    5862   
     63    static final String PROP_GEOIP_ENABLED = "routerconsole.geoip.enable";
     64    public static final String PROP_GEOIP_DIR = "geoip.dir";
     65    public static final String GEOIP_DIR_DEFAULT = "geoip";
     66    static final String GEOIP_FILE_DEFAULT = "geoip.txt";
     67    static final String COUNTRY_FILE_DEFAULT = "countries.txt";
     68    public static final String PROP_IP_COUNTRY = "i2np.lastCountry";
     69    public static final String PROP_DEBIAN_GEOIP = "geoip.dat";
     70    public static final String PROP_DEBIAN_GEOIPV6 = "geoip.v6.dat";
     71    private static final String DEBIAN_GEOIP_FILE = "/usr/share/GeoIP/GeoIP.dat";
     72    private static final String DEBIAN_GEOIPV6_FILE = "/usr/share/GeoIP/GeoIPv6.dat";
     73    private static final boolean ENABLE_DEBIAN = !(SystemVersion.isWindows() || SystemVersion.isAndroid());
     74    /** maxmind API */
     75    private static final String UNKNOWN_COUNTRY_CODE = "--";
     76
    5977    /**
    6078     *  @param context RouterContext in production, I2PAppContext for testing only
     
    7290        readCountryFile();
    7391    }
    74    
    75     static final String PROP_GEOIP_ENABLED = "routerconsole.geoip.enable";
    76     public static final String PROP_GEOIP_DIR = "geoip.dir";
    77     public static final String GEOIP_DIR_DEFAULT = "geoip";
    78     static final String GEOIP_FILE_DEFAULT = "geoip.txt";
    79     static final String COUNTRY_FILE_DEFAULT = "countries.txt";
    80     public static final String PROP_IP_COUNTRY = "i2np.lastCountry";
    8192
    8293    /**
     
    146157                if (search.length > 0) {
    147158                    Arrays.sort(search);
    148                     String[] countries = readGeoIPFile(search);
    149                     for (int i = 0; i < countries.length; i++) {
    150                         if (countries[i] != null)
    151                             _IPToCountry.put(search[i], countries[i]);
    152                         else
    153                             _notFound.add(search[i]);
     159                    File f = new File(_context.getProperty(PROP_DEBIAN_GEOIP, DEBIAN_GEOIP_FILE));
     160                    if (ENABLE_DEBIAN && f.exists()) {
     161                        // Maxmind database
     162                        LookupService ls = null;
     163                        try {
     164                            ls = new LookupService(f, LookupService.GEOIP_STANDARD);
     165                            for (int i = 0; i < search.length; i++) {
     166                                long ip = search[i].longValue();
     167                                // returns upper case or "--"
     168                                String uc = ls.getCountry(ip).getCode();
     169                                if (!uc.equals(UNKNOWN_COUNTRY_CODE)) {
     170                                    String cached = _codeCache.get(uc.toLowerCase(Locale.US));
     171                                    _IPToCountry.put(search[i], cached);
     172                                } else {
     173                                    _notFound.add(search[i]);
     174                                }
     175                            }
     176                        } catch (IOException ioe) {
     177                            _log.error("GeoIP failure", ioe);
     178                        } catch (InvalidDatabaseException ide) {
     179                            _log.error("GeoIP failure", ide);
     180                        } finally {
     181                            if (ls != null) ls.close();
     182                        }
     183                    } else {
     184                        // Tor-style database
     185                        String[] countries = readGeoIPFile(search);
     186                        for (int i = 0; i < countries.length; i++) {
     187                            if (countries[i] != null)
     188                                _IPToCountry.put(search[i], countries[i]);
     189                            else
     190                                _notFound.add(search[i]);
     191                        }
    154192                    }
    155193                }
     
    159197                if (search.length > 0) {
    160198                    Arrays.sort(search);
    161                     String[] countries = GeoIPv6.readGeoIPFile(_context, search, _codeCache);
    162                     for (int i = 0; i < countries.length; i++) {
    163                         if (countries[i] != null)
    164                             _IPToCountry.put(search[i], countries[i]);
    165                         else
    166                             _notFound.add(search[i]);
     199                    File f = new File(_context.getProperty(PROP_DEBIAN_GEOIPV6, DEBIAN_GEOIPV6_FILE));
     200                    if (ENABLE_DEBIAN && f.exists()) {
     201                        // Maxmind database
     202                        LookupService ls = null;
     203                        try {
     204                            ls = new LookupService(f, LookupService.GEOIP_STANDARD);
     205                            for (int i = 0; i < search.length; i++) {
     206                                long ip = search[i].longValue();
     207                                String ipv6 = toV6(ip);
     208                                // returns upper case or "--"
     209                                String uc = ls.getCountryV6(ipv6).getCode();
     210                                if (!uc.equals(UNKNOWN_COUNTRY_CODE)) {
     211                                    String cached = _codeCache.get(uc.toLowerCase(Locale.US));
     212                                    _IPToCountry.put(search[i], cached);
     213                                } else {
     214                                    _notFound.add(search[i]);
     215                                }
     216                            }
     217                        } catch (IOException ioe) {
     218                            _log.error("GeoIP failure", ioe);
     219                        } catch (InvalidDatabaseException ide) {
     220                            _log.error("GeoIP failure", ide);
     221                        } finally {
     222                            if (ls != null) ls.close();
     223                        }
     224                    } else {
     225                        // Tor-style database
     226                        String[] countries = GeoIPv6.readGeoIPFile(_context, search, _codeCache);
     227                        for (int i = 0; i < countries.length; i++) {
     228                            if (countries[i] != null)
     229                                _IPToCountry.put(search[i], countries[i]);
     230                            else
     231                                _notFound.add(search[i]);
     232                        }
    167233                    }
    168234                }
     
    406472
    407473    /**
     474     * @return e.g. aabb:ccdd:eeff:1122::
     475     * @since 0.9.26 for maxmind
     476     */
     477    private static String toV6(long ip) {
     478        StringBuilder buf = new StringBuilder(21);
     479        for (int i = 0; i < 4; i++) {
     480            buf.append(Long.toHexString((ip >> ((3-i)*16)) & 0xffff));
     481            buf.append(':');
     482        }
     483        buf.append(':');
     484        return buf.toString();
     485    }
     486
     487    /**
    408488     * Get the country for a country code
    409489     * @param code two-letter lower case code
  • router/java/src/net/i2p/router/transport/udp/UDPTransport.java

    r2eb89e93 r38b930c  
    44import java.io.Writer;
    55import java.net.InetAddress;
     6import java.net.Inet4Address;
    67import java.net.SocketException;
    78import java.net.UnknownHostException;
     
    1011import java.util.Arrays;
    1112import java.util.HashMap;
     13import java.util.HashSet;
    1214import java.util.Iterator;
    1315import java.util.List;
     
    326328       
    327329        // bind host
     330        // This is not exposed in the UI and in practice is always null.
     331        // We use PROP_EXTERNAL_HOST instead. See below.
    328332        String bindTo = _context.getProperty(PROP_BIND_INTERFACE);
    329333
     
    334338            String fixedHost = _context.getProperty(PROP_EXTERNAL_HOST);
    335339            if (fixedHost != null && fixedHost.length() > 0) {
    336                 try {
    337                     // TODO getAllByName(), bind to each
    338                     String testAddr = InetAddress.getByName(fixedHost).getHostAddress();
    339                     if (Addresses.getAddresses().contains(testAddr))
    340                         bindTo = testAddr;
    341                 } catch (UnknownHostException uhe) {}
    342             }
    343         }
    344 
    345         List<InetAddress> bindToAddrs = new ArrayList<InetAddress>(4);
     340                // Generate a comma-separated list of valid IP addresses
     341                // that we can bind to,
     342                // from the comma-separated PROP_EXTERNAL_HOST config.
     343                // The config may contain IPs or hostnames; expand each
     344                // hostname to one or more (v4 or v6) IPs.
     345                TransportUtil.IPv6Config cfg = getIPv6Config();
     346                Set<String> myAddrs;
     347                if (cfg == IPV6_DISABLED)
     348                    myAddrs = Addresses.getAddresses(false, false);
     349                else
     350                    myAddrs = Addresses.getAddresses(false, true);
     351                StringBuilder buf = new StringBuilder();
     352                String[] bta = DataHelper.split(fixedHost, "[,; \r\n\t]");
     353                for (int i = 0; i < bta.length; i++) {
     354                    String bt = bta[i];
     355                    if (bt.length() <= 0)
     356                        continue;
     357                    try {
     358                        InetAddress[] all = InetAddress.getAllByName(bt);
     359                        for (int j = 0; j < all.length; j++) {
     360                            InetAddress ia = all[j];
     361                            if (cfg == IPV6_ONLY && (ia instanceof Inet4Address)) {
     362                                if (_log.shouldWarn())
     363                                    _log.warn("Configured for IPv6 only, not binding to configured IPv4 host " + bt);
     364                                continue;
     365                            }
     366                            String testAddr = ia.getHostAddress();
     367                            if (myAddrs.contains(testAddr)) {
     368                                if (buf.length() > 0)
     369                                    buf.append(',');
     370                                buf.append(testAddr);
     371                            } else {
     372                                if (_log.shouldWarn())
     373                                    _log.warn("Not a local address, not binding to configured IP " + testAddr);
     374                            }
     375                        }
     376                    } catch (UnknownHostException uhe) {
     377                        if (_log.shouldWarn())
     378                            _log.warn("Not binding to configured host " + bt + " - " + uhe);
     379                    }
     380                }
     381                if (buf.length() > 0) {
     382                    bindTo = buf.toString();
     383                    if (_log.shouldWarn() && !fixedHost.equals(bindTo))
     384                        _log.warn("Expanded external host config \"" + fixedHost + "\" to \"" + bindTo + '"');
     385                }
     386            }
     387        }
     388
     389        // construct a set of addresses
     390        Set<InetAddress> bindToAddrs = new HashSet<InetAddress>(4);
    346391        if (bindTo != null) {
     392            // Generate a set IP addresses
     393            // that we can bind to,
     394            // from the comma-separated PROP_BIND_INTERFACE config,
     395            // or as generated from the PROP_EXTERNAL_HOST config.
     396            // In theory, the config may contain IPs and/or hostnames.
     397            // However, in practice, it's only IPs, because any hostnames
     398            // in PROP_EXTERNAL_HOST were expanded above to one or more (v4 or v6) IPs.
     399            // PROP_BIND_INTERFACE is not exposed in the UI and is never set.
    347400            String[] bta = DataHelper.split(bindTo, "[,; \r\n\t]");
    348401            for (int i = 0; i < bta.length; i++) {
     
    501554                rebuildExternalAddress(ia.getHostAddress(), newPort, false);
    502555            }
     556            // TODO
     557            // If we are bound only to v4 addresses,
     558            // force _haveIPv6Address to false, or else we get 'no endpoint' errors
     559            // If we are bound only to v6 addresses,
     560            // override getIPv6Config() ?
    503561        }
    504562        if (isIPv4Firewalled()) {
  • router/java/src/net/i2p/router/tunnel/pool/BuildExecutor.java

    r2eb89e93 r38b930c  
    6969        _context.statManager().createRateStat("tunnel.buildFailFirstHop", "How often we fail to build a OB tunnel because we can't contact the first hop", "Tunnels", new long[] { 60*1000, 10*60*1000 });
    7070        _context.statManager().createRateStat("tunnel.buildReplySlow", "Build reply late, but not too late", "Tunnels", new long[] { 10*60*1000 });
     71        //ctx.statManager().createRateStat("tunnel.buildClientExpireIB", "", "Tunnels", new long[] { 60*60*1000 });
     72        //ctx.statManager().createRateStat("tunnel.buildClientExpireOB", "", "Tunnels", new long[] { 60*60*1000 });
     73        //ctx.statManager().createRateStat("tunnel.buildExploratoryExpireIB", "", "Tunnels", new long[] { 60*60*1000 });
     74        //ctx.statManager().createRateStat("tunnel.buildExploratoryExpireOB", "", "Tunnels", new long[] { 60*60*1000 });
    7175
    7276        // Get stat manager, get recognized bandwidth tiers
     
    185189                    if (ri != null) bwTier = ri.getBandwidthTier(); // Returns "Unknown" if none recognized
    186190                    // Record that a peer of the given tier expired
    187                     _context.statManager().addRateData("tunnel.tierExpire" + bwTier, 1, 0);
     191                    _context.statManager().addRateData("tunnel.tierExpire" + bwTier, 1);
    188192                    didNotReply(cfg.getReplyMessageId(), peer);
    189193                    // Blame everybody since we don't know whose fault it is.
     
    195199                if (pool != null)
    196200                    pool.buildComplete(cfg);
    197                 if (cfg.getDestination() == null)
    198                     _context.statManager().addRateData("tunnel.buildExploratoryExpire", 1, 0);
    199                 else
    200                     _context.statManager().addRateData("tunnel.buildClientExpire", 1, 0);
     201                if (cfg.getDestination() == null) {
     202                    _context.statManager().addRateData("tunnel.buildExploratoryExpire", 1);
     203                    //if (cfg.isInbound())
     204                    //    _context.statManager().addRateData("tunnel.buildExploratoryExpireIB", 1);
     205                    //else
     206                    //    _context.statManager().addRateData("tunnel.buildExploratoryExpireOB", 1);
     207                } else {
     208                    _context.statManager().addRateData("tunnel.buildClientExpire", 1);
     209                    //if (cfg.isInbound())
     210                    //    _context.statManager().addRateData("tunnel.buildClientExpireIB", 1);
     211                    //else
     212                    //    _context.statManager().addRateData("tunnel.buildClientExpireOB", 1);
     213                }
    201214            }
    202215        }
  • router/java/src/net/i2p/router/tunnel/pool/BuildHandler.java

    r2eb89e93 r38b930c  
    498498            int numTunnels = _context.tunnelManager().getParticipatingCount();
    499499            int limit = Math.max(MIN_LOOKUP_LIMIT, Math.min(MAX_LOOKUP_LIMIT, numTunnels * PERCENT_LOOKUP_LIMIT / 100));
    500             int current = _currentLookups.incrementAndGet();
     500            int current;
     501            // leaky counter, since it isn't reliable
     502            if (_context.random().nextInt(16) > 0)
     503                current = _currentLookups.incrementAndGet();
     504            else
     505                current = 1;
    501506            if (current <= limit) {
     507                // don't let it go negative
     508                if (current <= 0)
     509                    _currentLookups.set(1);
    502510                if (_log.shouldLog(Log.DEBUG))
    503511                    _log.debug("Request " + req
     
    511519                    _log.warn("Drop next hop lookup, limit " + limit + ": " + req);
    512520                _context.statManager().addRateData("tunnel.dropLookupThrottle", 1);
    513             }
    514             if (from != null)
    515                 _context.commSystem().mayDisconnect(from);
     521                if (from != null)
     522                    _context.commSystem().mayDisconnect(from);
     523            }
    516524            return -1;
    517525        } else {
Note: See TracChangeset for help on using the changeset viewer.