propagate from branch 'i2p.i2p.zzz.test4' (head bf9ef6aabb549475a41e936e7074ef625ab194e0)

to branch 'i2p.i2p.zzz.dhtsnark' (head 0a6fe29cd1c9fc357ad2c973be4f1a2a752b52b7)
This commit is contained in:
zzz
2010-12-26 13:17:33 +00:00
26 changed files with 479 additions and 82 deletions

View File

@@ -306,7 +306,7 @@ public class MetaInfo
if (piece >= 0 && piece < pieces -1)
return piece_length;
else if (piece == pieces -1)
return (int)(length - piece * piece_length);
return (int)(length - ((long)piece * piece_length));
else
throw new IndexOutOfBoundsException("no piece: " + piece);
}

View File

@@ -94,7 +94,7 @@ public class Peer implements Comparable
this.infohash = infohash;
this.metainfo = metainfo;
_id = ++__id;
//_log.debug("Creating a new peer with " + peerID.getAddress().calculateHash().toBase64(), new Exception("creating"));
//_log.debug("Creating a new peer with " + peerID.toString(), new Exception("creating"));
}
/**
@@ -120,7 +120,7 @@ public class Peer implements Comparable
this.peerID = new PeerID(id, sock.getPeerDestination());
_id = ++__id;
if (_log.shouldLog(Log.DEBUG))
_log.debug("Creating a new peer with " + peerID.getAddress().calculateHash().toBase64(), new Exception("creating " + _id));
_log.debug("Creating a new peer with " + peerID.toString(), new Exception("creating " + _id));
}
/**
@@ -216,7 +216,7 @@ public class Peer implements Comparable
throw new IllegalStateException("Peer already started");
if (_log.shouldLog(Log.DEBUG))
_log.debug("Running connection to " + peerID.getAddress().calculateHash().toBase64(), new Exception("connecting"));
_log.debug("Running connection to " + peerID.toString(), new Exception("connecting"));
try
{
// Do we need to handshake?

View File

@@ -301,7 +301,7 @@ public class TrackerClient extends I2PAppThread
// only delay if we actually make an attempt to add peer
if(coordinator.addPeer(cur)) {
int delay = DELAY_MUL;
delay *= ((int)cur.getPeerID().getAddress().calculateHash().toBase64().charAt(0)) % 10;
delay *= r.nextInt(10);
delay += DELAY_MIN;
sleptTime += delay;
try { Thread.sleep(delay); } catch (InterruptedException ie) {}

View File

@@ -9,6 +9,7 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import net.i2p.router.client.ClientManagerFacadeImpl;
import net.i2p.router.startup.ClientAppConfig;
import net.i2p.router.startup.LoadClientAppsJob;
@@ -35,6 +36,10 @@ public class ConfigClientsHandler extends FormHandler {
saveClientChanges();
return;
}
if (_action.equals(_("Save Interface Configuration"))) {
saveInterfaceChanges();
return;
}
if (_action.equals(_("Save WebApp Configuration"))) {
saveWebAppChanges();
return;
@@ -193,7 +198,7 @@ public class ConfigClientsHandler extends FormHandler {
String[] arr = (String[]) _settings.get(key);
if (arr == null)
return null;
return arr[0];
return arr[0].trim();
}
private void startClient(int i) {
@@ -337,4 +342,37 @@ public class ConfigClientsHandler extends FormHandler {
_log.error("Error starting plugin " + app, e);
}
}
/**
* Handle interface form
* @since 0.8.3
*/
private void saveInterfaceChanges() {
String port = getJettyString("port");
if (port != null)
_context.router().setConfigSetting(ClientManagerFacadeImpl.PROP_CLIENT_PORT, port);
String intfc = getJettyString("interface");
if (intfc != null)
_context.router().setConfigSetting(ClientManagerFacadeImpl.PROP_CLIENT_HOST, intfc);
String user = getJettyString("user");
if (user != null)
_context.router().setConfigSetting(ConfigClientsHelper.PROP_USER, user);
String pw = getJettyString("pw");
if (pw != null)
_context.router().setConfigSetting(ConfigClientsHelper.PROP_PW, pw);
String mode = getJettyString("mode");
boolean disabled = "0".equals(mode);
boolean ssl = "2".equals(mode);
_context.router().setConfigSetting(ConfigClientsHelper.PROP_DISABLE_EXTERNAL,
Boolean.toString(disabled));
_context.router().setConfigSetting(ConfigClientsHelper.PROP_ENABLE_SSL,
Boolean.toString(ssl));
_context.router().setConfigSetting(ConfigClientsHelper.PROP_AUTH,
Boolean.toString((_settings.get("auth") != null)));
boolean all = "0.0.0.0".equals(intfc) || "0:0:0:0:0:0:0:0".equals(intfc) ||
"::".equals(intfc);
_context.router().setConfigSetting(ConfigClientsHelper.BIND_ALL_INTERFACES, Boolean.toString(all));
_context.router().saveConfig();
addFormNotice(_("Interface configuration saved successfully - restart required to take effect."));
}
}

