From 0c5c18a76797566f4a050de563fd8390ae89f1c0 Mon Sep 17 00:00:00 2001 From: zzz Date: Sun, 31 Aug 2014 16:19:46 +0000 Subject: [PATCH] * Build: Add support for bundling router infos in the package --- build.properties | 6 + build.xml | 22 ++- .../kademlia/PersistentDataStore.java | 161 ++++++++++++++++++ .../net/i2p/router/startup/WorkingDir.java | 2 + 4 files changed, 190 insertions(+), 1 deletion(-) diff --git a/build.properties b/build.properties index 8ee39009bf..7479e174e1 100644 --- a/build.properties +++ b/build.properties @@ -91,3 +91,9 @@ javac.version=1.6 # Optional properties used in tests to enable additional tools. #with.cobertura=/PATH/TO/cobertura.jar #with.clover=/PATH/TO/clover.jar + +### Bundle router infos ### +# Set to bundle router infos from your local I2P install in the package +#bundle.routerInfos=true +#bundle.routerInfos.count=200 +#bundle.routerInfos.i2pConfigDir=/PATH/TO/.i2p diff --git a/build.xml b/build.xml index 6c243f857a..9c9d9e4a55 100644 --- a/build.xml +++ b/build.xml @@ -960,7 +960,7 @@ - + @@ -1054,6 +1054,26 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java b/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java index 79117a4371..f4e6767ca4 100644 --- a/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java +++ b/router/java/src/net/i2p/router/networkdb/kademlia/PersistentDataStore.java @@ -17,6 +17,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; +import java.util.Collection; import java.util.Collections; import java.util.Iterator; import java.util.List; @@ -25,10 +26,13 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.concurrent.ConcurrentHashMap; +import gnu.getopt.Getopt; + import net.i2p.data.Base64; import net.i2p.data.DatabaseEntry; import net.i2p.data.DataFormatException; import net.i2p.data.Hash; +import net.i2p.data.RouterAddress; import net.i2p.data.RouterInfo; import net.i2p.router.JobImpl; import net.i2p.router.Router; @@ -660,4 +664,161 @@ class PersistentDataStore extends TransientDataStore { return (name.startsWith(ROUTERINFO_PREFIX.toUpperCase(Locale.US)) && name.endsWith(ROUTERINFO_SUFFIX.toUpperCase(Locale.US))); } } + + /** + * Usage: PersistentDataStore -i configDir -o toDir -c count + * + * Copy a random selection of 'count' router infos from configDir/netDb + * to 'toDir'. Skip your own router info, and old, hidden, unreachable, and + * introduced routers. + * + * Used in the build process, do not comment out. + * + * @since 0.9.15 + */ + public static void main(String[] args) { + Getopt g = new Getopt("PersistentDataStore", args, "i:o:c:"); + String in = System.getProperty("user.home") + "/.i2p"; + String out = "netDb"; + int count = 200; + boolean error = false; + int c; + while ((c = g.getopt()) != -1) { + switch (c) { + case 'i': + in = g.getOptarg(); + break; + + case 'o': + out = g.getOptarg(); + break; + + case 'c': + String scount = g.getOptarg(); + try { + count = Integer.parseInt(scount); + } catch (NumberFormatException nfe) { + error = true; + } + break; + + case '?': + case ':': + default: + error = true; + } + } + if (error) { + usage(); + System.exit(1); + } + + File confDir = new File(in); + File dbDir = new File(confDir, "netDb"); + if (!dbDir.exists()) { + System.out.println("NetDB directory " + dbDir + " does not exist"); + System.exit(1); + } + File myFile = new File(confDir, "router.info"); + File toDir = new File(out); + toDir.mkdirs(); + InputStream fis = null; + Hash me = null; + try { + fis = new BufferedInputStream(new FileInputStream(myFile)); + RouterInfo ri = new RouterInfo(); + ri.readBytes(fis, true); // true = verify sig on read + me = ri.getIdentity().getHash(); + } catch (Exception e) { + //System.out.println("Can't determine our identity"); + } finally { + if (fis != null) try { fis.close(); } catch (IOException ioe) {} + } + + int routerCount = 0; + List toRead = new ArrayList(2048); + for (int j = 0; j < B64.length(); j++) { + File subdir = new File(dbDir, DIR_PREFIX + B64.charAt(j)); + File[] files = subdir.listFiles(RouterInfoFilter.getInstance()); + if (files == null) + continue; + routerCount += files.length; + for (int i = 0; i < files.length; i++) { + toRead.add(files[i]); + } + } + if (toRead.isEmpty()) { + System.out.println("No files to copy in " + dbDir); + System.exit(1); + } + Collections.shuffle(toRead); + int copied = 0; + long tooOld = System.currentTimeMillis() - 7*24*60*60*1000L; + for (File file : toRead) { + if (copied >= count) + break; + Hash key = getRouterInfoHash(file.getName()); + if (key == null) { + System.out.println("Skipping bad " + file); + continue; + } + if (key.equals(me)) { + System.out.println("Skipping my RI"); + continue; + } + fis = null; + try { + fis = new BufferedInputStream(new FileInputStream(file)); + RouterInfo ri = new RouterInfo(); + ri.readBytes(fis, true); // true = verify sig on read + try { fis.close(); } catch (IOException ioe) {} + fis = null; + if (ri.getPublished() < tooOld) { + System.out.println("Skipping too old " + key); + continue; + } + if (ri.getCapabilities().contains("U")) { + System.out.println("Skipping unreachable " + key); + continue; + } + Collection addrs = ri.getAddresses(); + if (addrs.isEmpty()) { + System.out.println("Skipping hidden " + key); + continue; + } + boolean hasIntro = false; + for (RouterAddress addr : addrs) { + if ("SSU".equals(addr.getTransportStyle()) && addr.getOption("ihost0") != null) { + hasIntro = true; + break; + } + } + if (hasIntro) { + System.out.println("Skipping introduced " + key); + continue; + } + File toFile = new File(toDir, file.getName()); + // We could call ri.write() to avoid simultaneous change by the router + boolean ok = FileUtil.copy(file, toFile, true, true); + if (ok) + copied++; + else + System.out.println("Failed copy of " + file + " to " + toDir); + } catch (Exception e) { + System.out.println("Skipping bad " + file); + } finally { + if (fis != null) try { fis.close(); } catch (IOException ioe) {} + } + } + if (copied > 0) { + System.out.println("Copied " + copied + " router info files to " + toDir); + } else { + System.out.println("Failed to copy any files to " + toDir); + System.exit(1); + } + } + + private static void usage() { + System.err.println("Usage: PersistentDataStore [-i $HOME/.i2p] [-o netDb/] [-c 200]"); + } } diff --git a/router/java/src/net/i2p/router/startup/WorkingDir.java b/router/java/src/net/i2p/router/startup/WorkingDir.java index 3763f2e7a7..d44b2a5397 100644 --- a/router/java/src/net/i2p/router/startup/WorkingDir.java +++ b/router/java/src/net/i2p/router/startup/WorkingDir.java @@ -271,6 +271,8 @@ public class WorkingDir { // We don't currently have a default addressbook/ in the base distribution, // but distros might put one in "addressbook,eepsite," + + // 0.9.15 support bundled router infos + "netDb," + // base install - files // We don't currently have a default router.config, logger.config, susimail.config, or webapps.config in the base distribution, // but distros might put one in