Compare commits

...

3 Commits

3 changed files with 201 additions and 2 deletions

View File

@ -4,15 +4,31 @@ import java.io.IOException;
import java.text.Collator;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
import net.i2p.I2PAppContext;
import net.i2p.client.I2PClient;
import net.i2p.client.I2PSession;
import net.i2p.client.I2PSessionException;
import net.i2p.client.I2PSimpleClient;
import net.i2p.client.naming.LookupDest;
import net.i2p.crypto.EncType;
import net.i2p.crypto.SigType;
import net.i2p.data.DataHelper;
import net.i2p.data.Destination;
import net.i2p.data.Hash;
import net.i2p.data.LeaseSet;
import net.i2p.data.i2np.DatabaseStoreMessage;
import net.i2p.data.i2np.DeliveryInstructions;
import net.i2p.data.router.RouterInfo;
import net.i2p.util.ConvertToHash;
import net.i2p.util.SystemVersion;
import net.i2p.router.JobImpl;
import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
import net.i2p.router.sybil.Analysis;
import net.i2p.router.web.FormHandler;
import net.i2p.router.web.Messages;
@ -39,6 +55,8 @@ public class NetDbHelper extends FormHandler {
private String _newNonce;
private boolean _postOK;
private String _sendhash, _recvhash, _sraction;
private static final int DEFAULT_LIMIT = SystemVersion.isARM() ? 250 : 500;
private static final int DEFAULT_PAGE = 0;
@ -54,7 +72,8 @@ public class NetDbHelper extends FormHandler {
"Sybil", // 7
"Advanced Lookup", // 8
"LeaseSet Lookup", // 9
"LeaseSets (Client DBs)" // 10
"LeaseSets (Client DBs)", // 10
"Manual Interactions", // 11
};
private static final String links[] =
@ -69,6 +88,7 @@ public class NetDbHelper extends FormHandler {
"?f=4", // 8
"", // 9
"?l=7", // 10
"?f=5", // 11
};
@ -245,6 +265,18 @@ public class NetDbHelper extends FormHandler {
_icount = Integer.parseInt(f);
} catch (NumberFormatException nfe) {}
}
public void setSendhash(String f) {
_sendhash = f;
}
public void setRecvhash(String f) {
_recvhash = f;
}
public void setSraction(String f) {
_sraction = f;
}
/**
* call for non-text-mode browsers
@ -316,7 +348,12 @@ public class NetDbHelper extends FormHandler {
NetDbRenderer renderer = new NetDbRenderer(_context);
try {
renderNavBar();
if (_routerPrefix != null || _version != null || _country != null ||
if ((_sendhash != null && _recvhash != null && _sraction != null) &&
(!_sendhash.equals("") && !_recvhash.equals("") && !_sraction.equals(""))) {
_log.error("'" + _sendhash + "' '" + _recvhash + "' '" + _sraction, new Exception());
renderManipulationForm();
renderManipulationResult();
} else if (_routerPrefix != null || _version != null || _country != null ||
_family != null || _caps != null || _ip != null || _sybil != null ||
_port != 0 || _type != null || _mtu != null || _ipv6 != null ||
_ssucaps != null || _transport != null || _cost != 0 || _etype != null ||
@ -337,6 +374,8 @@ public class NetDbHelper extends FormHandler {
(new SybilRenderer(_context)).getNetDbSummary(_out, _newNonce, _mode, _date);
} else if (_full == 4) {
renderLookupForm();
} else if (_full == 5) {
renderManipulationForm();
} else if (_clientOnly) {
for (Hash client : _context.clientManager().getPrimaryHashes()) {
renderer.renderLeaseSetHTML(_out, false, client);
@ -379,6 +418,8 @@ public class NetDbHelper extends FormHandler {
return 9;
if (_clientOnly)
return 10;
if (_full == 5)
return 11;
return 0;
}
@ -484,4 +525,115 @@ public class NetDbHelper extends FormHandler {
"<button type=\"submit\" class=\"search\" value=\"Lookup\">Lookup</button></td></tr>\n" +
"</table>\n</form>\n");
}
private void renderManipulationForm() throws IOException {
_out.write("<form action=\"/netdb\" method=\"POST\">\n" +
"<input type=\"hidden\" name=\"nonce\" value=\"" + _newNonce + "\" >\n" +
"<table id=\"netdblookup\"><tr><th colspan=\"3\">Network Database Interaction</th></tr>\n");
_out.write("<tr><td>Hash(LeaseSet) to send:</td>" +
"<td><input type=\"text\" name=\"sendhash\"></td><td></td></tr>\n" +
"<tr><td>Hash(LeaseSet or RouterInfo) to target:</td>" +
"<td><input type=\"text\" name=\"recvhash\"></td><td></td></tr>\n" +
"<tr><td><button type=\"reset\" class=\"cancel\" value=\"Cancel\">" + _t("Cancel") + "</button> " +
"<button type=\"submit\" class=\"search\" name=\"sraction\" value=\"Search\">" + _t("Search") + "</button>\n" +
"<button type=\"submit\" class=\"store\" name=\"sraction\" value=\"Store\">" + _t("Store") + "</button>\n" +
"<button type=\"submit\" class=\"storesearch\" name=\"sraction\" value=\"StoreThenSearch\">"+ _t("Store then Search") +"</button></td></tr>\n" +
"</table>\n</form>\n");
}
private void renderManipulationResult() throws IOException {
String _searchResult = "search for" + _sendhash + " on " + _recvhash;
String _storeResult = "store for" + _sendhash + " on " + _recvhash;
Destination recvhash = null;
try {
recvhash = lookupDest(_recvhash);
if (recvhash == null) {
_searchResult = "Search Target Hash not found for: " + _recvhash;
_storeResult = "Store Target Hash not found for: " + _recvhash;
}
} catch (Exception e) {
_searchResult = "Search Exception: Target Hash not found for: " + _recvhash + e.toString();
_storeResult = "Store Exception: Target Hash not found for: " + _recvhash + e.toString();
}
Destination sendhash = null;
try {
sendhash = lookupDest(_sendhash);
if (sendhash == null) {
_searchResult = "Search Hash not found for: " + _sendhash;
_storeResult = "Store Hash not found for: " + _sendhash;
}
} catch (Exception e) {
_searchResult = "Search Exception: Search Hash not found for: " + _sendhash + e.toString();
_storeResult = "Store Exception: Store Hash not found for: " + _sendhash + e.toString();
}
if (recvhash != null && sendhash != null) {
RouterInfo ri = _context.netDb().lookupRouterInfoLocally(recvhash.getHash());
LeaseSet ls = _context.netDb().lookupLeaseSetLocally(recvhash.getHash());
LeaseSet sendls = _context.netDb().lookupLeaseSetLocally(sendhash.getHash());
if (ri != null && ls == null && sendls != null) {
_searchResult = "Search for LeaseSet: " + sendls.getHash() + " on Router: " + ri.getIdentity().getHash();
_storeResult = "Store for LeaseSet: " + sendls.getHash() + " on Router: " + ri.getIdentity().getHash();
} else if (ri == null && ls != null && sendls != null) {
_searchResult = "Search for LeaseSet: " + sendls.getHash() + " on client: " + ls.getHash();
_storeResult = "Store for LeaseSet: " + sendls.getHash() + " on client: " + ls.getHash();
}
}
String _searchThenStoreResult = _searchResult + ", then "+ _storeResult;
_out.write("<div id=\"netdbresult\">"+
"<table id=\"netdbresult\"><tr><th colspan=\"3\">Network Database Interaction Results</th></tr>\n");
switch (_sraction) {
case "Search":
// searching for sendHash on recvHash
_out.write("<tr><td>Search result:</td><td colspan=\"2\"><pre>" + _searchResult + "</pre></td></tr>\n");
break;
case "Store":
// storing sendHash on recvHash
_out.write("<tr><td>Store result:</td><td colspan=\"2\"><pre>" + _storeResult + "</pre></td></tr>\n");
break;
case "StoreThenSearch":
// storing sendHash on recvHash, then searching for sendHash on recvHash
_out.write("<tr><td>Store result:</td><td colspan=\"2\"><pre>" + _searchThenStoreResult + "</pre></td></tr>\n");
}
_out.write("</table></div>\n");
}
private boolean sendStoreToTarget(Hash sendhash, RouterInfo target) {
return false;
}
private boolean searchFromTarget(Hash sendhash, RouterInfo target) {
return false;
}
private boolean searchThenStoreFromTarget(Hash sendhash, RouterInfo target) {
return false;
}
private Destination lookupDest(String hostname) throws I2PSessionException {
if (hostname == null) return null;
Hash hash = ConvertToHash.getHash(hostname);
_context.netDb().lookupDestination(hash, null, DEFAULT_LIMIT, null);
LookupWaiter lw = new LookupWaiter();
synchronized(lw) {
try { lw.wait(9*1000); } catch (InterruptedException ie) {}
}
Destination rv = _context.netDb().lookupDestinationLocally(hash);
return rv;
}
private class LookupWaiter extends JobImpl {
public LookupWaiter() { super(_context); }
public void runJob() {
synchronized(this) {
notifyAll();
}
}
public String getName() { return "Console netdb lookup"; }
}
}

View File

@ -40,6 +40,11 @@
<jsp:setProperty name="formhandler" property="leaseset" value="<%=request.getParameter(\"ls\")%>" />
<jsp:setProperty name="formhandler" property="sort" value="<%=request.getParameter(\"s\")%>" />
<jsp:setProperty name="formhandler" property="intros" value="<%=request.getParameter(\"i\")%>" />
<jsp:setProperty name="formhandler" property="sendhash" value="<%=request.getParameter(\"sendhash\")%>" />
<jsp:setProperty name="formhandler" property="recvhash" value="<%=request.getParameter(\"recvhash\")%>" />
<jsp:setProperty name="formhandler" property="sraction" value="<%=request.getParameter(\"sraction\")%>" />
<%@include file="formhandler.jsi" %>
<jsp:getProperty name="formhandler" property="netDbSummary" />
</div></body></html>

View File

@ -257,6 +257,48 @@ public class FloodfillNetworkDatabaseFacade extends KademliaNetworkDatabaseFacad
return true;
}
/**
* Send to a specific peer, specified by hash
*
* @param ds
*/
public void flood(DatabaseEntry ds, Hash h) {
Hash key = ds.getHash();
Hash peer = h;
DatabaseStoreMessage msg = new DatabaseStoreMessage(_context);
msg.setEntry(ds);
RouterInfo ritarget = _context.netDb().lookupRouterInfoLocally(key);
if (ritarget != null) {
flood(ds, ritarget, msg, peer);
}
LeaseSet lstarget = _context.netDb().lookupLeaseSetLocally(key);
if (lstarget != null) {
flood(ds, lstarget, msg, peer);
}
}
public void flood(DatabaseEntry ds, LeaseSet target, DatabaseStoreMessage msg, Hash peer) {
//OutNetMessage m = new OutNetMessage(_context, msg, _context.clock().now()+FLOOD_TIMEOUT, FLOOD_PRIORITY, target);
}
public void flood(DatabaseEntry ds, RouterInfo target, DatabaseStoreMessage msg, Hash peer) {
OutNetMessage m = new OutNetMessage(_context, msg, _context.clock().now()+FLOOD_TIMEOUT, FLOOD_PRIORITY, target);
Job floodFail = new FloodFailedJob(_context, peer);
m.setOnFailedSendJob(floodFail);
// we want to give credit on success, even if we aren't sure,
// because otherwise no use noting failure
Job floodGood = new FloodSuccessJob(_context, peer);
m.setOnSendJob(floodGood);
_context.commSystem().processMessage(m);
//flooded++;
if (_log.shouldLog(Log.INFO))
_log.info("Flooding the entry for " + ds.getHash() + " to " + peer.toBase64());
if (_log.shouldLog(Log.INFO))
_log.info("Flooded the data to " + peer);
}
/**
* Send to a subset of all floodfill peers.
* We do this to implement Kademlia within the floodfills, i.e.