View File

@@ -1,6 +1,9 @@
package net.i2p.router.web;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
@@ -8,13 +11,90 @@ import java.util.Properties;
import java.util.Set;
import java.util.TreeSet;
import net.i2p.router.client.ClientManagerFacadeImpl;
import net.i2p.router.startup.ClientAppConfig;
import net.i2p.router.transport.Addresses;
public class ConfigClientsHelper extends HelperBase {
private String _edit;
/** from ClientListenerRunner */
public static final String BIND_ALL_INTERFACES = "i2cp.tcp.bindAllInterfaces";
/** from ClientManager */
public static final String PROP_DISABLE_EXTERNAL = "i2cp.disableInterface";
public static final String PROP_ENABLE_SSL = "i2cp.SSL";
/** from ClientMessageEventListener */
public static final String PROP_AUTH = "i2cp.auth";
public static final String PROP_USER = "i2cp.username";
public static final String PROP_PW = "i2cp.password";
public ConfigClientsHelper() {}
/** @since 0.8.3 */
public String getPort() {
return _context.getProperty(ClientManagerFacadeImpl.PROP_CLIENT_PORT,
Integer.toString(ClientManagerFacadeImpl.DEFAULT_PORT));
}
/** @since 0.8.3 */
public String getUser() {
return _context.getProperty(PROP_USER, "");
}
/** @since 0.8.3 */
public String getPw() {
return _context.getProperty(PROP_PW, "");
}
/** @since 0.8.3 */
public String i2cpModeChecked(int mode) {
boolean disabled = _context.getBooleanProperty(PROP_DISABLE_EXTERNAL);
boolean ssl = _context.getBooleanProperty(PROP_ENABLE_SSL);
if ((mode == 0 && disabled) ||
(mode == 1 && (!disabled) && (!ssl)) ||
(mode == 2 && (!disabled) && ssl))
return "checked=\"true\"";
return "";
}
/** @since 0.8.3 */
public String getAuth() {
boolean enabled = _context.getBooleanProperty(PROP_AUTH);
if (enabled)
return "checked=\"true\"";
return "";
}
/** @since 0.8.3 */
public String[] intfcAddresses() {
String[] addrs = Addresses.getAllAddresses();
List<String> aList = new ArrayList();
aList.addAll(Arrays.asList(addrs));
boolean ipv6 = false;
for (String a : aList) {
if (a.indexOf(':') >= 0) {
ipv6 = true;
break;
}
}
if (!aList.contains("0.0.0.0"))
aList.add("0.0.0.0");
if (ipv6 && !aList.contains("0:0:0:0:0:0:0:0"))
aList.add("0:0:0:0:0:0:0:0"); // we could do "::" but all the other ones are probably in long form
Collections.sort(aList);
return aList.toArray(addrs);
}
/** @since 0.8.3 */
public boolean isIFSelected(String addr) {
boolean bindAll = _context.getBooleanProperty(BIND_ALL_INTERFACES);
if (bindAll && addr.equals("0.0.0.0") || addr.equals("::"))
return true;
String host = _context.getProperty(ClientManagerFacadeImpl.PROP_CLIENT_HOST,
ClientManagerFacadeImpl.DEFAULT_HOST);
return (host.equals(addr));
}
public void setEdit(String edit) {
if (edit == null)
return;
@@ -92,9 +172,9 @@ public class ConfigClientsHelper extends HelperBase {
continue;
StringBuilder desc = new StringBuilder(256);
desc.append("<table border=\"0\">")
.append("<tr><td><b>").append(_("Version")).append("<td>").append(stripHTML(appProps, "version"))
.append("<tr><td><b>").append(_("Version")).append("</b></td><td>").append(stripHTML(appProps, "version"))
.append("<tr><td><b>")
.append(_("Signed by")).append("<td>");
.append(_("Signed by")).append("</b></td><td>");
String s = stripHTML(appProps, "signer");
if (s != null) {
if (s.indexOf("@") > 0)
@@ -111,13 +191,13 @@ public class ConfigClientsHelper extends HelperBase {
if (ms > 0) {
String date = (new SimpleDateFormat("yyyy-MM-dd HH:mm")).format(new Date(ms));
desc.append("<tr><td><b>")
.append(_("Date")).append("<td>").append(date);
.append(_("Date")).append("</b></td><td>").append(date);
}
}
s = stripHTML(appProps, "author");
if (s != null) {
desc.append("<tr><td><b>")
.append(_("Author")).append("<td>");
.append(_("Author")).append("</b></td><td>");
if (s.indexOf("@") > 0)
desc.append("<a href=\"mailto:").append(s).append("\">").append(s).append("</a>");
else
@@ -128,12 +208,12 @@ public class ConfigClientsHelper extends HelperBase {
s = stripHTML(appProps, "description");
if (s != null) {
desc.append("<tr><td><b>")
.append(_("Description")).append("<td>").append(s);
.append(_("Description")).append("</b></td><td>").append(s);
}
s = stripHTML(appProps, "license");
if (s != null) {
desc.append("<tr><td><b>")
.append(_("License")).append("<td>").append(s);
.append(_("License")).append("</b></td><td>").append(s);
}
s = stripHTML(appProps, "websiteURL");
if (s != null) {

View File

@@ -139,6 +139,6 @@ public class ConfigStatsHelper extends HelperBase {
public boolean getCurrentCanBeGraphed() { return _currentCanBeGraphed; }
public String getExplicitFilter() { return _filter; }
public boolean getIsFull() {
return _context.getBooleanPropertyDefaultTrue(StatManager.PROP_STAT_FULL);
return _context.getBooleanProperty(StatManager.PROP_STAT_FULL);
}
}

View File

@@ -1,8 +1,11 @@
package net.i2p.router.web;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;
@@ -15,10 +18,12 @@ import net.i2p.router.RouterVersion;
import net.i2p.util.EepGet;
import net.i2p.util.I2PAppThread;
import net.i2p.util.Log;
import net.i2p.util.PartialEepGet;
import net.i2p.util.VersionComparator;
/**
* <p>Handles the request to update the router by firing off an
* {@link net.i2p.util.EepGet} call to download the latest signed update file
* <p>Handles the request to update the router by firing one or more
* {@link net.i2p.util.EepGet} calls to download the latest signed update file
* and displaying the status to anyone who asks.
* </p>
* <p>After the download completes the signed update file is verified with
@@ -125,6 +130,11 @@ public class UpdateHandler {
protected boolean done;
protected EepGet _get;
protected final DecimalFormat _pct = new DecimalFormat("0.0%");
/** tells the listeners what mode we are in */
private boolean _isPartial;
/** set by the listeners on completion */
private boolean _isNewer;
private ByteArrayOutputStream _baos;
public UpdateRunner() {
_isRunning = false;
@@ -141,39 +151,88 @@ public class UpdateHandler {
System.setProperty(PROP_UPDATE_IN_PROGRESS, "false");
_isRunning = false;
}
/**
* Loop through the entire list of update URLs.
* For each one, first get the version from the first 56 bytes and see if
* it is newer than what we are running now.
* If it is, get the whole thing.
*/
protected void update() {
updateStatus("<b>" + _("Updating") + "</b>");
// TODO:
// Do a PartialEepGet on the selected URL, check for version we expect,
// and loop if it isn't what we want.
// This will allow us to do a release without waiting for the last host to install the update.
// Alternative: In bytesTransferred(), Check the data in the output file after
// we've received at least 56 bytes. Need a cancel() method in EepGet ?
String updateURL = selectUpdateURL();
if (_log.shouldLog(Log.DEBUG))
_log.debug("Selected update URL: " + updateURL);
boolean shouldProxy = Boolean.valueOf(_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY)).booleanValue();
String proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
int proxyPort = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_PORT, ConfigUpdateHandler.DEFAULT_PROXY_PORT_INT);
try {
if (shouldProxy)
// 40 retries!!
_get = new EepGet(_context, proxyHost, proxyPort, 40, _updateFile, updateURL, false);
else
_get = new EepGet(_context, 1, _updateFile, updateURL, false);
_get.addStatusListener(UpdateRunner.this);
_get.fetch();
} catch (Throwable t) {
_log.error("Error updating", t);
List<String> urls = getUpdateURLs();
if (urls.isEmpty()) {
// not likely, don't bother translating
updateStatus("<b>Update source list is empty, cannot download update</b>");
_log.log(Log.CRIT, "Update source list is empty - cannot download update");
return;
}
if (shouldProxy)
_baos = new ByteArrayOutputStream(TrustedUpdate.HEADER_BYTES);
for (String updateURL : urls) {
updateStatus("<b>" + _("Updating from {0}", linkify(updateURL)) + "</b>");
if (_log.shouldLog(Log.DEBUG))
_log.debug("Selected update URL: " + updateURL);
// Check the first 56 bytes for the version
if (shouldProxy) {
_isPartial = true;
_isNewer = false;
_baos.reset();
try {
// no retries
_get = new PartialEepGet(_context, proxyHost, proxyPort, _baos, updateURL, TrustedUpdate.HEADER_BYTES);
_get.addStatusListener(UpdateRunner.this);
_get.fetch();
} catch (Throwable t) {
_isNewer = false;
}
_isPartial = false;
if (!_isNewer)
continue;
}
// Now get the whole thing
try {
if (shouldProxy)
// 40 retries!!
_get = new EepGet(_context, proxyHost, proxyPort, 40, _updateFile, updateURL, false);
else
_get = new EepGet(_context, 1, _updateFile, updateURL, false);
_get.addStatusListener(UpdateRunner.this);
_get.fetch();
} catch (Throwable t) {
_log.error("Error updating", t);
}
if (this.done)
break;
}
}
// EepGet Listeners below.
// We use the same for both the partial and the full EepGet,
// with a couple of adjustments depending on which mode.
public void attemptFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt, int numRetries, Exception cause) {
_isNewer = false;
if (_log.shouldLog(Log.DEBUG))
_log.debug("Attempt failed on " + url, cause);
// ignored
}
public void bytesTransferred(long alreadyTransferred, int currentWrite, long bytesTransferred, long bytesRemaining, String url) {
if (_isPartial)
return;
StringBuilder buf = new StringBuilder(64);
buf.append("<b>").append(_("Updating")).append("</b> ");
double pct = ((double)alreadyTransferred + (double)currentWrite) /
@@ -186,6 +245,19 @@ public class UpdateHandler {
updateStatus(buf.toString());
}
public void transferComplete(long alreadyTransferred, long bytesTransferred, long bytesRemaining, String url, String outputFile, boolean notModified) {
if (_isPartial) {
// Compare version with what we have now
String newVersion = TrustedUpdate.getVersionString(new ByteArrayInputStream(_baos.toByteArray()));
boolean newer = (new VersionComparator()).compare(newVersion, RouterVersion.VERSION) > 0;
if (!newer) {
updateStatus("<b>" + _("No new version found at {0}", linkify(url)) + "</b>");
if (_log.shouldLog(Log.WARN))
_log.warn("Found old version \"" + newVersion + "\" at " + url);
}
_isNewer = newer;
return;
}
// Process the .sud/.su2 file
updateStatus("<b>" + _("Update downloaded") + "</b>");
TrustedUpdate up = new TrustedUpdate(_context);
File f = new File(_updateFile);
@@ -223,15 +295,16 @@ public class UpdateHandler {
}
} else {
_log.log(Log.CRIT, err + " from " + url);
updateStatus("<b>" + err + ' ' + _("from {0}", url) + " </b>");
updateStatus("<b>" + err + ' ' + _("from {0}", linkify(url)) + " </b>");
}
}
public void transferFailed(String url, long bytesTransferred, long bytesRemaining, int currentAttempt) {
_isNewer = false;
// don't display bytesTransferred as it is meaningless
_log.log(Log.CRIT, "Update from " + url + " did not download completely (" +
_log.error("Update from " + url + " did not download completely (" +
bytesRemaining + " remaining after " + currentAttempt + " tries)");
updateStatus("<b>" + _("Transfer failed") + "</b>");
updateStatus("<b>" + _("Transfer failed from {0}", linkify(url)) + "</b>");
}
public void headerReceived(String url, int attemptNum, String key, String val) {}
public void attempting(String url) {}
@@ -242,27 +315,24 @@ public class UpdateHandler {
_context.router().shutdownGracefully(Router.EXIT_GRACEFUL_RESTART);
}
private String selectUpdateURL() {
private List<String> getUpdateURLs() {
String URLs = _context.getProperty(ConfigUpdateHandler.PROP_UPDATE_URL, ConfigUpdateHandler.DEFAULT_UPDATE_URL);
StringTokenizer tok = new StringTokenizer(URLs, " ,\r\n");
List URLList = new ArrayList();
List<String> URLList = new ArrayList();
while (tok.hasMoreTokens())
URLList.add(tok.nextToken().trim());
int size = URLList.size();
//_log.log(Log.DEBUG, "Picking update source from " + size + " candidates.");
if (size <= 0) {
_log.log(Log.CRIT, "Update source list is empty - cannot download update");
return null;
}
int index = I2PAppContext.getGlobalContext().random().nextInt(size);
_log.log(Log.DEBUG, "Picked update source " + index + ".");
return (String) URLList.get(index);
Collections.shuffle(URLList, _context.random());
return URLList;
}
protected void updateStatus(String s) {
_status = s;
}
protected static String linkify(String url) {
return "<a target=\"_blank\" href=\"" + url + "\"/>" + url + "</a>";
}
/** translate a string */
protected String _(String s) {
return Messages.getString(s, _context);

View File

@@ -47,7 +47,51 @@ button span.hide{
<input type="submit" name="edit" value="<%=intl._("Add Client")%>" />
<% } %>
<input type="submit" name="action" value="<%=intl._("Save Client Configuration")%>" />
</div></div><h3><a name="webapp"></a><%=intl._("WebApp Configuration")%></h3><p>
</div></div>
<h3><a name="i2cp"></a><%=intl._("Advanced Client Interface Configuration")%></h3><p>
<b><%=intl._("External I2CP (I2P Client Protocol) Interface Configuration")%></b><br>
<input type="radio" class="optbox" name="mode" value="1" <%=clientshelper.i2cpModeChecked(1) %> >
<%=intl._("Enabled without SSL")%><br>
<input type="radio" class="optbox" name="mode" value="2" <%=clientshelper.i2cpModeChecked(2) %> >
<%=intl._("Enabled with SSL required")%><br>
<input type="radio" class="optbox" name="mode" value="0" <%=clientshelper.i2cpModeChecked(0) %> >
<%=intl._("Disabled - Clients outside this Java process may not connect")%><br>
<%=intl._("I2CP Port")%>:
<input name="port" type="text" size="5" maxlength="5" value="<jsp:getProperty name="clientshelper" property="port" />" ><br>
<%=intl._("I2CP Interface")%>:
<select name="interface">
<%
String[] ips = clientshelper.intfcAddresses();
for (int i = 0; i < ips.length; i++) {
out.print("<option value=\"");
out.print(ips[i]);
out.print('\"');
if (clientshelper.isIFSelected(ips[i]))
out.print(" selected=\"selected\"");
out.print('>');
out.print(ips[i]);
out.print("</option>\n");
}
%>
</select><br>
<b><%=intl._("Authorization")%></b><br>
<input type="checkbox" class="optbox" name="auth" value="true" <jsp:getProperty name="clientshelper" property="auth" /> >
<%=intl._("Requre username and password")%><br>
<%=intl._("Username")%>:
<input name="user" type="text" value="<jsp:getProperty name="clientshelper" property="user" />" ><br>
<%=intl._("Password")%>:
<input name="pw" type="password" value="<jsp:getProperty name="clientshelper" property="pw" />" ><br>
</p><p><b><%=intl._("The default settings will work for most people.")%></b>
<%=intl._("Any changes made here must also be configured in the external client.")%>
<%=intl._("Many clients do not support SSL or authorization.")%>
<i><%=intl._("All changes require restart to take effect.")%></i>
</p><hr><div class="formaction">
<input type="submit" name="foo" value="<%=intl._("Cancel")%>" />
<input type="submit" name="action" value="<%=intl._("Save Interface Configuration")%>" />
</div>
<h3><a name="webapp"></a><%=intl._("WebApp Configuration")%></h3><p>
<%=intl._("The Java web applications listed below are started by the webConsole client and run in the same JVM as the router. They are usually web applications accessible through the router console. They may be complete applications (e.g. i2psnark),front-ends to another client or application which must be separately enabled (e.g. susidns, i2ptunnel), or have no web interface at all (e.g. addressbook).")%>
</p><p>
<%=intl._("A web app may also be disabled by removing the .war file from the webapps directory; however the .war file and web app will reappear when you update your router to a newer version, so disabling the web app here is the preferred method.")%>