> Date: Fri, 13 Aug 2004 15:58:30 +1200 (NZST)

> Message-ID: <1776.202.37.75.101.1092369510.squirrel@202.37.75.101>
> From: adam@adambuckley.net
> To: jrandom@i2p.net
>
> [...]
>
> I hereby authorize my NtpClient.java and NtpMessage.java code to be
> redistributed under the BSD license for the purpose of integration with
> the I2P project, providing that I am credited as the original author of
> the code.
>
> [...]
w00t!  adam++
code migrated into core/java/src/net/i2p/time, integrated with Clock,
dropping that whole ugly pass-the-time-through-URL, and hence dropped
support for :7655/setTime.
New router.config properties to control the timestamper:
  time.sntpServerList=pool.ntp.org,pool.ntp.org,pool.ntp.org
  time.queryFrequencyMs=300000
  time.disabled=false
So, to disable, add time.disabled=true to your router.config.  It is
enabled by default.
Default router.config and startup scripts updated accordingly (since
timestamper.jar is now gone)
This commit is contained in:
jrandom
2004-08-13 21:15:22 +00:00
committed by zzz
parent 3c9b0273d4
commit 352396bdc2
17 changed files with 287 additions and 313 deletions

View File

@ -17,6 +17,7 @@ import java.util.List;
import java.util.Set;
import net.i2p.util.Log;
import net.i2p.time.Timestamper;
import net.i2p.router.RouterContext;
import net.i2p.router.ClientTunnelSettings;
@ -221,9 +222,9 @@ public class ConfigNetHandler extends FormHandler {
updateRates();
if (_timeSyncEnabled) {
System.setProperty("timestamper.enabled", "true");
_context.router().setConfigSetting(Timestamper.PROP_DISABLED, "false");
} else {
System.setProperty("timestamper.enabled", "false");
_context.router().setConfigSetting(Timestamper.PROP_DISABLED, "false");
}
boolean saved = _context.router().saveConfig();

View File

@ -6,6 +6,7 @@ import java.util.List;
import java.util.Iterator;
import java.util.TreeMap;
import net.i2p.time.Timestamper;
import net.i2p.util.Log;
import net.i2p.router.RouterContext;
@ -50,8 +51,8 @@ public class ConfigNetHelper {
}
public String getEnableTimeSyncChecked() {
String enabled = System.getProperty("timestamper.enabled");
if ( (enabled == null) || (!"true".equals(enabled)) )
String enabled = _context.getProperty(Timestamper.PROP_DISABLED, "true");
if ( (enabled == null) || (!"true".equalsIgnoreCase(enabled)) )
return "";
else
return " checked ";

View File

@ -34,10 +34,8 @@
to <a href="http://www.whatismyip.com/">www.whatismyip.com</a>.</i>
<hr />
<b>Enable internal time synchronization?</b> <input type="checkbox" <jsp:getProperty name="nethelper" property="enableTimeSyncChecked" /> name="enabletimesync" /><br />
<i>If disabled, your machine <b>must</b> be NTP synchronized. This option only
takes effect for the current run - if your machine is always synchronized within
(a few seconds), you can update your configuration so that it doesn't start the
"Timestamper" app (which would make this option irrelevent)</i>
<i>If disabled, your machine <b>must</b> be NTP synchronized - your clock must always
be within a few seconds of "correct".</i>
<hr />
<b>Bandwidth limiter</b><br />
<b>Inbound rate</b>:

View File

@ -1,41 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project basedir="." default="all" name="time">
<target name="all" depends="clean, build" />
<target name="build" depends="builddep, jar" />
<target name="builddep">
<ant dir="../../../core/java/" target="build" />
</target>
<target name="compile">
<mkdir dir="./build" />
<mkdir dir="./build/obj" />
<javac srcdir="./src" debug="true" source="1.3" target="1.3" deprecation="on" destdir="./build/obj" includes="**/*.java" classpath="../../../core/java/build/i2p.jar" />
</target>
<target name="jar" depends="compile">
<jar destfile="./build/timestamper.jar" basedir="./build/obj" includes="**/*.class">
<manifest>
<attribute name="Main-Class" value="net.i2p.time.Timestamper" />
<attribute name="Class-Path" value="i2p.jar timestamper.jar" />
</manifest>
</jar>
</target>
<target name="javadoc">
<mkdir dir="./build" />
<mkdir dir="./build/javadoc" />
<javadoc
sourcepath="./src:../../../core/java/src:../../../core/java/test" destdir="./build/javadoc"
packagenames="*"
use="true"
access="package"
splitindex="true"
windowtitle="I2P timestamper" />
</target>
<target name="clean">
<delete dir="./build" />
</target>
<target name="cleandep" depends="clean">
<ant dir="../../../core/java/" target="cleandep" />
</target>
<target name="distclean" depends="clean">
<ant dir="../../../core/java/" target="distclean" />
</target>
</project>

View File

@ -1,122 +0,0 @@
package net.i2p.time;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import net.i2p.util.I2PThread;
import net.i2p.util.Log;
/**
* Periodically query a series of NTP servers and post the offset
* to a given URL. It tries the NTP servers in order, contacting them
* using UDP port 123, and sends the current date to the URL specified
* (specifically, URL+"&now=" + yyyyMMdd_HH:mm:ss.SSS in the UK locale).
* It does this every 5 minutes, forever.
*
* Usage: <pre>
* Timestamper URL ntpServer1[ ntpServer2]*
* </pre>
*/
public class Timestamper implements Runnable {
private static Log _log = new Log(Timestamper.class);
private static String _targetURL;
private static String _serverList[];
private int DELAY_MS = 5*60*1000;
public Timestamper() {}
public void startTimestamper() {
if (_log.shouldLog(Log.INFO))
_log.info("Starting timestamper pointing at " + _targetURL);
synchronized (Timestamper.class) {
String enabled = System.getProperty("timestamper.started");
if (enabled != null) {
_log.warn("Timestamper already running");
return;
} else {
System.setProperty("timestamper.started", "true");
System.setProperty("timestamper.enabled", "true");
}
}
I2PThread t = new I2PThread(this, "Timestamper");
t.setPriority(I2PThread.MIN_PRIORITY);
t.start();
}
public void run() {
if (_log.shouldLog(Log.INFO))
_log.info("Starting up timestamper");
try {
while (true) {
String enabled = System.getProperty("timestamper.enabled");
if ( (enabled == null) || (!"true".equals(enabled)) ) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Not stamping the time");
} else {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Querying servers " + _serverList);
try {
long now = NtpClient.currentTime(_serverList);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Stamp time");
stampTime(now);
} catch (IllegalArgumentException iae) {
_log.log(Log.CRIT, "Unable to reach any of the NTP servers - network disconnected?");
}
}
try { Thread.sleep(DELAY_MS); } catch (InterruptedException ie) {}
}
} catch (Throwable t) {
_log.log(Log.CRIT, "Timestamper died!", t);
}
}
/**
* Send an HTTP request to a given URL specifying the current time
*/
private void stampTime(long now) {
try {
String toRequest = _targetURL + "&now=" + getNow(now);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Stamping [" + toRequest + "]");
URL url = new URL(toRequest);
Object o = url.getContent();
// ignore the content
} catch (MalformedURLException mue) {
_log.error("Invalid URL", mue);
} catch (IOException ioe) {
_log.error("Error stamping the time", ioe);
}
}
private SimpleDateFormat _fmt = new SimpleDateFormat("yyyyMMdd_HH:mm:ss.SSS", Locale.UK);
private String getNow(long now) {
synchronized (_fmt) {
return _fmt.format(new Date(now));
}
}
public static void main(String args[]) {
if ( (args == null) || (args.length < 2) ) {
usage();
return;
//args = new String[] { "http://dev.i2p.net:80/somePath?pass=password", "ntp1.sth.netnod.se", "ntp2.sth.netnod.se" };
}
String servers[] = new String[args.length-1];
System.arraycopy(args, 1, servers, 0, servers.length);
_targetURL = args[0];
_serverList = servers;
Timestamper ts = new Timestamper();
ts.startTimestamper();
}
private static void usage() {
System.err.println("Usage: Timestamper URL ntpServer[ ntpServer]*");
_log.error("Usage: Timestamper URL ntpServer[ ntpServer]*");
}
}

View File

@ -27,7 +27,6 @@
<ant dir="apps/sam/java/" target="jar" />
<ant dir="apps/heartbeat/java/" target="jar" />
<ant dir="apps/netmonitor/java/" target="jar" />
<ant dir="apps/time/java/" target="jar" />
<ant dir="apps/routerconsole/java/" target="jar" />
<ant dir="installer/java/" target="jar" />
</target>
@ -43,7 +42,6 @@
<copy file="apps/sam/java/build/sam.jar" todir="build/" />
<copy file="apps/heartbeat/java/build/heartbeat.jar" todir="build/" />
<copy file="apps/netmonitor/java/build/netmonitor.jar" todir="build/" />
<copy file="apps/time/java/build/timestamper.jar" todir="build/" />
<copy file="installer/java/build/install.jar" todir="build/" />
<copy file="installer/java/build/guiinstall.jar" todir="build/" />
<copy file="installer/java/build/fetchseeds.jar" todir="build/" />
@ -74,7 +72,6 @@
<ant dir="apps/heartbeat/java/" target="distclean" />
<ant dir="apps/netmonitor/java/" target="distclean" />
<ant dir="apps/routerconsole/java/" target="distclean" />
<ant dir="apps/time/java/" target="distclean" />
<ant dir="installer/java/" target="distclean" />
<delete>
<fileset dir="." includes="**/*.class" />

View File

@ -1,5 +1,33 @@
package net.i2p.time;
/*
* Copyright (c) 2004, Adam Buckley
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Adam Buckley nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.DatagramPacket;
@ -17,20 +45,6 @@ import java.net.InetAddress;
* Note that on windows platforms, the curent time-of-day timestamp is limited
* to an resolution of 10ms and adversely affects the accuracy of the results.
*
*
* This code is copyright (c) Adam Buckley 2004
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version. A HTML version of the GNU General Public License can be
* seen at http://www.gnu.org/licenses/gpl.html
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* @author Adam Buckley
* (minor refactoring by jrandom)
*/

View File

@ -1,4 +1,33 @@
package net.i2p.time;
/*
* Copyright (c) 2004, Adam Buckley
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of Adam Buckley nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*/
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
@ -34,21 +63,6 @@ import java.util.Date;
* socket.receive(packet);
* System.out.println(msg.toString());
*
*
* This code is copyright (c) Adam Buckley 2004
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version. A HTML version of the GNU General Public License can be
* seen at http://www.gnu.org/licenses/gpl.html
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*
* Comments for member variables are taken from RFC2030 by David Mills,
* University of Delaware.
*

View File

@ -0,0 +1,190 @@
package net.i2p.time;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import net.i2p.I2PAppContext;
import net.i2p.util.I2PThread;
import net.i2p.util.Log;
/**
* Periodically query a series of NTP servers and update any associated
* listeners. It tries the NTP servers in order, contacting them using
* SNTP (UDP port 123). By default, it does this every 5 minutes,
* forever.
*/
public class Timestamper implements Runnable {
private I2PAppContext _context;
private Log _log;
private List _servers;
private List _listeners;
private int _queryFrequency;
private boolean _disabled;
private static final int DEFAULT_QUERY_FREQUENCY = 5*60*1000;
private static final String DEFAULT_SERVER_LIST = "pool.ntp.org, pool.ntp.org";
private static final boolean DEFAULT_DISABLED = false;
public static final String PROP_QUERY_FREQUENCY = "time.queryFrequencyMs";
public static final String PROP_SERVER_LIST = "time.sntpServerList";
public static final String PROP_DISABLED = "time.disabled";
public Timestamper(I2PAppContext ctx) {
this(ctx, null);
}
public Timestamper(I2PAppContext ctx, UpdateListener lsnr) {
_context = ctx;
_servers = new ArrayList(1);
_listeners = new ArrayList(1);
if (lsnr != null)
_listeners.add(lsnr);
updateConfig();
startTimestamper();
}
public int getServerCount() {
synchronized (_servers) {
return _servers.size();
}
}
public String getServer(int index) {
synchronized (_servers) {
return (String)_servers.get(index);
}
}
public int getQueryFrequencyMs() { return _queryFrequency; }
public boolean getIsDisabled() { return _disabled; }
public void addListener(UpdateListener lsnr) {
synchronized (_listeners) {
_listeners.add(lsnr);
}
}
public void removeListener(UpdateListener lsnr) {
synchronized (_listeners) {
_listeners.remove(lsnr);
}
}
public int getListenerCount() {
synchronized (_listeners) {
return _listeners.size();
}
}
public UpdateListener getListener(int index) {
synchronized (_listeners) {
return (UpdateListener)_listeners.get(index);
}
}
private void startTimestamper() {
I2PThread t = new I2PThread(this, "Timestamper");
t.setPriority(I2PThread.MIN_PRIORITY);
t.start();
}
public void run() {
try { Thread.sleep(1000); } catch (InterruptedException ie) {}
_log = _context.logManager().getLog(Timestamper.class);
if (_log.shouldLog(Log.INFO))
_log.info("Starting timestamper");
if (_log.shouldLog(Log.INFO))
_log.info("Starting up timestamper");
try {
while (true) {
if (!_disabled) {
String serverList[] = null;
synchronized (_servers) {
serverList = new String[_servers.size()];
for (int i = 0; i < serverList.length; i++)
serverList[i] = (String)_servers.get(i);
}
if (_log.shouldLog(Log.DEBUG))
_log.debug("Querying servers " + _servers);
try {
long now = NtpClient.currentTime(serverList);
if (_log.shouldLog(Log.DEBUG))
_log.debug("Stamp time");
stampTime(now);
} catch (IllegalArgumentException iae) {
_log.log(Log.CRIT, "Unable to reach any of the NTP servers - network disconnected?");
}
}
updateConfig();
try { Thread.sleep(_queryFrequency); } catch (InterruptedException ie) {}
}
} catch (Throwable t) {
_log.log(Log.CRIT, "Timestamper died!", t);
}
}
/**
* Send an HTTP request to a given URL specifying the current time
*/
private void stampTime(long now) {
synchronized (_listeners) {
for (int i = 0; i < _listeners.size(); i++) {
UpdateListener lsnr = (UpdateListener)_listeners.get(i);
lsnr.setNow(now);
}
}
}
/**
* Reload all the config elements from the appContext
*
*/
private void updateConfig() {
String serverList = _context.getProperty(PROP_SERVER_LIST);
if ( (serverList == null) || (serverList.trim().length() <= 0) )
serverList = DEFAULT_SERVER_LIST;
synchronized (_servers) {
StringTokenizer tok = new StringTokenizer(serverList, ",");
while (tok.hasMoreTokens()) {
String val = (String)tok.nextToken();
val = val.trim();
if (val.length() > 0)
_servers.add(val);
}
}
String freq = _context.getProperty(PROP_QUERY_FREQUENCY);
if ( (freq == null) || (freq.trim().length() <= 0) )
freq = DEFAULT_QUERY_FREQUENCY + "";
try {
int ms = Integer.parseInt(freq);
if (ms > 60*1000) {
_queryFrequency = ms;
} else {
if ( (_log != null) && (_log.shouldLog(Log.ERROR)) )
_log.error("Query frequency once every " + ms + "ms is too fast!");
_queryFrequency = DEFAULT_QUERY_FREQUENCY;
}
} catch (NumberFormatException nfe) {
if ( (_log != null) && (_log.shouldLog(Log.WARN)) )
_log.warn("Invalid query frequency [" + freq + "], falling back on " + DEFAULT_QUERY_FREQUENCY);
_queryFrequency = DEFAULT_QUERY_FREQUENCY;
}
String disabled = _context.getProperty(PROP_DISABLED);
if (disabled == null)
disabled = DEFAULT_DISABLED + "";
_disabled = Boolean.getBoolean(disabled);
}
/**
* Interface to receive update notifications for when we query the time
*
*/
public interface UpdateListener {
/**
* The time has been queried and we have a current value for 'now'
*
*/
public void setNow(long now);
}
}

View File

@ -5,6 +5,7 @@ import java.util.Iterator;
import java.util.Set;
import net.i2p.I2PAppContext;
import net.i2p.time.Timestamper;
/**
* Alternate location for determining the time which takes into account an offset.
@ -13,18 +14,23 @@ import net.i2p.I2PAppContext;
* (such as an NTP synchronized clock).
*
*/
public class Clock {
public class Clock implements Timestamper.UpdateListener {
private I2PAppContext _context;
private Timestamper _timestamper;
public Clock(I2PAppContext context) {
_context = context;
_offset = 0;
_alreadyChanged = false;
_listeners = new HashSet(64);
_timestamper = new Timestamper(context, this);
}
public static Clock getInstance() {
return I2PAppContext.getGlobalContext().clock();
}
public Timestamper getTimestamper() { return _timestamper; }
/** we fetch it on demand to avoid circular dependencies (logging uses the clock) */
private Log getLog() { return _context.logManager().getLog(Clock.class); }

View File

@ -10,7 +10,6 @@
<ant dir="../../apps/sam/java/" target="build" />
<ant dir="../../apps/netmonitor/java/" target="build" />
<ant dir="../../apps/heartbeat/java/" target="build" />
<ant dir="../../apps/time/java/" target="build" />
</target>
<target name="compile">
<mkdir dir="./build" />
@ -40,7 +39,6 @@
<fileset file="../../apps/sam/java/build/sam.jar" />
<fileset file="../../apps/heartbeat/java/build/heartbeat.jar" />
<fileset file="../../apps/netmonitor/java/build/netmonitor.jar" />
<fileset file="../../apps/time/java/build/timestamper.jar" />
<fileset file="../doc/COPYING" />
<fileset file="../../readme.txt" />
<fileset file="../../hosts.txt" />
@ -64,7 +62,6 @@
<fileset file="../../apps/sam/java/build/sam.jar" />
<fileset file="../../apps/heartbeat/java/build/heartbeat.jar" />
<fileset file="../../apps/netmonitor/java/build/netmonitor.jar" />
<fileset file="../../apps/time/java/build/timestamper.jar" />
<fileset file="../doc/COPYING" />
<fileset file="../../readme.txt" />
<fileset file="../../hosts.txt" />
@ -86,7 +83,6 @@
<ant dir="../../apps/sam/java/" target="cleandep" />
<ant dir="../../apps/heartbeat/java" target="cleandep" />
<ant dir="../../apps/netmonitor/java" target="cleandep" />
<ant dir="../../apps/time/java" target="cleandep" />
</target>
<target name="distclean" depends="clean">
<ant dir="../../core/java/" target="distclean" />
@ -96,6 +92,5 @@
<ant dir="../../apps/sam/java/" target="distclean" />
<ant dir="../../apps/heartbeat/java" target="distclean" />
<ant dir="../../apps/netmonitor/java" target="distclean" />
<ant dir="../../apps/time/java" target="distclean" />
</target>
</project>

View File

@ -325,10 +325,6 @@ public abstract class Install {
_i2cpPort = ((Integer)_answers.get("i2cpPort")).intValue();
_inBPS = ((Integer)_answers.get("inBPS")).intValue();
_outBPS = ((Integer)_answers.get("outBPS")).intValue();
long num = new java.util.Random().nextLong();
if (num < 0)
num = 0 - num;
_answers.put("timestamperPassword", new Long(num));
}
private void useTemplate(String templateName, File destFile) {

View File

@ -115,5 +115,3 @@ libs.0012.name=harvester.config
libs.0012.islib=false
libs.0013.name=heartbeat.config
libs.0013.islib=false
libs.0014.name=timestamper.jar
libs.0014.islib=true

View File

@ -109,13 +109,7 @@ tunnels.tunnelDuration=600000
# http://localhost:7655/shutdown?password=thisIsASecret)
#router.shutdownPassword=thisIsASecret
#
# the remaining lines describe how you can get your router to fire up client
# applications it is up and running, all within the router's JVM. Uncomment the
# ones you want (revising the numbers and ports accordingly)
# Keep the router's clock in sync by querying one of the specified NTP servers once
# a minute (uses UDP port 123)
# Comma delimited list of SNTP servers to query. pool.ntp.org is a DNS trick to
# This defaults to the DNS round-robin ntp pool - see http://www.pool.ntp.org/
# Please change the NTP server specified to include ones closer to you - see
# http://www.eecis.udel.edu/~mills/ntp/clock2a.html for a list (you can specify as
@ -126,28 +120,30 @@ tunnels.tunnelDuration=600000
# BR: ntp1.pucpr.br
# BE: ntp2.belbone.be
# AU: ntp.saard.net
clientApp.0.main=net.i2p.time.Timestamper
clientApp.0.name=Timestamper
clientApp.0.onBoot=true
clientApp.0.args=http://localhost:7655/setTime?##timestamperPassword## pool.ntp.org pool.ntp.org pool.ntp.org
time.sntpServerList=pool.ntp.org,pool.ntp.org,pool.ntp.org
# The admin time passphrase, used to prevent unauthorized people from updating your
# routers time. The value should be included in the timestamper's args above,
# otherwise it wont honor timestamp updates. You shouldnt include any spaces or funky
# characters - just pick some random numbers.
adminTimePassphrase=##timestamperPassword##
# Query an SNTP server every 5 minutes
# time.queryFrequencyMs=300000
# If you really really know that your computer's clock is ALWAYS correct, set this property
# time.disabled=true
#
# the remaining lines describe how you can get your router to fire up client
# applications it is up and running, all within the router's JVM. Uncomment the
# ones you want (revising the numbers and ports accordingly)
# SAM bridge (a simplified socket based protocol for using I2P - listens on port 7656. see
# the specs at http://www.i2p.net/node/view/144 for more info)
clientApp.1.main=net.i2p.sam.SAMBridge
clientApp.1.name=SAMBridge
clientApp.1.args=sam.keys 0.0.0.0 7656 i2cp.tcp.host=localhost i2cp.tcp.port=##_router_i2cp_port##
clientApp.0.main=net.i2p.sam.SAMBridge
clientApp.0.name=SAMBridge
clientApp.0.args=sam.keys 0.0.0.0 7656 i2cp.tcp.host=localhost i2cp.tcp.port=##_router_i2cp_port##
# The eepProxy (HTTP proxy that lets you browse both eepsites and the normal web via squid.i2p) and
# the ircProxy (which connects to the anonymously hosted ircd at irc.duck.i2p)
clientApp.2.main=net.i2p.i2ptunnel.I2PTunnel
clientApp.2.name=Tunnels
clientApp.2.args=-nocli -e "config localhost ##_router_i2cp_port##" -e "httpclient 4444" -e "client 6668 irc.duck.i2p"
clientApp.1.main=net.i2p.i2ptunnel.I2PTunnel
clientApp.1.name=Tunnels
clientApp.1.args=-nocli -e "config localhost ##_router_i2cp_port##" -e "httpclient 4444" -e "client 6668 irc.duck.i2p"
# note: if you want the proxies to be reachable from other machines, add:
# -e "listen_on 0.0.0.0"
# before the -e "httpclient 4444". otherwise, both of these proxies will only listen for connections on 127.0.0.1
@ -157,10 +153,10 @@ clientApp.2.args=-nocli -e "config localhost ##_router_i2cp_port##" -e "httpclie
# and add jetty-all.jar and routerconsole.jar in the router's classpath in the startRouter
# script
# (don't bother trying to figure this out prior to the 0.4 release)
#clientApp.3.main=net.i2p.router.web.RouterConsoleRunner
#clientApp.3.name=webConsole
#clientApp.3.args=7657 127.0.0.1 ./webapps/
#clientApp.3.onBoot=true
#clientApp.2.main=net.i2p.router.web.RouterConsoleRunner
#clientApp.2.name=webConsole
#clientApp.2.args=7657 127.0.0.1 ./webapps/
#clientApp.2.onBoot=true
# To require simple HTTP authentication for accessing any of the pages underneath the web console
# (including any other webapps deployed), uncomment the following line and set the password
@ -169,16 +165,3 @@ clientApp.2.args=-nocli -e "config localhost ##_router_i2cp_port##" -e "httpclie
# settings, etc). This is only used for the new jetty console (started in clientApp.3.* above)
#
#consolePassword=fooBarBaz
# Network monitor (harvests data from the network database and stores it under
# monitorData/, and with the netviewer GUI you can browse through its results)
#clientApp.4.main=net.i2p.netmonitor.NetMonitor
#clientApp.4.name=NetMonitor
#clientApp.4.args=
# Heartbeat engine (ueber-simple ping/pong system, configured in heartbeat.config. By itself
# it just writes out stat data where its told to, but there's a seperate HeartbeatMonitor
# GUI to let you visualize things)
#clientApp.5.main=net.i2p.heartbeat.Heartbeat
#clientApp.5.name=Heartbeat
#clientApp.5.args=heartbeat.config

View File

@ -4,4 +4,4 @@ cd ##_scripts_installdir##
REM the -XX args are workarounds for bugs in java 1.4.2's garbage collector
java -cp lib\i2p.jar;lib\router.jar;lib\mstreaming.jar;lib\heartbeat.jar;lib\i2ptunnel.jar;lib\netmonitor.jar;lib\sam.jar;lib\timestamper.jar -Djava.library.path=. -DloggerFilenameOverride=logs\log-router-#.txt -XX:NewSize=4M -XX:MaxNewSize=8M -XX:PermSize=8M -XX:MaxPermSize=32M net.i2p.router.Router
java -cp lib\i2p.jar;lib\router.jar;lib\mstreaming.jar;lib\heartbeat.jar;lib\i2ptunnel.jar;lib\netmonitor.jar;lib\sam.jar -Djava.library.path=. -DloggerFilenameOverride=logs\log-router-#.txt -XX:NewSize=4M -XX:MaxNewSize=8M -XX:PermSize=8M -XX:MaxPermSize=32M net.i2p.router.Router

View File

@ -2,7 +2,7 @@
cd ##_scripts_installdir##
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
# the -XX args are workarounds for bugs in java 1.4.2's garbage collector
nohup nice java -cp lib/i2p.jar:lib/router.jar:lib/mstreaming.jar:lib/heartbeat.jar:lib/i2ptunnel.jar:lib/netmonitor.jar:lib/sam.jar:lib/timestamper.jar -Djava.library.path=. -DloggerFilenameOverride=logs/log-router-#.txt -XX:NewSize=4M -XX:MaxNewSize=8M -XX:PermSize=8M -XX:MaxPermSize=32M net.i2p.router.Router --quiet > /dev/null &
nohup nice java -cp lib/i2p.jar:lib/router.jar:lib/mstreaming.jar:lib/heartbeat.jar:lib/i2ptunnel.jar:lib/netmonitor.jar:lib/sam.jar -Djava.library.path=. -DloggerFilenameOverride=logs/log-router-#.txt -XX:NewSize=4M -XX:MaxNewSize=8M -XX:PermSize=8M -XX:MaxPermSize=32M net.i2p.router.Router --quiet > /dev/null &
# Save the pid just in case we ever want to stop the router
echo $! > router.pid
echo I2P Router started

View File

@ -6,10 +6,7 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Iterator;
import java.util.Locale;
import java.util.Set;
import net.i2p.data.Hash;
@ -58,13 +55,6 @@ class AdminRunner implements Runnable {
}
} else if (command.indexOf("/profile/") >= 0) {
replyText(out, getProfile(command));
} else if (command.indexOf("setTime") >= 0) {
if (allowTimeUpdate(command)) {
setTime(command);
reply(out, "<html><body>Time updated</body></html>");
} else {
reply(out, "<html><body>Time not updated</body></html>");
}
} else if (command.indexOf("/shutdown") >= 0) {
reply(out, shutdown(command));
} else if (true || command.indexOf("routerConsole.html") > 0) {
@ -80,25 +70,6 @@ class AdminRunner implements Runnable {
}
}
private boolean allowTimeUpdate(String command) {
String pass = _context.getProperty("adminTimePassphrase");
if ( (pass == null) || (pass.trim().length() <= 0) ) {
if (_log.shouldLog(Log.ERROR))
_log.error("No passphrase for update time from " + _socket.getInetAddress()
+ ":" + _socket.getPort());
return false;
}
if (command.indexOf(pass) != -1) {
return true;
} else {
if (_log.shouldLog(Log.ERROR))
_log.error("Invalid passphrase for update time from " + _socket.getInetAddress()
+ ":" + _socket.getPort());
return false;
}
}
private void reply(OutputStream out, String content) throws IOException {
StringBuffer reply = new StringBuffer(10240);
reply.append("HTTP/1.1 200 OK\n");
@ -152,33 +123,6 @@ class AdminRunner implements Runnable {
return "No such peer is being profiled\n";
}
private static final String FORMAT_STRING = "yyyyMMdd_HH:mm:ss.SSS";
private SimpleDateFormat _fmt = new SimpleDateFormat(FORMAT_STRING, Locale.UK);
private long getTime(String now) throws ParseException {
synchronized (_fmt) {
return _fmt.parse(now).getTime();
}
}
private void setTime(String cmd) {
int start = cmd.indexOf("now=");
String str = cmd.substring(start + 4, start+4+FORMAT_STRING.length());
try {
long now = getTime(str);
if (_log.shouldLog(Log.INFO))
_log.log(Log.INFO, "Admin time set to " + str);
setTime(now);
} catch (ParseException pe) {
_log.error("Invalid time specified [" + str + "]", pe);
}
}
private void setTime(long now) {
_context.clock().setNow(now);
}
private static final String SHUTDOWN_PASSWORD_PROP = "router.shutdownPassword";
private String shutdown(String cmd) {
String password = _context.router().getConfigSetting(SHUTDOWN_PASSWORD_PROP);