PageRenderTime 75ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 1ms

/src/freenet/node/Node.java

https://github.com/freenet/legacy
Java | 5311 lines | 3982 code | 508 blank | 821 comment | 326 complexity | ef64a1efa861fd49520d8b84be251a55 MD5 | raw file
Possible License(s): GPL-2.0
  1. package freenet.node;
  2. import java.io.DataInputStream;
  3. import java.io.DataOutputStream;
  4. import java.io.File;
  5. import java.io.FileInputStream;
  6. import java.io.FileOutputStream;
  7. import java.io.IOException;
  8. import java.nio.channels.FileLock;
  9. import java.text.NumberFormat;
  10. import java.util.Enumeration;
  11. import freenet.Address;
  12. import freenet.Authentity;
  13. import freenet.Core;
  14. import freenet.CoreException;
  15. import freenet.DSAAuthentity;
  16. import freenet.DSAIdentity;
  17. import freenet.FieldSet;
  18. import freenet.Identity;
  19. import freenet.Key;
  20. import freenet.KeyException;
  21. import freenet.Message;
  22. import freenet.MessageSendCallback;
  23. import freenet.OpenConnectionManager;
  24. import freenet.Peer;
  25. import freenet.PeerPacketMessage;
  26. import freenet.Presentation;
  27. import freenet.PresentationHandler;
  28. import freenet.SendFailedException;
  29. import freenet.SessionHandler;
  30. import freenet.Ticker;
  31. import freenet.TrailerWriter;
  32. import freenet.TransportHandler;
  33. import freenet.Version;
  34. import freenet.client.BackgroundInserter;
  35. import freenet.client.ClientFactory;
  36. import freenet.client.FECTools;
  37. import freenet.client.InternalClient;
  38. import freenet.config.Config;
  39. import freenet.config.Params;
  40. import freenet.config.RandomPortOption;
  41. import freenet.diagnostics.Diagnostics;
  42. import freenet.fs.dir.Directory;
  43. import freenet.interfaces.NIOInterface;
  44. import freenet.node.ds.DataStore;
  45. import freenet.node.rt.ExtrapolatingTimeDecayingEventCounter;
  46. import freenet.node.rt.NGRouting;
  47. import freenet.node.rt.NGRoutingTable;
  48. import freenet.node.rt.NodeSortingRoutingTable;
  49. import freenet.node.rt.RTDiagSnapshot;
  50. import freenet.node.rt.RunningAverage;
  51. import freenet.node.rt.SimpleBinaryRunningAverage;
  52. import freenet.node.rt.SimpleIntervalledRunningAverage;
  53. import freenet.node.rt.SynchronizedRunningAverage;
  54. import freenet.node.rt.TimeDecayingRunningAverage;
  55. import freenet.session.LinkManager;
  56. import freenet.support.Bucket;
  57. import freenet.support.BucketFactory;
  58. import freenet.support.Checkpointed;
  59. import freenet.support.HexUtil;
  60. import freenet.support.IntervalledSum;
  61. import freenet.support.LimitCounter;
  62. import freenet.support.LoadSaveCheckpointed;
  63. import freenet.support.Logger;
  64. import freenet.support.io.Bandwidth;
  65. import freenet.support.io.ReadInputStream;
  66. import freenet.thread.ThreadFactory;
  67. import freenet.transport.tcpAddress;
  68. import freenet.transport.tcpConnection;
  69. import freenet.transport.tcpListener;
  70. /*
  71. * This code is part of the Java Adaptive Network Client by Ian Clarke. It is
  72. * distributed under the GNU Public Licence (GPL) version 2. See
  73. * http://www.gnu.org/ for further details of the GPL.
  74. */
  75. /**
  76. * This is a Wrapper object that contains the components of a Node in the
  77. * Adaptive Network. It uses a Network object to communicate with other Nodes
  78. * in the Network.
  79. *
  80. * @author <A HREF="mailto:I.Clarke@strs.co.uk">Ian Clarke</A>
  81. * @author <a href="mailto:blanu@uts.cc.utexas.edu">Brandon Wiley</a>
  82. */
  83. public class Node extends Core implements ConnectionThrottler{
  84. /**
  85. * @author root
  86. *
  87. * TODO To change the template for this generated type comment go to
  88. * Window - Preferences - Java - Code Generation - Code and Comments
  89. */
  90. private class RateLimitingWriterCheckpointed extends LoadSaveCheckpointed {
  91. public RateLimitingWriterCheckpointed(File routingDir) {
  92. super(routingDir, new String[] { "ratedata_a", "ratedata_b" });
  93. }
  94. protected int checkpointPeriod() {
  95. return 60000;
  96. }
  97. public void writeData(DataOutputStream dos) throws IOException {
  98. receivedRequestCounter.writeDataTo(dos);
  99. acceptedExternalRequestCounter.writeDataTo(dos);
  100. globalQuotaAverager.writeDataTo(dos);
  101. sentRequestCounter.writeDataTo(dos);
  102. }
  103. protected void fillInBlanks() {
  104. if(receivedRequestCounter == null)
  105. receivedRequestCounter = new ExtrapolatingTimeDecayingEventCounter(rateLimitingInterval, 1000);
  106. Core.logger.log(this, "receivedRequestCounter = "+receivedRequestCounter, Logger.DEBUG);
  107. if(acceptedExternalRequestCounter == null)
  108. acceptedExternalRequestCounter = new ExtrapolatingTimeDecayingEventCounter(rateLimitingInterval, 1000);
  109. Core.logger.log(this, "acceptedExternalRequestCounter = "+acceptedExternalRequestCounter, Logger.DEBUG);
  110. if(globalQuotaAverager == null)
  111. globalQuotaAverager = new TimeDecayingRunningAverage(1000, rateLimitingInterval, 0, Double.MAX_VALUE);
  112. Core.logger.log(this, "globalQuotaAverager = "+globalQuotaAverager, Logger.DEBUG);
  113. if(sentRequestCounter == null)
  114. sentRequestCounter = new ExtrapolatingTimeDecayingEventCounter(rateLimitingInterval/2, 1000);
  115. Core.logger.log(this, "sentRequestCounter = "+sentRequestCounter, Logger.DEBUG);
  116. }
  117. protected void readFrom(DataInputStream dis) throws IOException {
  118. receivedRequestCounter = new ExtrapolatingTimeDecayingEventCounter(1000, rateLimitingInterval, dis);
  119. Core.logger.log(this, "Read receivedRequestCounter: "+receivedRequestCounter, Logger.MINOR);
  120. acceptedExternalRequestCounter = new ExtrapolatingTimeDecayingEventCounter(1000, rateLimitingInterval, dis);
  121. Core.logger.log(this, "Read acceptedExternalRequestCounter: "+acceptedExternalRequestCounter, Logger.MINOR);
  122. globalQuotaAverager = new TimeDecayingRunningAverage(1000, rateLimitingInterval, 0, Double.MAX_VALUE, dis);
  123. Core.logger.log(this, "Read globalQuotaAverager: "+globalQuotaAverager, Logger.MINOR);
  124. sentRequestCounter = new ExtrapolatingTimeDecayingEventCounter(1000, rateLimitingInterval, dis);
  125. Core.logger.log(this, "Read sentRequestCounter: "+sentRequestCounter, Logger.MINOR);
  126. }
  127. protected void preload() {
  128. // All will be initted to null
  129. }
  130. public String getCheckpointName() {
  131. return "Rate limiting data save process";
  132. }
  133. }
  134. public static int maxConnDefault = 200;
  135. public static int maxFileDefault = 256;
  136. public static boolean isWin95;
  137. public static boolean isWin9X;
  138. public static boolean isWinCE;
  139. public static boolean isOSX;
  140. public static String sysName = System.getProperty("os.name");
  141. private static final NumberFormat nfp;
  142. private static final NumberFormat nf1;
  143. private static final NumberFormat nf03;
  144. private static final NumberFormat nf3;
  145. static float overloadHighDefault = 1.25f;
  146. private static final String ARG_BOOLEAN = "<true|false>";
  147. static {
  148. nfp = NumberFormat.getPercentInstance();
  149. nfp.setMinimumFractionDigits(0);
  150. nfp.setMaximumFractionDigits(1);
  151. nf1 = NumberFormat.getInstance();
  152. nf1.setMaximumFractionDigits(1);
  153. nf1.setMinimumFractionDigits(1);
  154. nf1.setGroupingUsed(false);
  155. nf03 = NumberFormat.getInstance();
  156. nf03.setMinimumFractionDigits(0);
  157. nf03.setMaximumFractionDigits(3);
  158. nf03.setGroupingUsed(false);
  159. nf3 = NumberFormat.getInstance();
  160. nf3.setMaximumFractionDigits(3);
  161. nf3.setMinimumFractionDigits(3);
  162. nf3.setGroupingUsed(false);
  163. // System.err.println("Node.java static initialization start.");
  164. Config config = getConfig();
  165. // internal defaults
  166. config.addOption("rtMaxRefs", 1, 50, 1300); // 50 refs/node
  167. // rtMaxNodes later down because of OS detection
  168. config.addOption("maxRoutingSteps", 1, 200, 1303); // to 10 refs
  169. config.addOption("messageStoreSize", 1, 10000, 1350);
  170. // 10000 live chains
  171. config.addOption("failureTableSize", 1, 20000, 1360);
  172. // 20000 failed keys - uses ~ 2.7MB
  173. config.addOption("failureTableItems", 1, 100000, 1361);
  174. config.addOption("failureTableTime", 1, 1800000l, 1362); // 30 min
  175. config.addOption("newNodePollInterval", 1, 30000, 1363); // 30 seconds
  176. // ARK stuff
  177. config.addOption("minCP", 1, 0.01F, 1370);
  178. config.addOption("failuresLookupARK", 1, 10, 1371);
  179. config.addOption("minARKDelay", 1, 900 * 1000, 1372);
  180. config.addOption("maxARKThreadsFraction", 1, 0.1F, 1373);
  181. // network defaults
  182. config.addOption("routeConnectTimeout", 1, 10000, 1400); // 10 sec
  183. config.addOption("maxHopsToLive", 1, 20, 1410);
  184. config.addOption("probIncHopsSinceReset", 1, 0.95F, 1411);
  185. config.addOption("cacheProbPerHop", 1, 0.8F, 1412);
  186. config.addOption("minStoreFullPCache", 1, 0.9F, 1413);
  187. config.addOption("minRTFullPRef", 1, 0.3F, 1414);
  188. config.addOption("minRTNodesPRef", 1, 0.8F, 1415);
  189. config.addOption("maxLog2DataSize", 1, 20, 1416);
  190. // network resource limiting options
  191. config.addOption("bandwidthLimit", 1, 0, 1200);
  192. config.addOption("inputBandwidthLimit", 1, 0, 1201); // disabled
  193. config.addOption("outputBandwidthLimit", 1, 12 * 1024, 1202);
  194. // 12kB/sec, so it doesn't ruin 128kbps uplink which is unfortunately
  195. // way too common
  196. config.addOption("averageBandwidthLimit", 1, 0, 1203); // disabled
  197. config.addOption("averageInputBandwidthLimit", 1, 0, 1204); // disabled
  198. config.addOption("averageOutputBandwidthLimit", 1, 0, 1205);
  199. // disabled
  200. sysName = sysName.toLowerCase();
  201. if (sysName.startsWith("windows")) {
  202. maxFileDefault = 1024;
  203. // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccore98/html/_crt__setmaxstdio.asp
  204. if (sysName.startsWith("windows ce"))
  205. isWinCE = true;
  206. else if (sysName.startsWith("windows 95")) {
  207. isWin95 = true;
  208. isWin9X = true;
  209. maxConnDefault = 20;
  210. } else if (
  211. sysName.startsWith("windows 98")
  212. || (sysName.startsWith("windows")
  213. && (sysName.indexOf("millennium") != -1))
  214. || (sysName.startsWith("windows me"))) {
  215. // Detected Windows 9X
  216. maxConnDefault = 60;
  217. isWin9X = true;
  218. } else {
  219. isWin9X = false;
  220. }
  221. }
  222. if (sysName.startsWith("mac os x")) {
  223. maxConnDefault = 128;
  224. maxFileDefault = 64;
  225. isOSX = true;
  226. } else
  227. isOSX = false;
  228. if (sysName.startsWith("netware")) {
  229. // supports unlimited FDs
  230. maxFileDefault = 0;
  231. }
  232. config.addOption("rtMaxNodes", 1, 100, 1301);
  233. config.addOption("doEstimatorSmoothing", 1, true, 1304);
  234. config.addOption("useFastEstimators", 1, true, 1305);
  235. config.addOption("maxNodeConnections", 1, maxConnDefault, 1224);
  236. config.addOption("maxOpenConnectionsNewbieFraction", 1, 0.2, 1225);
  237. config.addOption("maxNodeFilesOpen", 1, maxFileDefault, 1226);
  238. config.addOption("maxNegotiations", 1, 50, 1227);
  239. // I'm deprecating these in favor of
  240. config.addOption("maxConnectionsPerMinute", 1, 60, 1228);
  241. config.addOption("maxConnectionsMinute", 1, 60000, 1229);
  242. // these, and increasing the default quite a bit while at it.
  243. config.addOption("maxRequestsPerInterval", 1, -1, 1230);
  244. config.addOption("maxRequestsInterval", 1, 60000, 1231);
  245. // data store settings
  246. config.addOption("storeType", 1, "freenet", 999);
  247. // "freenet" or "native"
  248. config.addOption("nodeFile", 1, "", 1000); // node_<port>
  249. config.addOption("storeFile", 1, "", 1001); // store_<port>
  250. config.addOption("storeSize", 1, 256L*1024L*1024L, 1010, true);
  251. // 256MB is reasonable, strictish minimum would be 101MB ((1MB chunk +
  252. // header) * 100)
  253. config.addOption("storeBlockSize", 1, 4096, 1011);
  254. config.addOption("storeMaxTempFraction", 1, (1F / 3F), 1012);
  255. config.addOption("storeCipherName", 1, "Twofish", 1020);
  256. // Twofish cipher
  257. config.addOption("storeCipherWidth", 1, 128, 1021); // 128 bits
  258. config.addOption("routingDir", 1, "", 1022);
  259. config.addOption("useDSIndex", 1, true, 1023);
  260. // network settings
  261. config.addOption("ipAddress", 1, "", 100); // autodetected if not set
  262. config.addOption(new RandomPortOption("listenPort", 1, 101));
  263. // random choice
  264. config.addOption("clientPort", 1, 8481, 110);
  265. config.addOption("fcpHosts", 1, "", 112); // loopback only
  266. config.addOption("transient", 1, false, 300);
  267. config.setDeprecated("transient", true);
  268. config.addOption("seedFile", 1, "seednodes.ref", 320);
  269. config.addOption("routingTableImpl", 1, "ng", 330);
  270. // logging options
  271. config.addOption("logLevel", 1, "normal", 1250);
  272. config.addOption("logFile", 1, "freenet.log", 1251);
  273. config.addOption("logFormat", 1, "d (c, t, p): m", 1252);
  274. config.addOption("logDate", 1, "", 1253); // locale default
  275. config.addOption("logLevelDetail", 1, "", 1254);
  276. config.addOption("logMaxLinesCached", 1, 10000, 1255);
  277. config.addOption("logMaxBytesCached", 1, 10L*1024L*1024L, 1256);
  278. config.addOption("logRotate", 1, false, 1257);
  279. config.addOption("logRotateUseNativeGzip", 1, false, 1258);
  280. config.addOption("logRotateInterval", 1, "hour", 1259);
  281. config.addOption("logOverwrite", 1, true, 1260);
  282. // diagnostics options
  283. config.addOption("diagnosticsPath", 1, "stats", 501);
  284. // announcement options
  285. config.addOption("doAnnounce", 1, true, 310);
  286. config.addOption("announcementHTL", 1, 15, 1501);
  287. config.addOption("announcementAttempts", 1, 3, 1502);
  288. config.addOption("announcementPollInterval", 1, 900 * 1000, 1513);
  289. // Set to 0 - with bidi, new nodes should announce immediately
  290. config.addOption("announcementFirstDelay", 1, /*2 * 3600 * 1000*/0, 1514);
  291. config.addOption("announcementThreads", 1, 3, 1515);
  292. config.addOption("announcementUseRT", 1, true, 1516);
  293. config.addOption("initialRequests", 1, 10, 1520);
  294. config.addOption("initialRequestHTL", 1, 25, 1521);
  295. // Load balancing
  296. config.addOption("doLoadBalance", 1, true, 1550);
  297. // wierd stuff
  298. config.addOption("localIsOK", 1, false, 1551);
  299. config.addOption("dontLimitClients", 1, false, 1552);
  300. config.addOption("limitAll", 1, false, 1553);
  301. config.addOption("mainportURIOverride", 1, "", 1554);
  302. config.addOption("distributionURIOverride", 1, "", 1555);
  303. config.addOption("aggressiveGC", 1, 0, 1556);
  304. config.addOption("configUpdateInterval", 1, 5, 1557);
  305. config.addOption("seednodesUpdateInterval", 1, 5, 1558);
  306. config.addOption("defaultToSimpleUIMode", 1, true, 1559);
  307. config.addOption("defaultToOCMHTMLPeerHandlerMode", 1, false, 1560);
  308. config.addOption("ipDetectorInterval", 1, 10, 1561);
  309. // FCP admin options
  310. config.addOption("adminPassword", 1, String.class, 200);
  311. config.addOption("adminPeer", 1, String.class, 201);
  312. config.addOption("logOutputBytes", 1, true, 3540);
  313. config.addOption("logInputBytes", 1, true, 3541);
  314. // Logging, overload, triage
  315. config.addOption("logInboundContacts", 1, false, 3500);
  316. config.addOption("logOutboundContacts", 1, false, 3510);
  317. config.addOption("logInboundRequests", 1, false, 3520);
  318. config.addOption("logOutboundRequests", 1, false, 3530);
  319. config.addOption("logInboundInsertRequestDist", 1, false, 3541);
  320. config.addOption("logSuccessfulInsertRequestDist", 1, false, 3546);
  321. config.addOption("doRequestTriageByDelay", 1, true, 3250);
  322. config.addOption("doRequestTriageBySendTime", 1, true, 3251);
  323. config.addOption("overloadLow", 1, 1.0f, 3252);
  324. config.addOption("overloadHigh", 1, overloadHighDefault, 3253);
  325. config.addOption("threadConnectCutoff", 1, 1.5F, 3254);
  326. config.addOption("requestDelayCutoff", 1, 1000, 3255);
  327. config.addOption("successfulDelayCutoff", 1, 2000, 3256);
  328. config.addOption("requestSendTimeCutoff", 1, 500, 3257);
  329. config.addOption("successfulSendTimeCutoff", 1, 1000, 3258);
  330. config.addOption("doOutLimitCutoff", 1, false, 3259);
  331. config.addOption("outLimitCutoff", 1, 0.8F, 3260);
  332. config.addOption("doOutLimitConnectCutoff", 1, true, 3261);
  333. config.addOption("outLimitConnectCutoff", 1, 2.0F, 3262);
  334. config.addOption("lowLevelBWLimitFudgeFactor", 1, 3F / 4F, 3263);
  335. config.addOption("doReserveOutputBandwidthForSuccess", 1, false, 3264);
  336. // Give high-level a chance - if low level is too aggressive, high level
  337. // won't be effective
  338. config.addOption("lowLevelBWLimitMultiplier", 1, 1.4F, 3265);
  339. config.addOption("doLowLevelOutputLimiting", 1, true, 3266);
  340. config.addOption("doLowLevelInputLimiting", 1, true, 3267);
  341. // Commented out because of limited use and potential political
  342. // problems i.e. not cross platform
  343. config.addOption("doCPULoad",1,false,3264);
  344. config.addOption("sendingQueueLength", 1, 256, 3266);
  345. config.addOption("sendingQueueBytes", 1, 1492 * 8, 3267);
  346. config.addOption("requestIntervalDefault", 1, 1000, 3268);
  347. config.addOption("requestIntervalQRFactor", 1, 1.05, 3269);
  348. // WatchMe options.
  349. config.addOption("watchme", 1, false, 3541);
  350. config.addOption("watchmeRetries", 1, 3, 3542);
  351. // LoadStats options.
  352. config.addOption("defaultResetProbability", 1, 0.05, 3557);
  353. config.addOption("lsMaxTableSize", 1, 100, 3558);
  354. config.addOption("lsAcceptRatioSamples", 1, 500, 3559);
  355. config.addOption("lsHalfLifeHours", 1, 1.2, 3560);
  356. // Forward Error Correction (FEC) options
  357. config.addOption("FECTempDir", 1, "", 3600);
  358. config.addOption("FECInstanceCacheSize", 1, 1, 3610);
  359. config.addOption("FECMaxConcurrentCodecs", 1, 1, 3612);
  360. // Default FEC encoder and decoder implementations.
  361. config.addOption("FEC.Encoders.0.class", 1, "OnionFECEncoder", 3620);
  362. config.addOption("FEC.Decoders.0.class", 1, "OnionFECDecoder", 3630);
  363. // Default temp dir for FEC and fproxy if theirs aren't specified
  364. config.addOption("tempDir", 1, "", 3640);
  365. config.addOption("tempInStore", 1, false, 3641);
  366. config.addOption("publicNode", 1, false, 3650);
  367. // Allow HTTP inserts?
  368. config.addOption("httpInserts", 1, true, 3651);
  369. // Allow FCP inserts?
  370. config.addOption("fcpInserts", 1, true, 3652);
  371. // UI template set
  372. config.addOption("UITemplateSet", 1, "aqua", 3653);
  373. // Bundled client stuff
  374. config.addOption(
  375. "filterPassThroughMimeTypes",
  376. 1,
  377. "text/plain,image/jpeg,image/gif,image/png",
  378. 4000);
  379. // Mainport
  380. config.addOption(
  381. "mainport.class",
  382. 1,
  383. "freenet.interfaces.servlet.MultipleHttpServletContainer",
  384. 4100);
  385. config.addOption("mainport.port", 1, 8888, 4101);
  386. config.addOption("mainport.allowedHosts", 1, "127.0.0.0/8", 4102);
  387. config.addOption("mainport.bindAddress", 1, "", 4103);
  388. config.addOption("mainport.params.servlet.1.uri", 1, "/", 4110);
  389. config.addOption("mainport.params.servlet.1.method", 1, "GET", 4111);
  390. config.addOption(
  391. "mainport.params.servlet.1.class",
  392. 1,
  393. "freenet.client.http.FproxyServlet",
  394. 4112);
  395. config.addOption(
  396. "mainport.params.servlet.1.name",
  397. 1,
  398. "Freenet HTTP proxy (fproxy)",
  399. 4113);
  400. config.addOption(
  401. "mainport.params.servlet.1.params.requestHtl",
  402. 1,
  403. 15,
  404. 4114);
  405. config.addOption(
  406. "mainport.params.servlet.1.params.passThroughMimeTypes",
  407. 1,
  408. "",
  409. 4115);
  410. config.addOption(
  411. "mainport.params.servlet.1.params.filter",
  412. 1,
  413. true,
  414. 4116);
  415. config.addOption(
  416. "mainport.params.servlet.1.params.filterParanoidStringCheck",
  417. 1,
  418. false,
  419. 4117);
  420. config.addOption(
  421. "mainport.params.servlet.1.params.maxForceKeys",
  422. 1,
  423. 100,
  424. 4118);
  425. config.addOption(
  426. "mainport.params.servlet.1.params.doSendRobots",
  427. 1,
  428. true,
  429. 4119);
  430. config.addOption(
  431. "mainport.params.servlet.1.params.noCache",
  432. 1,
  433. false,
  434. 4119);
  435. config.addOption(
  436. "mainport.params.servlet.1.params.dontWarnOperaUsers",
  437. 1,
  438. false,
  439. 4119);
  440. config.addOption(
  441. "mainport.params.servlet.2.uri",
  442. 1,
  443. "/servlet/nodeinfo/",
  444. 4120);
  445. config.addOption("mainport.params.servlet.2.method", 1, "GET", 4121);
  446. config.addOption(
  447. "mainport.params.servlet.2.class",
  448. 1,
  449. "freenet.node.http.NodeInfoServlet",
  450. 4122);
  451. config.addOption(
  452. "mainport.params.servlet.2.name",
  453. 1,
  454. "Web Interface",
  455. 4123);
  456. // default bookmarks. Bookmarks start at 6000 so they come last in the config file
  457. config.addOption("mainport.params.servlet.2.bookmarks.count", 1, -1, 6000);
  458. config.addOption("mainport.params.servlet.2.bookmarks.0.key", 1, "SSK@qe3ZRJg1Nv1XErADrz7ZYjhDidUPAgM/nubile/11//", 6100);
  459. config.addOption("mainport.params.servlet.2.bookmarks.0.title", 1, "Nubile", 6101);
  460. config.addOption("mainport.params.servlet.2.bookmarks.0.activelinkFile", 1, "nubile.png", 6102);
  461. config.addOption("mainport.params.servlet.2.bookmarks.0.description", 1,
  462. "Freesite aimed at beginners. Learn basic methods of retrieving and inserting data from and into freenet. " +
  463. "Unfortunately some of the specifics are slightly outdated.", 6103);
  464. config.addOption("mainport.params.servlet.2.bookmarks.1.key", 1, "SSK@a7SLJXxcl2eT967cHE5~mzQaYTkPAgM/newtofn/7//", 6130);
  465. config.addOption("mainport.params.servlet.2.bookmarks.1.title", 1, "New to Freenet?", 6131);
  466. config.addOption("mainport.params.servlet.2.bookmarks.1.activelinkFile", 1, "newtofn.jpg", 6132);
  467. config.addOption("mainport.params.servlet.2.bookmarks.1.description", 1,
  468. "Another freesite aimed at beginners, with emphasis on Windows users connecting via modem.", 6133);
  469. config.addOption("mainport.params.servlet.2.bookmarks.2.key", 1, "SSK@y~-NCd~il6RMxOe9jjf~VR7mSYwPAgM,ds52dBUTmr8fSHePn1Sn4g/OneMore//", 6140);
  470. config.addOption("mainport.params.servlet.2.bookmarks.2.title", 1, "One More Time", 6141);
  471. config.addOption("mainport.params.servlet.2.bookmarks.2.activelinkFile", 1, "activelink.gif", 6142);
  472. config.addOption("mainport.params.servlet.2.bookmarks.2.description", 1,
  473. "A freesite indexing other freesites. The index is categorized, with one page per category.", 6143);
  474. config.addOption("mainport.params.servlet.2.bookmarks.3.key", 1, "SSK@pHWN3FglLQOoBleE3pQ3EX3PLFoPAgM,xgvJe~4roO7d3lT~4QPIzA/atwocentindex//", 6150);
  475. config.addOption("mainport.params.servlet.2.bookmarks.3.title", 1, "A Two Cent Index", 6151);
  476. config.addOption("mainport.params.servlet.2.bookmarks.3.activelinkFile", 1, "activelink.jpg", 6152);
  477. config.addOption("mainport.params.servlet.2.bookmarks.3.description", 1, "A freesite index with narrower inclusion criteria.", 6153);
  478. config.addOption("mainport.params.servlet.2.bookmarks.4.key", 1, "SSK@rgFrfo~dAesFgV5vylYVNvNGXO0PAgM,wo3T~oLnVbWq-vuD2Kr86Q/frost/19//", 6160);
  479. config.addOption("mainport.params.servlet.2.bookmarks.4.title", 1, "Frost", 6161);
  480. config.addOption("mainport.params.servlet.2.bookmarks.4.activelinkFile", 1, "activelink.png", 6162);
  481. config.addOption("mainport.params.servlet.2.bookmarks.4.description", 1, "Bulletin board and filesharing software.", 6163);
  482. config.addOption("mainport.params.servlet.2.bookmarks.5.key", 1, "SSK@TEx6TiaPeszpV4AFw3ToutDb49EPAgM/mytwocents/59//", 6200);
  483. config.addOption("mainport.params.servlet.2.bookmarks.5.title", 1, "My Two Cents Worth", 6201);
  484. config.addOption("mainport.params.servlet.2.bookmarks.5.activelinkFile", 1, "activelink.jpg", 6202);
  485. config.addOption("mainport.params.servlet.2.bookmarks.5.description", 1,
  486. "A flog (freenet blog) about \"my 2cents worth on just about any subject\", according to the author.", 6203);
  487. // end bookmarks
  488. config.addOption(
  489. "mainport.params.servlet.3.uri",
  490. 1,
  491. "/servlet/images/",
  492. 4130);
  493. config.addOption("mainport.params.servlet.3.method", 1, "GET", 4131);
  494. config.addOption(
  495. "mainport.params.servlet.3.class",
  496. 1,
  497. "freenet.client.http.ImageServlet",
  498. 4132);
  499. config.addOption(
  500. "mainport.params.servlet.3.name",
  501. 1,
  502. "Server Images",
  503. 4133);
  504. config.addOption(
  505. "mainport.params.servlet.4.uri",
  506. 1,
  507. "/servlet/Insert",
  508. 4140);
  509. config.addOption("mainport.params.servlet.4.method", 1, "BOTH", 4141);
  510. config.addOption(
  511. "mainport.params.servlet.4.class",
  512. 1,
  513. "freenet.client.http.InsertServlet",
  514. 4142);
  515. config.addOption(
  516. "mainport.params.servlet.4.name",
  517. 1,
  518. "Insert Proxy Status",
  519. 4143);
  520. config.addOption(
  521. "mainport.params.servlet.4.params.insertHtl",
  522. 1,
  523. 20,
  524. 4144);
  525. config.addOption(
  526. "mainport.params.servlet.4.params.sfInsertThreads",
  527. 1,
  528. 30,
  529. 4145);
  530. config.addOption(
  531. "mainport.params.servlet.4.params.sfInsertRetries",
  532. 1,
  533. 3,
  534. 4146);
  535. config.addOption(
  536. "mainport.params.servlet.4.params.sfRefreshIntervalSecs",
  537. 1,
  538. 15,
  539. 4147);
  540. config.addOption("mainport.params.servlet.6.uri", 1, "/", 4190);
  541. config.addOption("mainport.params.servlet.6.method", 1, "POST", 4191);
  542. config.addOption(
  543. "mainport.params.servlet.6.class",
  544. 1,
  545. "freenet.client.http.InsertServlet",
  546. 4192);
  547. config.addOption(
  548. "mainport.params.servlet.6.name",
  549. 1,
  550. "Insert Proxy",
  551. 4193);
  552. config.addOption(
  553. "mainport.params.servlet.6.params.insertHtl",
  554. 1,
  555. 20,
  556. 4194);
  557. config.addOption(
  558. "mainport.params.servlet.6.params.sfInsertThreads",
  559. 1,
  560. 20,
  561. 4195);
  562. config.addOption(
  563. "mainport.params.servlet.6.params.sfInsertRetries",
  564. 1,
  565. 3,
  566. 4196);
  567. config.addOption(
  568. "mainport.params.servlet.6.params.sfRefreshIntervalSecs",
  569. 1,
  570. 15,
  571. 4197);
  572. config.addOption(
  573. "mainport.params.servlet.5.uri",
  574. 1,
  575. "/servlet/nodestatus/",
  576. 4150);
  577. config.addOption("mainport.params.servlet.5.method", 1, "BOTH", 4151);
  578. config.addOption(
  579. "mainport.params.servlet.5.class",
  580. 1,
  581. "freenet.client.http.NodeStatusServlet",
  582. 4152);
  583. config.addOption(
  584. "mainport.params.servlet.5.name",
  585. 1,
  586. "Node Status",
  587. 4153);
  588. config.addOption(
  589. "mainport.params.servlet.7.uri",
  590. 1,
  591. "/servlet/SFRequest/",
  592. 4160);
  593. config.addOption("mainport.params.servlet.7.method", 1, "BOTH", 4161);
  594. config.addOption(
  595. "mainport.params.servlet.7.class",
  596. 1,
  597. "freenet.client.http.SplitFileRequestServlet",
  598. 4162);
  599. config.addOption(
  600. "mainport.params.servlet.7.name",
  601. 1,
  602. "SplitFile Download Servlet (alpha!)",
  603. 4163);
  604. config.addOption(
  605. "mainport.params.servlet.7.params.requestHtl",
  606. 1,
  607. 20,
  608. 4164);
  609. config.addOption(
  610. "mainport.params.servlet.7.params.sfBlockRequestHtl",
  611. 1,
  612. 0,
  613. 4165);
  614. config.addOption(
  615. "mainport.params.servlet.7.params.sfRequestRetries",
  616. 1,
  617. 4,
  618. 4166);
  619. // Safer to go straight from 0 to 20
  620. config.addOption(
  621. "mainport.params.servlet.7.params.sfRetryHtlIncrement",
  622. 1,
  623. 20,
  624. 4167);
  625. config.addOption(
  626. "mainport.params.servlet.7.params.sfRequestThreads",
  627. 1,
  628. 30,
  629. 4168);
  630. config.addOption(
  631. "mainport.params.servlet.7.params.sfDoParanoidChecks",
  632. 1,
  633. true,
  634. 4169);
  635. config.addOption(
  636. "mainport.params.servlet.7.params.sfRefreshIntervalSecs",
  637. 1,
  638. 15,
  639. 4170);
  640. config.addOption(
  641. "mainport.params.servlet.7.params.sfForceSave",
  642. 1,
  643. false,
  644. 4171);
  645. config.addOption(
  646. "mainport.params.servlet.7.params.sfSkipDS",
  647. 1,
  648. false,
  649. 4172);
  650. config.addOption(
  651. "mainport.params.servlet.7.params.sfUseUI",
  652. 1,
  653. true,
  654. 4173);
  655. config.addOption(
  656. "mainport.params.servlet.7.params.sfRunFilter",
  657. 1,
  658. true,
  659. 4174);
  660. config.addOption(
  661. "mainport.params.servlet.7.params.sfRandomSegs",
  662. 1,
  663. true,
  664. 4175);
  665. config.addOption(
  666. "mainport.params.servlet.7.params.sfFilterParanoidStringCheck",
  667. 1,
  668. false,
  669. 4176);
  670. config.addOption(
  671. "mainport.params.servlet.7.params.sfHealHtl",
  672. 1,
  673. 20,
  674. 4177);
  675. config.addOption(
  676. "mainport.params.servlet.7.params.sfHealPercentage",
  677. 1,
  678. 100,
  679. 4178);
  680. config.addOption(
  681. "mainport.params.servlet.7.params.sfForceSave",
  682. 1,
  683. true,
  684. 4179);
  685. config.addOption(
  686. "mainport.params.servlet.7.params.maxRetries",
  687. 1,
  688. 50,
  689. 4179);
  690. String downloadDir;
  691. try {
  692. downloadDir =
  693. System.getProperty("user.home")
  694. + File.separator
  695. + "freenet-downloads";
  696. } catch (Throwable e) {
  697. downloadDir = "";
  698. }
  699. config.addOption(
  700. "mainport.params.servlet.7.params.sfDefaultSaveDir",
  701. 1,
  702. downloadDir,
  703. 4180);
  704. config.addOption(
  705. "mainport.params.servlet.7.params.sfDefaultWriteToDisk",
  706. 1,
  707. downloadDir.length()!=0,
  708. 4181);
  709. config.addOption(
  710. "mainport.params.servlet.7.params.sfDisableWriteToDisk",
  711. 1,
  712. false,
  713. 4182);
  714. config.addOption(
  715. "mainport.params.servlet.8.uri",
  716. 1,
  717. "/servlet/stream/",
  718. 4190);
  719. config.addOption("mainport.params.servlet.8.method", 1, "GET", 4191);
  720. config.addOption(
  721. "mainport.params.servlet.8.class",
  722. 1,
  723. "freenet.client.http.StreamServlet",
  724. 4192);
  725. config.addOption(
  726. "mainport.params.servlet.8.name",
  727. 1,
  728. "Freenet Streaming Servlet",
  729. 4193);
  730. config.addOption(
  731. "mainport.params.servlet.9.uri",
  732. 1,
  733. "/servlet/streamInsert/",
  734. 5101);
  735. config.addOption("mainport.params.servlet.9.method", 1, "GET", 5102);
  736. config.addOption(
  737. "mainport.params.servlet.9.class",
  738. 1,
  739. "freenet.client.http.StreamInsertServlet",
  740. 5103);
  741. config.addOption(
  742. "mainport.params.servlet.9.name",
  743. 1,
  744. "Freenet Stream Insert Servlet",
  745. 5104);
  746. config.setExpert("mainport.params.servlet.8.uri", true);
  747. config.setExpert("mainport.params.servlet.8.method", true);
  748. config.setExpert("mainport.params.servlet.8.class", true);
  749. config.setExpert("mainport.params.servlet.8.name", true);
  750. config.setExpert("mainport.params.servlet.9.uri", true);
  751. config.setExpert("mainport.params.servlet.9.method", true);
  752. config.setExpert("mainport.params.servlet.9.class", true);
  753. config.setExpert("mainport.params.servlet.9.name", true);
  754. config.addOption(
  755. "mainport.params.defaultServlet.uri",
  756. 1,
  757. "/default",
  758. 4190);
  759. config.addOption(
  760. "mainport.params.defaultServlet.method",
  761. 1,
  762. "GET",
  763. 4191);
  764. config.addOption(
  765. "mainport.params.defaultServlet.class",
  766. 1,
  767. "freenet.client.http.RedirectServlet",
  768. 4192);
  769. config.addOption(
  770. "mainport.params.defaultServlet.name",
  771. 1,
  772. "Web Interface Redirect",
  773. 4193);
  774. config.addOption(
  775. "mainport.params.defaultServlet.params.targetURL",
  776. 1,
  777. "/servlet/nodeinfo/",
  778. 4194);
  779. // RouteConnectTimeout
  780. config.setExpert("routeConnectTimeout", true);
  781. config.argDesc("routeConnectTimeout", "<millis>");
  782. config.shortDesc(
  783. "routeConnectTimeout",
  784. "wait on new connection when routing.");
  785. config.longDesc(
  786. "routeConnectTimeout",
  787. "The time to wait for connections to be established and ",
  788. "authenticated before passing by a node while routing out.",
  789. "Connections that are by passed are still finished and cached ",
  790. "for the time set by <connectionTimeout> (in milliseconds).");
  791. // maxHopsToLive
  792. config.setExpert("maxHopsToLive", true);
  793. config.argDesc("maxHopsToLive", "<integer>");
  794. config.shortDesc("maxHopsToLive", "max HTL allowed on routed requests");
  795. config.longDesc(
  796. "maxHopsToLive",
  797. "When forwarding a request, the node will reduce the HTL to this value",
  798. "if it is found to be in excess.");
  799. // maxLog2DataSize
  800. config.setExpert("maxLog2DataSize", true);
  801. config.argDesc("maxLog2DataSize", "<integer>");
  802. config.shortDesc(
  803. "maxLog2DataSize",
  804. "maximum file data size (log to base 2)");
  805. config.longDesc(
  806. "maxLog2DataSize",
  807. "The logarithm to the base 2 of the maximum file data+metadata size ",
  808. "that the node will accept. 20 means 1 megabyte, which is reasonable.");
  809. // probIncHopsSinceReset
  810. config.setExpert("probIncHopsSinceReset", true);
  811. config.argDesc("probIncHopsSinceReset", "<number between 0 and 1>");
  812. config.shortDesc(
  813. "probIncHopsSinceReset",
  814. "Probability of incrementing hopsSinceReset when forwarding a request. Leave this alone.");
  815. // cacheProbPerHop
  816. config.setExpert("cacheProbPerHop", true);
  817. config.argDesc("cacheProbPerHop", "<number between 0 and 1>");
  818. config.longDesc(
  819. "cacheProbPerHop",
  820. "Number which is raised to the power of the number of hops since a datasource reset to determine the cache probability. Set lower for better routing, higher for more caching/redundancy. The default is equivalent to approximately 5 nodes caching a file in a request.");
  821. // minStoreFullPCache
  822. config.setExpert("minStoreFullPCache", true);
  823. config.argDesc("minStoreFullPCache", "<number between 0 and 1>");
  824. config.longDesc(
  825. "minStoreFullPCache",
  826. "Minimum proportion of the datastore that must be filled before probabilistic caching kicks in.");
  827. // minRTFullPRef
  828. config.setExpert("minRTFullPRef", true);
  829. config.argDesc("minRTFullPRef", "<number between 0 and 1>");
  830. config.longDesc(
  831. "minRTFullPRef",
  832. "Minimium proportion of the routing table (classic mode) that must be filled before probabilistic ",
  833. "referencing kicks in.");
  834. // minRTNodesPRef
  835. config.setExpert("minRTNodesPRef", true);
  836. config.argDesc("minRTNodesPRef", "<number between 0 and 1>");
  837. config.longDesc(
  838. "minRTNodesPRef",
  839. "Minimum proportion of the routing table nodes that must be filled and not backed off before ",
  840. "probabilistic referencing kicks in");
  841. // nodeFile
  842. config.setExpert("nodeFile", true);
  843. config.argDesc("nodeFile", "<file>");
  844. config.shortDesc("nodeFile", "location of node's key file");
  845. config.longDesc(
  846. "nodeFile",
  847. "The path to the file containing the node's private key, DSA group,",
  848. "cipher key, etc. Defaults to node in the current directory.");
  849. // storeFile
  850. config.setExpert("storeFile", true);
  851. config.argDesc("storeFile", "<file>[,..]");
  852. config.shortDesc(
  853. "storeFile",
  854. "location of data store directory - do not put anywhere with existing files");
  855. config.longDesc(
  856. "storeFile",
  857. "The path to the single directory containing the data "
  858. + "store. The total maximum size of the files in the "
  859. + "directory is given by <storeSize>. It will create new "
  860. + "files and directories in this dir, and DELETE OLD ONES. "
  861. + "Defaults to store in the current directory.");
  862. // storeSize
  863. config.argDesc(
  864. "storeSize",
  865. "<bytes - can use kKmMgGtTpPeE multipliers>");
  866. config.shortDesc("storeSize", "size of the data store file(s)");
  867. config.longDesc(
  868. "storeSize",
  869. "The byte size of the data store directory.",
  870. "The maximum sized file that will be cached is 1/100th of",
  871. "this value. We recommend the default 256MB, to cache the largest common",
  872. "file size on freenet, 1MB plus some headers, with plenty of elbowroom, but",
  873. "any size about 101MB should be adequate (a 1MB chunk is not exactly 1MB...).",
  874. "Note that if you increase settings such as maximumThreads, you may need to",
  875. "use a larger store.");
  876. // storeType
  877. config.setExpert("storeType", true);
  878. config.argDesc("storeType", "<string>");
  879. config.shortDesc(
  880. "storeType",
  881. "datastore implementation: \"native\" (new), \"monolithic\" (old, gets the DSB), \"freenet\" (autodetect, prefer native), or \"convert\" (convert old to new)");
  882. config.longDesc(
  883. "storeType",
  884. "Datastore implementation. Put \"native\" (without the quotes) if you want the new native filesystem datastore, which stores the files in a directory. Put \"convert\" to convert from an old monolithic store to a native store. Note that convert uses lots of disk space while doing the conversion (approximately twice the datastore size), and the resulting store may be (temporarily) slightly larger than the old one due to block size mismatch (this will be fixed as soon as the node tries to add a file to the store).");
  885. // storeBlockSize
  886. config.setExpert("storeBlockSize", true);
  887. config.argDesc("storeBlockSize", "<bytes>");
  888. config.shortDesc(
  889. "storeBlockSize",
  890. "Size of filesystem accounting blocks for storeType=native");
  891. config.longDesc(
  892. "storeBlockSize",
  893. "Size of blocks in the underlying filesystem for purposes of calculating space usage when storeType=native.");
  894. // storeMaxTempFraction
  895. config.setExpert("storeMaxTempFraction", true);
  896. config.argDesc("storeMaxTempFraction", "<number between 0 and 1>");
  897. config.shortDesc(
  898. "storeMaxTempFraction",
  899. "Maximum fraction of the datastore to use for temp files (assuming the temp dir is not overridden)");
  900. // storeCipherName
  901. config.setExpert("storeCipherName", true);
  902. config.argDesc("storeCipherName", "<string>");
  903. config.shortDesc(
  904. "storeCipherName",
  905. "name of symmetric cipher algorithm");
  906. config.longDesc("storeCipherName", "deprecated");
  907. // storeCipherWidth
  908. config.setExpert("storeCipherWidth", true);
  909. config.argDesc("storeCipherWidth", "<integer>");
  910. config.shortDesc("storeCipherWidth", "bit-width of cipher key");
  911. config.longDesc("storeCipherWidth", "deprecated");
  912. // routingDir
  913. config.setExpert("routingDir", true);
  914. config.argDesc("routingDir", "<directory>");
  915. config.shortDesc(
  916. "routingDir",
  917. "The directory in which to store the routing table files. Defaults to parent dir of storeDir");
  918. // useDSIndex
  919. config.setExpert("useDSIndex", true);
  920. config.argDesc("useDSIndex", "true|false");
  921. config.shortDesc("useDSIndex", "Use a datastore index file");
  922. config.longDesc(
  923. "useDSIndex",
  924. "Use a datastore index file. Shorter startup time, but we have to run checkpoints, which lock the datastore, causing a hiccup");
  925. // rtMaxRefs
  926. config.setExpert("rtMaxRefs", true);
  927. config.argDesc("rtMaxRefs", "<integer>");
  928. config.shortDesc("rtMaxRefs", "max no. of refs per node");
  929. config.longDesc(
  930. "rtMaxRefs",
  931. "The number of references allowed per node in the routing table.",
  932. "This should not be set too high.");
  933. // rtMaxNodes
  934. config.setExpert("rtMaxNodes", true);
  935. config.argDesc("rtMaxNodes", "<integer>");
  936. config.shortDesc("rtMaxNodes", "max no. unique nodes in routing table");
  937. config.longDesc(
  938. "rtMaxNodes",
  939. "The number of unique nodes that can be contained in the routing table. Note that the node will try to keep an idle connection open to each of these, so don't set it to more than half the value of maxNodeConnections. Too big or too small will result in inefficient or completely useless routing, or slow specialization; the default 50 is reasonable (if you see another default, it's because you have an OS with too few connections).");
  940. // doEstimatorSmoothing
  941. config.setExpert("doEstimatorSmoothing", true);
  942. config.argDesc("doEstimatorSmoothing", ARG_BOOLEAN);
  943. config.longDesc("doEstimatorSmoothing",
  944. "Whether to use adjacent buckets to estimate the value of a given bucket in a KeyspaceEstimator when it has no reports. "+
  945. "If you don't understand what I just said you should probably leave it alone!");
  946. // useFastEstimators
  947. config.setExpert("useFastEstimators", true);
  948. config.argDesc("useFastEstimators", ARG_BOOLEAN);
  949. config.longDesc("useFastEstimators",
  950. "Whether to use doubles (floating point, 53 bit mantissa, implemented in hardware on most systems) instead of BigIntegers (full 160 bits, slow) in NGRouting estimators.");
  951. // minCP
  952. config.setExpert("minCP", true);
  953. config.argDesc("minCP", "<number between 0 and 1>");
  954. config.shortDesc(
  955. "minCP",
  956. "Lower bound on Contact Probability of nodes in the Routing Table");
  957. // failuresLookupARK
  958. config.setExpert("failuresLookupARK", true);
  959. config.argDesc("failuresLookupARK", "<integer>");
  960. config.shortDesc(
  961. "failuresLookupARK",
  962. "Number of consecutive failures required to trigger an ARK lookup");
  963. // minARKDelay
  964. config.setExpert("minARKDelay", true);
  965. config.argDesc("minARKDelay", "<milliseconds>");
  966. config.shortDesc(
  967. "minARKDelay",
  968. "Minimum time that a node in the routing table must have been uncontactable for before we can trigger an ARK lookup");
  969. // maxARKThreadsFraction
  970. config.setExpert("maxARKThreadsFraction", true);
  971. config.argDesc("maxARKThreadsFraction", "<number between 0 and 1>");
  972. config.shortDesc(
  973. "maxARKThreadsFraction",
  974. "Maximum fraction of maximumThreads to use for ARK lookups");
  975. // maxRoutingSteps
  976. config.setExpert("maxRoutingSteps", true);
  977. config.argDesc("maxRoutingSteps", "<integer>");
  978. config.shortDesc(
  979. "maxRoutingSteps",
  980. "max no. node refs used per routing attempt.");
  981. config.longDesc(
  982. "maxRoutingSteps",
  983. "The maximum number or node refs that will be used to route a request before RNFing. ",
  984. "-1 means 1/10th the routing table size.");
  985. // messageStoreSize
  986. config.setExpert("messageStoreSize", true);
  987. config.argDesc("messageStoreSize", "<integer>");
  988. config.shortDesc(
  989. "messageStoreSize",
  990. "max no. of simultaneous requests.");
  991. config.longDesc(
  992. "messageStoreSize",
  993. "The number of outstanding message replies the node will",
  994. "wait for before it starts to abandon them.");
  995. // failureTableSize
  996. config.setExpert("failureTableSize", true);
  997. config.argDesc("failureTableSize", "<integer>");
  998. config.shortDesc("failureTableSize", "max. no. cached failed keys.");
  999. config.longDesc(
  1000. "failureTableSize",
  1001. "The number keys that failed to be retrieved the node should key track of.");
  1002. //failureTableItems
  1003. config.setExpert("failureTableItems", true);
  1004. // failureTableTime
  1005. config.setExpert("failureTableTime", true);
  1006. config.argDesc("failureTableTime", "<milliseconds>");
  1007. config.shortDesc("failureTableTime", "max. time to fail keys.");
  1008. config.longDesc(
  1009. "failureTableTime",
  1010. "The amount of time to keep keys cache keys that could not be found and",
  1011. "automatically fail requests for them.");
  1012. // newNodePollInterval
  1013. config.setExpert("newNodePollInterval", true);
  1014. config.argDesc("newNodePollInterval", "<milliseconds>");
  1015. config.shortDesc(
  1016. "newNodePollInterval",
  1017. "interval between polling new nodes");
  1018. config.longDesc(
  1019. "newNodePollInterval",
  1020. "The node will send a request for a random "
  1021. + "recently requested key to the node in the routing table with the fewest accesses, "
  1022. + "every N milliseconds. Please enter N.");
  1023. // bandwidthLimit
  1024. config.setExpert("bandwidthLimit", true); // because deprecated
  1025. config.argDesc("bandwidthLimit", "<bytes/sec>");
  1026. config.shortDesc("bandwidthLimit", "DEPRECATED");
  1027. config.setDeprecated("bandwidthLimit", true);
  1028. config.longDesc(
  1029. "bandwidthLimit",
  1030. "The maximum number of bytes per second to transmit, totaled between",
  1031. "incoming and outgoing connections. Ignored if either inputBandwidthLimit",
  1032. "or outputBandwidthLimit is nonzero. DEPRECATED - please set inputBandwidthLimit and outputBandwidthLimit directly. Difficult to implement for NIO and not widely used.");
  1033. // inputBandwidthLimit
  1034. config.argDesc("inputBandwidthLimit", "<bytes/sec>");
  1035. config.shortDesc("inputBandwidthLimit", "incoming bandwidth limit");
  1036. config.longDesc(
  1037. "inputBandwidthLimit",
  1038. "If nonzero, specifies an independent limit for incoming data only, in bytes",
  1039. "per second. A 512kbps broadband (DSL or cable) connection is 64kB/sec, but",
  1040. "you may want to use other things than Freenet on it. However, Freenet's",
  1041. "background usage should be close to the output limit most of the time. ",
  1042. "You may want to set this and then set doLowLevelInputLimiting=false, in ",
  1043. "order to have more accurate pending-transfers load. You SHOULD do this if ",
  1044. "your connection has more outbound than inbound bandwidth.");
  1045. // outputBandwidthLimit
  1046. config.argDesc("outputBandwidthLimit", "<bytes/sec>");
  1047. config.shortDesc(
  1048. "outputBandwidthLimit",
  1049. "if enabled, outgoing bandwidth limit");
  1050. config.longDesc(
  1051. "outputBandwidthLimit",
  1052. "If nonzero, specifies an independent limit for outgoing data only, in bytes",
  1053. "per second. Not entirely accurate. If you need exact limiting, do it at the",
  1054. "OS level. A typical broadband connection has either a 128kbps or a 256kbps",
  1055. "uplink, this equates to 16kB/sec and 32kB/sec respectively. You will need to",
  1056. "keep some bandwidth back for other apps and for downloads (yes, downloading",
  1057. "uses a small amount of upload bandwidth). We suggest therefore limits of",
  1058. "12000 for a 128kbps upload connection, or 24000 for a 256kbps upload",
  1059. "connection. Most broadband connections have far more download bandwidth than",
  1060. "upload bandwidth... just because you have 1Mbps download, does not mean you",
  1061. "have 1Mbps upload; if you do not know what your connection's upload speed is,",
  1062. "use one of the above options.");
  1063. // averageBandwidthLimit
  1064. config.setExpert("averageBandwidthLimit", true);
  1065. config.argDesc("averageBandwidthLimit", "<bytes/sec>");
  1066. config.setDeprecated("averageBandwidthLimit", true);
  1067. config.shortDesc("averageBandwidthLimit", "DEPRECATED");
  1068. config.longDesc(
  1069. "averageBandwidthLimit",
  1070. "The maximum number of bytes per second to transmit (averaged over a week),",
  1071. "totaled between incoming and outgoing connections. Error to define it if",
  1072. "any of (average)inputBandwidthLimit or (average)outputBandwidthLimit is",
  1073. "nonzero. DEPRECATED - please set inputBandwidthLimit and outputBandwidthLimit directly. Difficult to implement for NIO and not widely used.");
  1074. // averageInputBandwidthLimit
  1075. config.argDesc("averageInputBandwidthLimit", "<bytes/sec>");
  1076. config.shortDesc(
  1077. "averageInputBandwidthLimit",
  1078. "incoming bandwidth limit averaged over a week");
  1079. config.longDesc(
  1080. "averageInputBandwidthLimit",
  1081. "If nonzero, specifies an independent limit for incoming data only (averaged",
  1082. "over a week). (overrides averageBandwidthLimit if nonzero)");
  1083. // averageOutputBandwidthLimit
  1084. config.argDesc("averageOutputBandwidthLimit", "<bytes/sec>");
  1085. config.shortDesc(
  1086. "averageOutputBandwidthLimit",
  1087. "outgoing bandwidth limit averaged over a week");
  1088. config.longDesc(
  1089. "averageOutputBandwidthLimit",
  1090. "If nonzero, specifies an independent limit for outgoing data only (averaged",
  1091. "over a week). (overrides bandwidthLimit if nonzero)");
  1092. // maxConnectionsPerMinute
  1093. config.setExpert("maxConnectionsPerMinute", true);
  1094. config.argDesc("maxConnectionsPerMinute", "<int>");
  1095. config.shortDesc(
  1096. "maxConnectionsPerMinute",
  1097. "Max no. of connections in one minute.");
  1098. config.longDesc(
  1099. "maxConnectionsPerMinute",
  1100. "The maximum number of outgoing connections established in a one minute period. "
  1101. + "Deprecated and ignored.");
  1102. // maxConnectionsMinute
  1103. config.setExpert("maxConnectionsMinute", true);
  1104. config.argDesc("maxConnectionsMinute", "<milliseconds>");
  1105. config.shortDesc(
  1106. "maxConnectionsMinute",
  1107. "Length of a minute in milliseconds for purposes of maxConnectionsPerMinute");
  1108. config.longDesc(
  1109. "maxConnectionsMinute",
  1110. "The length of the period over which there must be at most maxConnectionsPerMinute connections. Deprecated"
  1111. + " and ignored.");
  1112. // maxRequestsPerInterval
  1113. config.setExpert("maxRequestsPerInterval", true);
  1114. config.argDesc("maxRequestsPerInterval", "<int>");
  1115. config.shortDesc(
  1116. "maxRequestsPerInterval",
  1117. "Max no. of outgoing requests per maxRequestsInterval.");
  1118. config.longDesc(
  1119. "maxRequestsPerInterval",
  1120. "The maximum number of outgoing requests per maxRequestsInterval. -1 = disable.");
  1121. // maxRequestsInterval
  1122. config.setExpert("maxRequestsInterval", true);
  1123. config.argDesc("maxRequestsInterval", "<milliseconds>");
  1124. config.shortDesc(
  1125. "maxRequestsInterval",
  1126. "Length of the period in milliseconds for purposes of maxRequestsPerInterval");
  1127. config.longDesc(
  1128. "maxRequestsInterval",
  1129. "The length of the period over which there must be at most maxRequestsPerInterval connections.");
  1130. // maxNodeConnections
  1131. config.setExpert("maxNodeConnections", true);
  1132. config.argDesc("maxNodeConnections", "<positive integer>");
  1133. config.shortDesc(
  1134. "maxNodeConnections",
  1135. "Max. no. of connections to other "
  1136. + "nodes. Deprecated unless maximumThreads=0.");
  1137. config.longDesc(
  1138. "maxNodeConnections",
  1139. "The maximum number of incoming and outgoing connections to "
  1140. + "allow at the same time. Forced to 0.4*maximumThreads unless"
  1141. + " maximumThreads = 0.");
  1142. // maxOpenConnectionsNewbieFraction
  1143. config.setExpert("maxOpenConnectionsNewbieFraction", true);
  1144. config.argDesc ("maxOpenConnectionsNewbieFraction", "<number between 0.0 and 1.0>");
  1145. config.shortDesc("maxOpenConnectionsNewbieFraction",
  1146. "Proportion of open connections limit that may be newbie nodes before we start "+
  1147. "rejecting new connections (unless there are free slots)");
  1148. // maxNodeFilesOpen
  1149. config.setExpert("maxNodeFilesOpen", true);
  1150. config.argDesc("maxNodeFilesOpen", "<positive integer>");
  1151. config.longDesc(
  1152. "maxNodeFilesOpen",
  1153. "Maximum number of file descriptors used by the node for files. Not including connections.");
  1154. // maxNegotiations
  1155. config.setExpert("maxNegotiations", true);
  1156. config.argDesc ("maxNegotiations", "<positive integer>");
  1157. config.shortDesc("maxNegotiations", "maximum number of simultaneous connection opens initiated by the node");
  1158. // ipAddress
  1159. config.setExpert("ipAddress", true);
  1160. config.argDesc("ipAddress", "xxx.xxx.xxx.xxx");
  1161. config.shortDesc(
  1162. "ipAddress",
  1163. "your IP as seen by the public internet (normally this is autoconfigured)");
  1164. config.longDesc(
  1165. "ipAddress",
  1166. "The IP address of this node as seen by the "
  1167. + "public Internet. You only need to override this "
  1168. + "if it cannot be autodetected, for example if you "
  1169. + "have a NAT (a.k.a. IP Masquerading) "
  1170. + "firewall/router, in which case you will need "
  1171. + "to set it to the IP address or DNS name of the "
  1172. + "internet-side interface of the router, which "
  1173. + "needs to be static (www.dyndns.org and similar "
  1174. + "services can help here if you have a dynamic IP).");
  1175. // listenPort
  1176. config.argDesc("listenPort", "<port no.>");
  1177. config.shortDesc("listenPort", "incoming FNP port");
  1178. config.longDesc(
  1179. "listenPort",
  1180. "The port to listen for incoming FNP (Freenet Node Protocol) connections on.");
  1181. // clientPort
  1182. config.setExpert("clientPort", true);
  1183. config.argDesc("clientPort", "<port no.>");
  1184. config.shortDesc("clientPort", "incoming FCP port");
  1185. config.longDesc(
  1186. "clientPort",
  1187. "The port to listen for local FCP (Freenet Client Protocol) connections on.");
  1188. // fcpHosts
  1189. config.setExpert("fcpHosts", true);
  1190. config.argDesc("fcpHosts", "<host list>");
  1191. config.shortDesc("fcpHosts", "hosts allowed to connect with FCP");
  1192. config.longDesc(
  1193. "fcpHosts",
  1194. "A comma-separated list of hosts that may connect to the FCP port",
  1195. "(clientPort). If left blank, only the localhost will be allowed."
  1196. + " If you set this, make sure localhost is included in the list or "
  1197. + " access won't be allowed from the local machine. ",
  1198. "May be given as IP addresses or host names.");
  1199. // logLevel
  1200. config.argDesc("logLevel", "<word>");
  1201. config.shortDesc("logLevel", "error, normal, minor, or debug");
  1202. config.longDesc(
  1203. "logLevel",
  1204. "The error reporting threshold, one of:",
  1205. " Error: Errors only",
  1206. " Normal: Report significant events, and errors",
  1207. " Minor: Report minor events, significant events, and errors",
  1208. " Debug: Report everything that can be reported");
  1209. // logLevelDetail
  1210. config.setExpert("logLevelDetail", true);
  1211. config.argDesc(
  1212. "logLevelDetail",
  1213. "<list of class name or package name = level e.g. freenet.node.rt:debug,freenet.support:minor>");
  1214. config.shortDesc(
  1215. "logLevelDetail",
  1216. "Detailed list of parts of freenet we want different logging for");
  1217. // logFile
  1218. config.setExpert("logFile", true);
  1219. config.argDesc("logFile", "<filename>|NO");
  1220. config.shortDesc("logFile", "path to the log file, or NO for STDERR");
  1221. config.longDesc(
  1222. "logFile",
  1223. "The name of the log file (`NO' to log to standard out)");
  1224. // logFormat
  1225. config.setExpert("logFormat", true);
  1226. config.argDesc("logFormat", "<tmpl.>");
  1227. config.shortDesc("logFormat", "template, like d:c:h:t:p:m");
  1228. config.longDesc(
  1229. "logFormat",
  1230. "A template string for log messages. All non-alphabet characters are",
  1231. "reproduced verbatim. Alphabet characters are substituted as follows:",
  1232. "d = date (timestamp), c = class name of the source object,",
  1233. "h = hashcode of the object, t = thread name, p = priority,",
  1234. "m = the actual log message, u = name the local interface");
  1235. // logDate
  1236. config.setExpert("logDate", true);
  1237. config.argDesc("logDate", "<tmpl.>");
  1238. config.shortDesc("logDate", "java style date/time template");
  1239. config.longDesc(
  1240. "logDate",
  1241. "A template for formatting the timestamp in log messages. Defaults to",
  1242. "the locale specific fully specified date format. The template string",
  1243. "is an ordinary Java date/time template - see:",
  1244. "http://java.sun.com/products/jdk/1.1/docs/api/java.text.SimpleDateFormat.html");
  1245. // logMaxLinesCached
  1246. config.setExpert("logMaxLinesCached", true);
  1247. config.argDesc("logMaxLinesCached", "<integer>");
  1248. config.shortDesc(
  1249. "logMaxLinesCached",
  1250. "Maximum number of log lines to cache, anything above this will be discarded to prevent deadlocks and blocking");
  1251. // logMaxBytes
  1252. config.setExpert("logMaxBytesCached", true);
  1253. config.argDesc(
  1254. "logMaxBytesCached",
  1255. "<bytes - can use kKmMgGg multipliers>");
  1256. config.shortDesc(
  1257. "logMaxBytesCached",
  1258. "Maximum number of logged bytes to cache, anything above this will be discarded to prevent deadlocks and blocking");
  1259. // logRotate
  1260. config.setExpert("logRotate", true);
  1261. config.argDesc("logRotate", "<true|false>");
  1262. config.shortDesc(
  1263. "logRotate",
  1264. "Whether to rotate the log files. This is best done inside freenet because restarting Fred is slow and loses open connections.");
  1265. // logRotateUseNativeGzip
  1266. config.setExpert("logRotateUseNativeGzip", true);
  1267. config.argDesc("logRotateUseNativeGzip", "<true|false>");
  1268. config.shortDesc(
  1269. "logRotateUseNativeGzip",
  1270. "Whether to launch a native gzip to compress the old log files.");
  1271. // logRotateInterval
  1272. config.setExpert("logRotateInterval", true);
  1273. config.argDesc("logRotateInterval", "<minute|hour|week|month|year>");
  1274. config.shortDesc(
  1275. "logRotateInterval",
  1276. "Time interval for logfile rotation.");
  1277. // logOverwrite
  1278. config.setExpert("logOverwrite", true);
  1279. config.argDesc("logOverwrite", "<yes|no>");
  1280. config.shortDesc(
  1281. "logOverwrite",
  1282. "Whether to overwrite old log files; otherwise they are appended to.");
  1283. // seedFile
  1284. config.argDesc("seedFile", "<file>");
  1285. config.shortDesc("seedFile", "initial node ref(s), for announcing");
  1286. config.longDesc(
  1287. "seedFile",
  1288. "A file containing one or more node references which will be incorporated",
  1289. "into the node's routing table on startup. A reference is only added if",
  1290. "there is no previously existing reference to that node. When this node",
  1291. "announces, it will announce to the nodes listed in this file.");
  1292. // routingTableImpl
  1293. config.setExpert("routingTableImpl", true);
  1294. config.argDesc("routingTableImpl", "classic or ng");
  1295. config.longDesc(
  1296. "routingTableImpl",
  1297. "Set to ng for the Next Generation Routing implementation, classic for the old Freenet routing algorithm.");
  1298. // doAnnounce
  1299. config.setExpert("doAnnounce", true);
  1300. config.argDesc("doAnnounce", "yes|no");
  1301. config.shortDesc("doAnnounce", "whether to automatically announce");
  1302. config.longDesc(
  1303. "doAnnounce",
  1304. "If this is true, the node will automatically announce to all nodes in",
  1305. "the <seedFile> file, as specified by <announcementDelay>, etc.");
  1306. // announcementPeers
  1307. config.setExpert("announcementHTL", true);
  1308. config.argDesc("announcementHTL", "<integer>");
  1309. config.shortDesc(
  1310. "announcementHTL",
  1311. "no. of nodes announcement goes to");
  1312. config.longDesc(
  1313. "announcementHTL",
  1314. "The number of nodes that each announcement message should be"
  1315. + "sent to.");
  1316. // announcementAttempts
  1317. config.setExpert("announcementAttempts", true);
  1318. config.argDesc("announcementAttempts", "<integer>");
  1319. config.shortDesc(
  1320. "announcementAttempts",
  1321. "number of attempts to announce");
  1322. config.longDesc(
  1323. "announcementAttempts",
  1324. "The number of attempts to make at announcing this node "
  1325. + "in any given attempt for any given node . Zero means "
  1326. + "the node will not announce itself.");
  1327. // announcementPollInterval
  1328. config.setExpert("announcementPollInterval", true);
  1329. config.argDesc("announcementPollInterval", "<milliseconds>");
  1330. config.shortDesc(
  1331. "announcementPollInterval",
  1332. "Interval between polling for inactivity to reannounce");
  1333. config.longDesc(
  1334. "announcementPollInterval",
  1335. "The time between polling for 1 hours no incoming requests to ",
  1336. "force reannouncement.");
  1337. // announcementFirstDelay
  1338. config.setExpert("announcementFirstDelay", true);
  1339. config.argDesc("announcementFirstDelay", "<milliseconds>");
  1340. config.shortDesc(
  1341. "announcementFirstDelay",
  1342. "Delay before announcing on first startup");
  1343. // announcementThreads
  1344. config.setExpert("announcementThreads", true);
  1345. config.argDesc("announcementThreads", "<integer>");
  1346. config.shortDesc(
  1347. "announcementThreads",
  1348. "Number of simultaneous announcement attempts");
  1349. config.longDesc(
  1350. "announcementThreads",
  1351. "The number of simultaneous announcement attempts; when a"
  1352. + "permanent node sees no traffic for a while, or when it"
  1353. + "initially joins the network, it will try to announce to "
  1354. + "this many nodes.");
  1355. // announcementUseRT
  1356. config.setExpert("announcementUseRT", true);
  1357. config.argDesc("announcementUseRT", "yes|no");
  1358. config.shortDesc(
  1359. "announcementUseRT",
  1360. "announce to nodes from routing table?");
  1361. config.longDesc(
  1362. "announcementThreads",
  1363. "If we run out of seed nodes, we can use other nodes from the"
  1364. + "routing table to announce to. However, since the trust level"
  1365. + "of these nodes is unknown, this is not recommended for the"
  1366. + "truly paranoid.");
  1367. // initialRequests
  1368. config.setExpert("initialRequests", true);
  1369. config.argDesc("initialRequests", "<integer>");
  1370. config.shortDesc("initialRequests", "number of initial requests");
  1371. config.longDesc(
  1372. "initialRequests",
  1373. "The number of keys to request from the returned close values",
  1374. "after an Announcement (this is per announcement made).");
  1375. // initialRequestHTL
  1376. config.setExpert("initialRequestHTL", true);
  1377. config.argDesc("initialRequestHTL", "<integer>");
  1378. config.shortDesc("initialRequestHTL", "HopsToLive on initial requests");
  1379. config.longDesc(
  1380. "initialRequestHTL",
  1381. "The hops that initial requests should make.");
  1382. //doLoadBalance
  1383. config.setExpert("doLoadBalance", true);
  1384. config.argDesc("doLoadBalance", "yes|no");
  1385. config.shortDesc("doLoadBalance", "Use load balancing.");
  1386. config.longDesc(
  1387. "doLoadBalance",
  1388. "Whether to emply load balancing algorithms against the ",
  1389. "network.");
  1390. //localIsOK
  1391. config.setExpert("localIsOK", true);
  1392. config.argDesc("localIsOK", "yes|no");
  1393. config.shortDesc(
  1394. "localIsOK",
  1395. "set yes to allow permanent nodes with non-internet-resolvable addresses. Do not use this except in a local testing network.");
  1396. //dontLimitClients
  1397. config.setExpert("dontLimitClients", true);
  1398. config.argDesc("dontLimitClients", "yes|no");
  1399. config.shortDesc(
  1400. "dontLimitClients",
  1401. "set yes to not bandwidth throttle connections to LocalInterfaces i.e. FCP and mainport");
  1402. //limitAll
  1403. config.setExpert("limitAll", true);
  1404. config.argDesc("limitAll", "yes|no");
  1405. config.shortDesc(
  1406. "limitAll",
  1407. "set yes to run the bandwidth limiter over all connections, local, network or internet. Overridden by dontLimitClients.");
  1408. //mainportURIOverride
  1409. config.setExpert("mainportURIOverride", true);
  1410. config.argDesc("mainportURIOverride", "URI");
  1411. config.shortDesc(
  1412. "mainportURIOverride",
  1413. "URI to mainport servlet, e.g. for SSL tunneling");
  1414. //distributionURIOverride
  1415. config.setExpert("distributionURIOverride", true);
  1416. config.argDesc("distributionURIOverride", "URI");
  1417. config.shortDesc(
  1418. "distributionURIOverride",
  1419. "URI to distribution servlet, e.g. for SSL tunneling");
  1420. //aggressiveGC
  1421. config.setExpert("aggressiveGC", true);
  1422. config.argDesc("aggressiveGC", "<seconds>");
  1423. config.shortDesc(
  1424. "aggressiveGC",
  1425. "How often (in seconds) to do aggressive garbage collection. May impact performance but should reduce working set. Set to 0 to disable.");
  1426. //configUpdateInterval
  1427. config.setExpert("configUpdateInterval", true);
  1428. config.argDesc("configUpdateInterval", "<minutes>");
  1429. config.shortDesc(
  1430. "configUpdateInterval",
  1431. "How often (in minutes) to check for config file changes. Set to 0 to disable.");
  1432. // seednodesUpdateInterval
  1433. config.setExpert("seednodesUpdateInterval", true);
  1434. config.argDesc("seednodesUpdateInterval", "<minutes>");
  1435. config.shortDesc(
  1436. "seednodesUpdateInterval",
  1437. "How often (in minutes) to check for seednodes file changes. Set to 0 to disable.");
  1438. // adminPassword
  1439. config.setExpert("adminPassword", true);
  1440. config.argDesc("adminPassword", "<string>");
  1441. config.shortDesc(
  1442. "adminPassword",
  1443. "allows remote admin using password.");
  1444. config.longDesc(
  1445. "adminPassword",
  1446. "If this is set then users that can provide the password can",
  1447. "can have administrative access. It is recommended that",
  1448. "you do not use this without also using adminPeer below",
  1449. "in which case both are required.");
  1450. // adminPeer
  1451. config.setExpert("adminPeer", true);
  1452. config.argDesc("adminPeer", "<Identity FieldSet>");
  1453. config.shortDesc("adminPeer", "allows remote admin using PKI");
  1454. config.longDesc(
  1455. "adminPeer",
  1456. "If this is set, then users that are authenticated owners",
  1457. "of the given PK identity can have administrative access.",
  1458. "If adminPassword is also set both are required.");
  1459. // ipDetectorInterval
  1460. config.setExpert("ipDetectorInterval", true);
  1461. config.argDesc("ipDetectorInterval", "time in seconds or 0");
  1462. config.shortDesc(
  1463. "ipDetectorInterval",
  1464. "Frequency in seconds to run the IP detector. Set to 0 or less to disable.");
  1465. //defaultToSimpleUIMode
  1466. config.setExpert("defaultToSimpleUIMode", true);
  1467. config.shortDesc(
  1468. "defaultToSimpleUIMode",
  1469. "Wheter the web interface should default to simple mode");
  1470. config.longDesc(
  1471. "defaultToSimpleUIMode",
  1472. "The mainport and distribution servlets can display data in one out of two modes, Simple or Advanced. This parameter selects which of the two modes that should be the default mode.");
  1473. //defaultToOCMHTMLPeerHandlerMode
  1474. config.setExpert("defaultToOCMHTMLPeerHandlerMode", true);
  1475. config.shortDesc(
  1476. "defaultToOCMHTMLPeerHandlerMode",
  1477. "Wheter the PeerHandler mode or the Connections mode should be the default mode int the OCM web interface");
  1478. config.longDesc(
  1479. "defaultToOCMHTMLPeerHandlerMode",
  1480. "The OCM web page display data in one out of two modes, ConnectionsMode or PeerMode. This parameter selects which of the two modes that should be the default mode.");
  1481. // diagnosticsPath
  1482. config.setExpert("diagnosticsPath", true);
  1483. config.argDesc("diagnosticsPath", "<dir>");
  1484. config.shortDesc("diagnosticsPath", "directory to save statistics in");
  1485. config.longDesc(
  1486. "diagnosticsPath",
  1487. "The directory in which to save diagnostics data. Defaults to",
  1488. "<storePath>/stats if left blank.");
  1489. /*
  1490. * Class and port of the services are set as installation, because the
  1491. * bad way that these are read requires them to be in the config. That
  1492. * is dumb of course - a config file shouldn't even be necessary.
  1493. * Hopefully I will fix that some day... -oskar
  1494. */
  1495. // NOTE: The default options for fproxy were moved into
  1496. // addDefaultHTTPPortParams. 20020922. --gj.
  1497. //
  1498. // Options for NodeStatusServlet.
  1499. //config.addOption("nodestatus.class", 1,
  1500. // "freenet.client.http.NodeStatusServlet", 2040, true);
  1501. //config.addOption("nodestatus.port", 1, 8889, 2041, true);
  1502. // Options for distribution servlet
  1503. config.addOption(
  1504. "distribution.class",
  1505. 1,
  1506. "freenet.node.http.DistributionServlet",
  1507. 2100);
  1508. config.addOption("distribution.port", 1, 8891, 2101);
  1509. config.addOption("distribution.params.unpacked", 1, ".", 2102);
  1510. config.addOption("distribution.params.distribDir", 1, "", 2105);
  1511. config.addOption("distribution.params.generatorAllowedHosts", 1, "localhost", 2104);
  1512. config.addOption("distribution.allowedHosts", 1, "*", 2103);
  1513. // Turn on fproxy, nodeinfo and NodeStatusServlet by default.
  1514. // mainport is a MultipleHttpServletContainer instance which
  1515. // runs fproxy and nodeinfo on the same port.
  1516. config.addOption("services", 1, "mainport, distribution", 2011);
  1517. config.addOption(
  1518. "mainport.params.servlet.10.uri",
  1519. 1,
  1520. "/servlet/bookmarkmanager",
  1521. 7000);
  1522. config.addOption("mainport.params.servlet.10.method", 1, "GET", 7001);
  1523. config.addOption(
  1524. "mainport.params.servlet.10.class",
  1525. 1,
  1526. "freenet.node.http.BookmarkManagerServlet",
  1527. 7002);
  1528. config.addOption(
  1529. "mainport.params.servlet.10.name",
  1530. 1,
  1531. "Bookmark Manager Servlet",
  1532. 7003);
  1533. config.setExpert("mainport.params.servlet.10.uri", true);
  1534. config.setExpert("mainport.params.servlet.10.method", true);
  1535. config.setExpert("mainport.params.servlet.10.class", true);
  1536. config.setExpert("mainport.params.servlet.10.name", true);
  1537. config.addOption(
  1538. "mainport.params.servlet.11.uri",
  1539. 1,
  1540. "/servlet/coloredpixel",
  1541. 7000);
  1542. config.addOption("mainport.params.servlet.11.method", 1, "GET", 7001);
  1543. config.addOption(
  1544. "mainport.params.servlet.11.class",
  1545. 1,
  1546. "freenet.node.http.ColoredPixelServlet",
  1547. 7002);
  1548. config.addOption(
  1549. "mainport.params.servlet.11.name",
  1550. 1,
  1551. "Colored Pixel Servlet",
  1552. 7003);
  1553. config.setExpert("mainport.params.servlet.11.uri", true);
  1554. config.setExpert("mainport.params.servlet.11.method", true);
  1555. config.setExpert("mainport.params.servlet.11.class", true);
  1556. config.setExpert("mainport.params.servlet.11.name", true);
  1557. // NodeStatusServlet class
  1558. /*
  1559. * config.setExpert ("nodestatus.class", true); config.argDesc
  1560. * ("nodestatus.class", " <class name> "); config.shortDesc
  1561. * ("nodestatus.class", "NodeStatusServlet class"); config.longDesc
  1562. * ("nodestatus.class", "The Java class for the NodeStatusServlet. You
  1563. * shouldn't need to change this."
  1564. */
  1565. // NodeStatusServlet port
  1566. /*
  1567. * config.setExpert ("nodestatus.port", true); config.argDesc
  1568. * ("nodestatus.port", " <port number> "); config.shortDesc
  1569. * ("nodestatus.port", "NodeStatusServlet listen port");
  1570. * config.longDesc ("nodestatus.port", "The port that the node status
  1571. * servlet listens for HTTP requests on."
  1572. */
  1573. config.setExpert("services", true);
  1574. config.argDesc("services", "service_0,service_1,...");
  1575. config.shortDesc("services", "services run at start up");
  1576. config.longDesc(
  1577. "services",
  1578. "A comma delimited list of services that are run when the node starts. "
  1579. + "If you don't know what this means, just accept the defaults.");
  1580. // DistributionServlet class
  1581. config.setExpert("distribution.class", true);
  1582. config.argDesc("distribution.class", "<class name>");
  1583. config.shortDesc("distribution.class", "Distribution servlet class");
  1584. config.longDesc(
  1585. "distribution.class",
  1586. "The Java class of the distribution servlet. You shouldn't need to touch this.");
  1587. config.setExpert("distribution.port", true);
  1588. config.argDesc("distribution.port", "<port number>");
  1589. config.shortDesc(
  1590. "distribution.port",
  1591. "DistributionServlet listen port");
  1592. config.longDesc(
  1593. "distribution.port",
  1594. "The port that the distribution servlet listens for HTTP requests on.");
  1595. // distribution.params
  1596. config.setExpert("distribution.params.unpacked", true);
  1597. config.argDesc("distribution.params.unpacked", "<directory>");
  1598. config.shortDesc(
  1599. "distribution.params.unpacked",
  1600. "Dir where freenet was unpacked");
  1601. config.longDesc(
  1602. "distribution.params.unpacked",
  1603. "A directory containing (some of) the files needed for the Distribution Servlet - for example, a CVS tree, or where the UNIX tarball was unpacked.");
  1604. // distribution.params.distribDir
  1605. config.setExpert("distribution.params.distribDir", true);
  1606. config.argDesc("distribution.params.distribDir", "<directory>");
  1607. config.shortDesc(
  1608. "distribution.params.distribDir",
  1609. "Dir to store redistributibles for the Distribution Servlet");
  1610. config.longDesc(
  1611. "distribution.params.distribDir",
  1612. "Directory used by the node to store redistributibles for the Distribution Servlet - there is rarely any need to override this.");
  1613. // distribution.allowedHosts - whole internet by default
  1614. config.setExpert("distribution.allowedHosts", true);
  1615. config.argDesc("distribution.allowedHosts", "<list of IP addresses>");
  1616. config.shortDesc(
  1617. "distribution.allowedHosts",
  1618. "List of addresses that will be allowed to access distribution pages from the DistributionServlet");
  1619. config.longDesc(
  1620. "distribution.allowedHosts",
  1621. "These IP addresses will be allowed to access the distribution pages generated by the DistributionServlet. Default * means everyone.");
  1622. // distribution.generatorAllowedHosts - localhost only by default
  1623. config.setExpert("distribution.params.generatorAllowedHosts", true);
  1624. config.argDesc("distribution.params.generatorAllowedHosts", "<list of IP addresses>");
  1625. config.shortDesc("distribution.params.generatorAllowedHosts", "Lists of addresses that will be allowed to generate new distribution pages.");
  1626. config.longDesc("distribution.params.generatorAllowedHosts", "Lists of addresses that will be allowed to generate new distribution pages. Default is localhost only.");
  1627. config.setExpert("logOutputBytes", true);
  1628. config.argDesc("logOutputBytes", "true/false");
  1629. config.shortDesc(
  1630. "logOutputBytes",
  1631. "Set true to count non-local TCP bytes sent for diagnostics."
  1632. + " Also used for medium range bandwidth limiting."
  1633. + " Since we for performance reasons don't limit messages"
  1634. + " and connection negotiation, we need to have some other"
  1635. + " way to keep bandwidth under control. This is it. We"
  1636. + " reject all queries if the previous minute's total was"
  1637. + " more than 50% over the limit.");
  1638. config.setExpert("logInputBytes", true);
  1639. config.argDesc ("logInputBytes", "true/false");
  1640. config.shortDesc("logInputBytes", "Set true to count non-local TCP bytes "
  1641. + "received for diagnostics. Also used for part of rate limiting.");
  1642. config.setExpert("watchme", true);
  1643. config.argDesc("watchme", "true/false");
  1644. config.shortDesc(
  1645. "watchme",
  1646. "Debugging only, setting this to true will remove your anonymity!");
  1647. config.setExpert("watchmeRetries", true);
  1648. config.argDesc("watchmeRetries", "<integer>");
  1649. config.shortDesc(
  1650. "watchmeRetries",
  1651. "Number of times watchMe will attempt to initialize");
  1652. // FEC options
  1653. config.setExpert("FECTempDir", true); // unnecessary
  1654. config.argDesc("FECTempDir", "<directory>");
  1655. config.shortDesc(
  1656. "FECTempDir",
  1657. "Dir. used for FEC temp files. You don't need to set this.");
  1658. config.setExpert("FEC.Encoders.0.class", true);
  1659. config.argDesc("FEC.Encoders.0.class", "<class name>");
  1660. config.shortDesc(
  1661. "FEC.Encoders.0.class",
  1662. "Default FEC encoder implementation.");
  1663. config.setExpert("FEC.Decoders.0.class", true);
  1664. config.argDesc("FEC.Decoders.0.class", "<class name>");
  1665. config.shortDesc(
  1666. "FEC.Decoders.0.class",
  1667. "Default FEC decoder implementation.");
  1668. // tempDir
  1669. config.setExpert("tempDir", true);
  1670. config.argDesc("tempDir", "<directory>");
  1671. config.shortDesc(
  1672. "tempDir",
  1673. "Dir used for temporary files, currently for fproxy");
  1674. config.longDesc(
  1675. "tempDir",
  1676. "The directory used for temporary files. Used currently by fproxy and the FCP FEC mechanism, if their individual temp dirs are not set. If this is left unset, it will create a tempdir in the datastore (if the datastore is native).");
  1677. // tempInStore
  1678. config.setExpert("tempInStore", true);
  1679. config.argDesc("tempInStore", "true/false");
  1680. config.shortDesc(
  1681. "tempInStore",
  1682. "Does temp space count as part of the datastore?");
  1683. config.longDesc(
  1684. "tempInStore",
  1685. "If true, temp space counts as part of the datastore for space accounting purposes. This means that freenet will never use significantly more disk space than the configured storeSize (ignoring space used for log files and routing table files), but it also means that if you have a small store you may not be able to download large files.");
  1686. // doRequestTriageByDelay
  1687. config.setExpert("doRequestTriageByDelay", true);
  1688. config.argDesc("doRequestTriageByDelay", "true/false");
  1689. config.shortDesc(
  1690. "doRequestTriageByDelay",
  1691. "triage requests if tickerDelay gets too high");
  1692. config.longDesc(
  1693. "doRequestTriageByDelay",
  1694. "If true, above 2000ms "
  1695. + "tickerDelay (successfulDelayCutoff) all incoming requests "
  1696. + "will be rejected, and above 1000ms, nearly all incoming "
  1697. + "requests will be rejected. This is an attempt to prevent "
  1698. + "the node from totally overwhelming the hardware it runs "
  1699. + "on, and slowing down the network in the process.");
  1700. config.setExpert("doRequestTriageBySendTime", true);
  1701. config.argDesc("doRequestTriageBySendTime", "true/false");
  1702. config.shortDesc(
  1703. "doRequestTriageBySendTime",
  1704. "Triage requests if messageSendTimeRequest > requestSendTimeCutoff");
  1705. config.longDesc(
  1706. "doRequestTriageBySendTime",
  1707. "If true, when messageSendTimeRequest goes above requestSendTimeCutoff, nearly all incoming requests will be rejected. messageSendTime correlates with CPU and bandwidth usage, and if it is too high your node will not do any useful work anyway because the messages will time out.");
  1708. // overloadLow
  1709. config.setExpert("overloadLow", true);
  1710. config.argDesc("overloadLow", "<float between 0 and 1>");
  1711. config.shortDesc(
  1712. "overloadLow",
  1713. "start to selectively reject requests at this load");
  1714. config.longDesc(
  1715. "overloadLow",
  1716. "The node will start to selectively reject requests above this load level.");
  1717. // overloadHigh
  1718. config.setExpert("overloadHigh", true);
  1719. config.argDesc("overloadHigh", "<float between 0 and infinity>");
  1720. config.shortDesc("overloadHigh", "reject all requests above this load");
  1721. config.longDesc(
  1722. "overloadHigh",
  1723. "The node will reject all QueryRequests above this load level. "+
  1724. "Should be over 1.0, because rate limiting will try to keep the load near 100%.");
  1725. // requestDelayCutoff
  1726. config.setExpert("requestDelayCutoff", true);
  1727. config.argDesc("requestDelayCutoff", "<milliseconds>");
  1728. config.shortDesc(
  1729. "requestDelayCutoff",
  1730. "reject queries above this routingTime");
  1731. config.longDesc(
  1732. "requestDelayCutoff",
  1733. "The node will reject nearly all incoming queries when routingTime is over this value.");
  1734. // successfulDelayCutoff
  1735. config.setExpert("successfulDelayCutoff", true);
  1736. config.argDesc("successfulDelayCutoff", "<milliseconds>");
  1737. config.shortDesc(
  1738. "successfulDelayCutoff",
  1739. "if enabled, reject ALL connections when routingTime > cutoff");
  1740. config.longDesc(
  1741. "successfulDelayCutoff",
  1742. "If doRequestTriageByDelay is true, the node will reject ALL connections when routingTime > successfulDelayCutoff.");
  1743. // requestSendTimeCutoff
  1744. config.setExpert("requestSendTimeCutoff", true);
  1745. config.argDesc("requestSendTimeCutoff", "<milliseconds>");
  1746. config.shortDesc(
  1747. "requestSendTimeCutoff",
  1748. "if enabled, reject queries when messageSendTimeRequest > cutoff");
  1749. config.longDesc(
  1750. "requestSendTimeCutoff",
  1751. "If doRequestTriageBySendTime is true, the node will reject queries when messageSendTimeRequest > requestSendTimeCutoff.");
  1752. // successfulSendTimeCutoff
  1753. config.setExpert("successfulSendTimeCutoff", true);
  1754. config.argDesc("successfulSendTimeCutoff", "<integer, per minute>");
  1755. config.shortDesc(
  1756. "successfulSendTimeCutoff",
  1757. "if enabled, reject ALL connections if messageSendTimeRequest > cutoff");
  1758. config.longDesc(
  1759. "successfulSendTimeCutoff",
  1760. "If doRequestTriageBySendTime is true, the node will reject ALL connections if messageSendTimeRequest > successfulSendTimeCutoff");
  1761. // doOutLimitCutoff
  1762. config.setExpert("doOutLimitCutoff", true);
  1763. config.argDesc("doOutLimitCutoff", "<true|false>");
  1764. config.shortDesc(
  1765. "doOutLimitCutoff",
  1766. "enable use of outLimitCutoff value");
  1767. config.longDesc(
  1768. "doOutLimitCutoff",
  1769. "If true, the node will refuse incoming requests according to outLimitCutoff.");
  1770. // outLimitCutoff
  1771. config.setExpert("outLimitCutoff", true);
  1772. config.argDesc("outLimitCutoff", "<floatint point number over 0>");
  1773. config.shortDesc(
  1774. "outLimitCutoff",
  1775. "if enabled, reject queries when outbound bandwidth exceeds outLimitCutoff*outputBandwidthLimit");
  1776. config.longDesc(
  1777. "outLimitCutoff",
  1778. "If the previous minute's outbound transfer limit was exceeded by this factor or more, the node will reject incoming requests.");
  1779. // doOutLimitConnectCutoff
  1780. config.setExpert("doOutLimitConnectCutoff", true);
  1781. config.argDesc("doOutLimitConnectCutoff", "<true|false>");
  1782. config.longDesc(
  1783. "doOutLimitConnectCutoff",
  1784. "Whether to refuse incoming conections when the node's outbound bandwidth limit is exceeded by the factor specified by outLimitConnectCutoff.");
  1785. // outLimitConnectCutoff
  1786. config.setExpert("outLimitConnectCutoff", true);
  1787. config.argDesc(
  1788. "outLimitConnectCutoff",
  1789. "<floating point number over 0>");
  1790. config.longDesc(
  1791. "outLimitConnectCutoff",
  1792. "If the previous minute's outbound transfer limit was exceeded by this factor or more, the node will reject incoming connections.");
  1793. // threadConnectCutoff
  1794. config.setExpert("threadConnectCutoff", true);
  1795. config.argDesc ("threadConnectCutoff",
  1796. "<floating point number over 0>");
  1797. config.shortDesc ("threadConnectCutoff",
  1798. "Fraction of thread limit over which to reject all incoming connections");
  1799. // lowLevelBWLimitFudgeFactor
  1800. config.setExpert("lowLevelBWLimitFudgeFactor", true);
  1801. config.argDesc(
  1802. "lowLevelBWLimitFudgeFactor",
  1803. "<floating point number over 0>");
  1804. config.longDesc(
  1805. "lowLevelBWLimitFudgeFactor",
  1806. "The low level bandwidth limiter is not entirely accurate. It has however been found that it can be made more accurate by multiplying the limit by a fudge factor of around 70%. This may vary from system to system so is a config option. Probably not useful with the new outLimitCutoff option... Leave it alone unless you know what you are doing. Distinct from lowLevelBWLimitMultiplier so that we can change the default even if the latter has been overridden.");
  1807. // doReserveOutputBandwidthForSuccess
  1808. config.setExpert("doReserveOutputBandwidthForSuccess", true);
  1809. config.argDesc("doReserveOutputBandwidthForSuccess", "<true|false>");
  1810. config.longDesc("doReserveOutputBandwidthForSuccess",
  1811. "If set to true, adjust the high level bandwidth limiting to "+
  1812. "underuse our available bandwidth according to the ratio of "+
  1813. "the actual probability of success to the best reasonable "+
  1814. "probability of success (estimated from the nodes in the RT). "+
  1815. "The idea here is that if you limit the number of requests "+
  1816. "this way, then on average the network won't accept too much "+
  1817. "work and end up backing off all over the place. This WILL "+
  1818. "reduce your upstream bandwidth usage, so if you don't like "+
  1819. "that, don't set it.");
  1820. // lowLevelBWLimitMultiplier
  1821. config.setExpert("lowLevelBWLimitMultiplier", true);
  1822. config.argDesc(
  1823. "lowLevelBWLimitMultiplier",
  1824. "<floating point number over 0>");
  1825. config.longDesc(
  1826. "lowLevelBWLimitMultiplier",
  1827. "Freenet has 2 separate bandwidth limiting mechanisms. The low level bandwidth limiter is more accurate, but can cause bad things to happeen and is quite expensive in terms of CPU time, and works by delaying messages, which may not be desirable. So by default limiting is done mainly by the high level limiter (see outLimitCutoff and outLimitConnectCutoff), and the low level limiter is set to a higher value to ensure that the node's usage does not get completely out of control when something unusual happens. Set the factor to multiply the bandwidth limits by before feeding them to the low level limiter here.");
  1828. // doLowLevelOutputLimiting
  1829. config.setExpert("doLowLevelOutputLimiting", true);
  1830. // doLowLevelInputLimiting
  1831. config.setExpert("doLowLevelInputLimiting", true);
  1832. // doCPULoad
  1833. config.setExpert ("doCPULoad", true);
  1834. config.argDesc ("doCPULoad", "<true|false>");
  1835. config.longDesc ("doCPULoad", "Whether to try to use the actual CPU"
  1836. +"usage percentage in the load estimate calculation.");
  1837. // sendingQueueLength
  1838. config.setExpert("sendingQueueLength", true);
  1839. config.argDesc("sendingQueueLength", "<positive integer>");
  1840. config.longDesc(
  1841. "sendingQueueLength",
  1842. "Maximum number of messages queued on a connection before we force opening of a new connection. Note that a value too low will cause lots of connections to be opened; this takes time and bandwidth. Note also that messages are not necessarily sent one at a time; over 10 messages (approximately) can sometimes be packed into a single packet.");
  1843. // sendingQueueBytes
  1844. config.setExpert("sendingQueueBytes", true);
  1845. config.argDesc("sendingQueueBytes", "<bytes>");
  1846. config.longDesc(
  1847. "sendingQueueBytes",
  1848. "Maximum number of bytes queued on a connection before we force opening of a new connection. Note that a value too low will cause lots of connections to be opened; this takes time and bandwidth. Note also that messages are not necessarily sent one at a time; over 10 messages (approximately) can sometimes be packed into a single packet.");
  1849. // requestIntervalDefault
  1850. config.setDeprecated("requestIntervalDefault", true);
  1851. // requestIntervalQRFactor
  1852. config.setDeprecated("requestIntervalQRFactor", true);
  1853. // defaultResetProbability
  1854. config.setExpert("defaultResetProbability", true);
  1855. config.argDesc("defaultResetProbability", "<probability>");
  1856. config.shortDesc(
  1857. "defaultResetProbability",
  1858. "Default probability of resetting the DataSource");
  1859. config.longDesc(
  1860. "defaultResetProbability",
  1861. "The node will have this probability, on average (it varies according to load unless you set doLoadBalance=no), of resetting the datasource. Increase this to get more load, reduce it to get less load.");
  1862. // lsMaxTableSize
  1863. config.setExpert("lsMaxTableSize", true);
  1864. config.argDesc("lsMaxTableSize", "<positive integer>");
  1865. config.shortDesc(
  1866. "lsMaxTableSize",
  1867. "Maximum number of peers to save queries/hour from");
  1868. config.longDesc(
  1869. "lsMaxTableSize",
  1870. "LoadStats: Global queries/hour is calculated from at most this number of peers.");
  1871. // lsAcceptRatioSamples
  1872. config.setExpert("lsAcceptRatioSamples", true);
  1873. config.argDesc("lsAcceptRatioSamples", "<positive integer>");
  1874. config.shortDesc(
  1875. "lsAcceptRatioSamples",
  1876. "Number of query arrival time and accepted/rejected status entries.");
  1877. config.longDesc(
  1878. "lsAcceptRatioSamples",
  1879. "LoadStats: Current proportion of requests being accepted is calculated from the fate of this number of recent requests. The local queries/hour is calculated from the time it took for this number of queries to arrive, averaged at least every time this number of queries is received.");
  1880. // lsHalfLifeHours
  1881. config.setExpert("lsHalfLifeHours", true);
  1882. config.argDesc("lsHalfLifeHours", "<positive real>");
  1883. config.shortDesc(
  1884. "lsHalfLifeHours",
  1885. "Half life in hours of the queries per hour decaying average.");
  1886. config.longDesc(
  1887. "lsHalfLifeHours",
  1888. "Half life in hours of the queries per hour decaying average. Small values permit the value to change rapidly; large values force it to change slowly. Use zero to get prior behavior.");
  1889. // logOutboundContacts
  1890. config.setExpert("logOutboundContacts", true);
  1891. config.argDesc("logOutboundContacts", "true/false");
  1892. config.shortDesc(
  1893. "logOutboundContacts",
  1894. "Set true to enable outbound contact monitoring.");
  1895. // logInboundContacts
  1896. config.setExpert("logInboundContacts", true);
  1897. config.argDesc("logInboundContacts", "true/false");
  1898. config.shortDesc(
  1899. "logInboundContacts",
  1900. "Set true to enable inbound contact monitoring.");
  1901. // logInboundRequests
  1902. config.setExpert("logInboundRequests", true);
  1903. config.argDesc("logInboundRequests", "true/false");
  1904. config.shortDesc(
  1905. "logInboundRequests",
  1906. "Set true to enable per host inbound request monitoring.");
  1907. // logOutboundRequests
  1908. config.setExpert("logOutboundRequests", true);
  1909. config.argDesc("logOutboundRequests", "true/false");
  1910. config.shortDesc(
  1911. "logOutboundRequests",
  1912. "Set true to enable per host outbound request monitoring.");
  1913. // logInboundInsertRequestDist
  1914. config.setExpert("logInboundInsertRequestDist", true);
  1915. config.argDesc("logInboundInsertRequestDist", "true/false");
  1916. config.shortDesc(
  1917. "logInboundInsertRequestDist",
  1918. "Set true to enable logging of inbound InsertRequest key distribution.");
  1919. // logSuccessfulInsertRequestDist
  1920. config.setExpert("logSuccessfulInsertRequestDist", true);
  1921. config.argDesc("logSuccessfulInsertRequestDist", "true/false");
  1922. config.shortDesc(
  1923. "logSuccessfulInsertRequestDist",
  1924. "Set true to enable logging of successful inbound InsertRequests' key distribution.");
  1925. // FECInstanceCacheSize
  1926. config.setExpert("FECInstanceCacheSize", true);
  1927. config.argDesc("FECInstanceCacheSize", "<integer>");
  1928. config.shortDesc(
  1929. "FECInstanceCacheSize",
  1930. "Number of FEC instances to cache. Set to 1 unless you expect more than one simultaneous FEC operation.");
  1931. // FECMaxConcurrentCodecs
  1932. config.setExpert("FECMaxConcurrentCodecs", true);
  1933. config.argDesc("FECMaxConcurrentCodecs", "<integer>");
  1934. config.shortDesc(
  1935. "FECMaxConcurrentCodecs",
  1936. "Number of concurrent FEC encodes/decodes allowed. "
  1937. + "Each codec can use up to 24Mb of memory.");
  1938. // publicNode
  1939. config.setExpert("publicNode", true);
  1940. config.argDesc("publicNode", "true/false");
  1941. config.shortDesc(
  1942. "publicNode",
  1943. "Disables anonymity threatening servlets and infolets on a multi-user machine");
  1944. // httpInserts
  1945. config.setExpert("httpInserts", true);
  1946. config.argDesc("httpInserts", "true/false");
  1947. config.shortDesc(
  1948. "httpInserts",
  1949. "Set false to disable inserts through FProxy.");
  1950. // fcpInserts
  1951. config.setExpert("fcpInserts", true);
  1952. config.argDesc("fcpInserts", "true/false");
  1953. config.shortDesc("fcpInserts", "Set false to disable FCP insertion.");
  1954. // UITemplateSet
  1955. config.setExpert("UITemplateSet", true);
  1956. config.argDesc("UITemplateSet", "name of a template set");
  1957. config.longDesc(
  1958. "UITemplateSet",
  1959. "Template set to use for user interface over HTTP. Default is aqua. Change it if you want to use another one - currently there is just one extra set (simple), but they can be added to src/freenet/node/http/templates/ easily enough");
  1960. // filterPassThroughMimeTypes
  1961. config.setExpert("filterPassThroughMimeTypes", true /* ? */
  1962. );
  1963. config.argDesc(
  1964. "filterPassThroughMimeTypes",
  1965. "comma delimited list of MIME types");
  1966. config.shortDesc(
  1967. "filterPassThroughMimeTypes",
  1968. "safe MIME types that will be passed through to the browser without query or filtering");
  1969. // mainport.class
  1970. config.setExpert("mainport.class", true);
  1971. config.argDesc("mainport.class", "interface class");
  1972. config.shortDesc(
  1973. "mainport.class",
  1974. "Name of the interface class to run the mainport service. Leave it alone.");
  1975. config.longDesc(
  1976. "mainport.class",
  1977. "Name of the interface class to run the mainport service. You do not need to change this.");
  1978. // mainport.port
  1979. config.setExpert("mainport.port", true);
  1980. config.argDesc("mainport.port", "port number");
  1981. config.shortDesc(
  1982. "mainport.port",
  1983. "Port to run the main Freenet HTTP interface on");
  1984. config.longDesc(
  1985. "mainport.port",
  1986. "Port to run the main Freenet HTTP interface on... this is the port that is accessed by your web browser when you are browsing freenet via fproxy, or looking at the various status monitors. This is normally only accessible from localhost, and is different from the public FNP port that other freenet nodes talk to, the FCP port that client programs talk to, and the distribution port that you can run a freenet distribution website on.");
  1987. // mainport.allowedHosts
  1988. config.setExpert("mainport.allowedHosts", true);
  1989. config.argDesc(
  1990. "mainport.allowedHosts",
  1991. "Comma delimited list of IP addresses, netmasks or hostnames");
  1992. config.shortDesc(
  1993. "mainport.allowedHosts",
  1994. "hosts allowed to access main freenet web interface");
  1995. config.longDesc(
  1996. "mainport.allowedHosts",
  1997. "List of IP addresses (for example \"192.168.1.7\"), DNS names (\"erica\" or \"www.nsa.gov\") or netmasks (\"192.168.1.0/24\") of hosts (computers) that should be allowed to access the main web interface of your freenet node. Defaults to localhost (127.0.0.0/8) only.");
  1998. // mainport.bindAddress
  1999. config.setExpert("mainport.bindAddress", true);
  2000. config.argDesc("mainport.bindAddress", "IP address or \"*\"");
  2001. config.shortDesc(
  2002. "mainport.bindAddress",
  2003. "IP address for main freenet web interface to listen on or \"*\"");
  2004. config.longDesc(
  2005. "mainport.bindAddress",
  2006. "IP address of one interface for the main freenet web interface to listen on, or \"*\" to listen on all interfaces. Will be automatically determined from mainport.allowedHosts if not given; leave it alone.");
  2007. // mainport.params.servlet.1.uri
  2008. config.setExpert("mainport.params.servlet.1.uri", true);
  2009. config.argDesc("mainport.params.servlet.1.uri", "path");
  2010. config.shortDesc(
  2011. "mainport.params.servlet.1.uri",
  2012. "Path within mainport for fproxy. Leave this alone");
  2013. // mainport.params.servlet.1.method
  2014. config.setExpert("mainport.params.servlet.1.method", true);
  2015. config.argDesc("mainport.params.servlet.1.method", "HTTP method");
  2016. config.shortDesc(
  2017. "mainport.params.servlet.1.method",
  2018. "HTTP method for fproxy. Leave this alone.");
  2019. // mainport.params.servlet.1.class
  2020. config.setExpert("mainport.params.servlet.1.class", true);
  2021. config.argDesc("mainport.params.servlet.1.class", "servlet class");
  2022. config.shortDesc(
  2023. "mainport.params.servlet.1.class",
  2024. "servlet class to run fproxy. Leave this alone.");
  2025. // mainport.params.servlet.1.name
  2026. config.setExpert("mainport.params.servlet.1.name", true);
  2027. config.argDesc("mainport.params.servlet.1.name", "string");
  2028. config.shortDesc(
  2029. "mainport.params.servlet.1.name",
  2030. "name of first servlet on mainport (normally fproxy - \"Freenet HTTP proxy (fproxy)\"). Leave this alone.)");
  2031. // mainport.params.servlet.1.params.requestHtl
  2032. config.setExpert("mainport.params.servlet.1.params.requestHtl", true);
  2033. config.argDesc(
  2034. "mainport.params.servlet.1.params.requestHtl",
  2035. "integer HTL value between 0 and maxHopsToLive");
  2036. config.shortDesc(
  2037. "mainport.params.servlet.1.params.requestHtl",
  2038. "hops to live of fproxy requests");
  2039. config.longDesc(
  2040. "mainport.params.servlet.1.params.requestHtl",
  2041. "hops to live (HTL) of requests made by fproxy");
  2042. // mainport.params.servlet.1.params.passThroughMimeTypes
  2043. config.setExpert(
  2044. "mainport.params.servlet.1.params.passThroughMimeTypes",
  2045. true);
  2046. config.argDesc(
  2047. "mainport.params.servlet.1.params.passThroughMimeTypes",
  2048. "comma delimited list of MIME types");
  2049. config.shortDesc(
  2050. "mainport.params.servlet.1.params.passThroughMimeTypes",
  2051. "safe MIME types, defaults to filterPassThroughMimeTypes");
  2052. config.longDesc(
  2053. "mainport.params.servlet.1.params.passThroughMimeTypes",
  2054. "MIME types regarded as safe that are passed to the browser without filtering or warning in fproxy. The default is empty (\"\"), which means to use the node global default filterPassThroughMimeTypes");
  2055. // mainport.params.servlet.1.params.filter
  2056. config.setExpert("mainport.params.servlet.1.params.filter", true);
  2057. config.argDesc("mainport.params.servlet.1.params.filter", "true|false");
  2058. config.shortDesc(
  2059. "mainport.params.servlet.1.params.filter",
  2060. "run the anonymity filter on HTML/CSS");
  2061. config.longDesc(
  2062. "mainport.params.servlet.1.params.filter",
  2063. "Whether to run the anonymity filter to remove HTML and CSS tags that might cause your browser to damage your anonymity");
  2064. // mainport.params.servlet.1.params.filterParanoidStringCheck
  2065. config.setExpert(
  2066. "mainport.params.servlet.1.params.filterParanoidStringCheck",
  2067. true);
  2068. config.argDesc(
  2069. "mainport.params.servlet.1.params.filterParanoidStringCheck",
  2070. "true|false");
  2071. config.shortDesc(
  2072. "mainport.params.servlet.1.params.filterParanoidStringCheck",
  2073. "whether to make the anonymity filter really paranoid");
  2074. config.longDesc(
  2075. "mainport.params.servlet.1.params.filterParanoidStringCheck",
  2076. "whether to make the anonymity filter really paranoid; currently this causes strings in CSS to be removed if they contain colons (\":\")");
  2077. // mainport.params.servlet.1.params.maxForceKeys
  2078. config.setExpert("mainport.params.servlet.1.params.maxForceKeys", true);
  2079. config.argDesc(
  2080. "mainport.params.servlet.1.params.maxForceKeys",
  2081. "integer");
  2082. config.shortDesc(
  2083. "mainport.params.servlet.1.params.maxForceKeys",
  2084. "Number of ?force= keys for fproxy to track");
  2085. config.longDesc(
  2086. "mainport.params.servlet.1.params.maxForceKeys",
  2087. "Number of key overrides Fproxy should track... these are the confirmation pages you get when you go to some file that fproxy doesn't know how to handle");
  2088. // mainport.params.servlet.1.params.doSendRobots
  2089. config.setExpert("mainport.params.servlet.1.params.doSendRobots", true);
  2090. config.argDesc(
  2091. "mainport.params.servlet.1.params.doSendRobots",
  2092. "yes|no");
  2093. config.shortDesc(
  2094. "mainport.params.servlet.1.params.doSendRobots",
  2095. "Whether to send /robots.txt to the browser");
  2096. // mainport.params.servlet.1.params.noCache
  2097. config.setExpert("mainport.params.servlet.1.params.noCache", true);
  2098. config.argDesc("mainport.params.servlet.1.params.noCache", "yes|no");
  2099. config.shortDesc(
  2100. "mainport.params.servlet.1.params.noCache",
  2101. "Whether to tell the browser not to cache Freenet content");
  2102. // mainport.params.servlet.1.params.dontWarnOperaUsers
  2103. config.setExpert("mainport.params.servlet.1.params.dontWarnOperaUsers", true);
  2104. config.argDesc ("mainport.params.servlet.1.params.dontWarnOperaUsers", "yes|no");
  2105. config.shortDesc("mainport.params.servlet.1.params.dontWarnOperaUsers",
  2106. "Set true to not warn Opera users about MIME types. READ LONG DESCRIPTION.");
  2107. config.longDesc ("mainport.params.servlet.1.params.dontWarnOperaUsers",
  2108. "Opera and IE suffer from a design flaw that prevent FProxy from protecting ",
  2109. "your anonymity properly. In Opera, it can be turned off. If you are sure you ",
  2110. "have done so (read the warning page for instructions), enable this option to ",
  2111. "eliminate the warning page.");
  2112. // mainport.params.servlet.2.uri
  2113. config.setExpert("mainport.params.servlet.2.uri", true);
  2114. config.argDesc("mainport.params.servlet.2.uri", "path");
  2115. config.shortDesc(
  2116. "mainport.params.servlet.2.uri",
  2117. "Path within mainport for the Node Info Servlet");
  2118. config.longDesc(
  2119. "mainport.params.servlet.2.uri",
  2120. "Path within mainport for the Node Info Servlet - this contains infolets which present pages of information about the node as well as the default front page");
  2121. // mainport.params.servlet.2.method
  2122. config.setExpert("mainport.params.servlet.2.method", true);
  2123. config.argDesc("mainport.params.servlet.2.method", "HTTP method");
  2124. config.shortDesc(
  2125. "mainport.params.servlet.2.method",
  2126. "HTTP method for Node Info Servlet. Leave this alone.");
  2127. // mainport.params.servlet.2.class
  2128. config.setExpert("mainport.params.servlet.2.class", true);
  2129. config.argDesc("mainport.params.servlet.2.class", "servlet class");
  2130. config.shortDesc(
  2131. "mainport.params.servlet.2.class",
  2132. "servlet class to run Node Info Servlet. Leave this alone");
  2133. // mainport.params.servlet.2.name
  2134. config.setExpert("mainport.params.servlet.2.name", true);
  2135. config.argDesc("mainport.params.servlet.2.name", "string");
  2136. config.shortDesc(
  2137. "mainport.params.servlet.2.name",
  2138. "name of (usually) Node Info Servlet. Leave this alone.");
  2139. // default bookmarks
  2140. config.setExpert("mainport.params.servlet.2.bookmarks.count", true);
  2141. config.argDesc(
  2142. "mainport.params.servlet.2.bookmarks.count",
  2143. "Number of bookmarks on fproxy");
  2144. config.shortDesc(
  2145. "mainport.params.servlet.2.bookmarks.count",
  2146. "Number of bookmarks on fproxy, or -1 to include all specified ones");
  2147. config.setExpert("mainport.params.servlet.2.bookmarks.0.key", true);
  2148. config.argDesc(
  2149. "mainport.params.servlet.2.bookmarks.0.key",
  2150. "freenet key");
  2151. config.shortDesc(
  2152. "mainport.params.servlet.2.bookmarks.0.key",
  2153. "The first bookmark for the web proxy");
  2154. config.setExpert("mainport.params.servlet.2.bookmarks.0.title", true);
  2155. config.argDesc("mainport.params.servlet.2.bookmarks.0.title", "string");
  2156. config.shortDesc(
  2157. "mainport.params.servlet.2.bookmarks.0.title",
  2158. "The title for the first bookmark for the web proxy");
  2159. config.setExpert(
  2160. "mainport.params.servlet.2.bookmarks.0.activelinkFile",
  2161. true);
  2162. config.argDesc(
  2163. "mainport.params.servlet.2.bookmarks.0.activelinkFile",
  2164. "string");
  2165. config.shortDesc(
  2166. "mainport.params.servlet.2.bookmarks.0.activelinkFile",
  2167. "The name of the activelink image within the key for the first bookmark");
  2168. config.setExpert(
  2169. "mainport.params.servlet.2.bookmarks.0.description",
  2170. true);
  2171. config.argDesc(
  2172. "mainport.params.servlet.2.bookmarks.0.description",
  2173. "string");
  2174. config.shortDesc(
  2175. "mainport.params.servlet.2.bookmarks.0.description",
  2176. "The description of the first bookmark on the web proxy");
  2177. config.setExpert("mainport.params.servlet.2.bookmarks.1.key", true);
  2178. config.argDesc(
  2179. "mainport.params.servlet.2.bookmarks.1.key",
  2180. "freenet key");
  2181. config.shortDesc(
  2182. "mainport.params.servlet.2.bookmarks.1.key",
  2183. "The second bookmark for the web proxy");
  2184. config.setExpert("mainport.params.servlet.2.bookmarks.1.title", true);
  2185. config.argDesc("mainport.params.servlet.2.bookmarks.1.title", "string");
  2186. config.shortDesc(
  2187. "mainport.params.servlet.2.bookmarks.1.title",
  2188. "The title for the second bookmark for the web proxy");
  2189. config.setExpert(
  2190. "mainport.params.servlet.2.bookmarks.1.activelinkFile",
  2191. true);
  2192. config.argDesc(
  2193. "mainport.params.servlet.2.bookmarks.1.activelinkFile",
  2194. "string");
  2195. config.shortDesc(
  2196. "mainport.params.servlet.2.bookmarks.1.activelinkFile",
  2197. "The name of the activelink image within the key for the second bookmark");
  2198. config.setExpert(
  2199. "mainport.params.servlet.2.bookmarks.1.description",
  2200. true);
  2201. config.argDesc(
  2202. "mainport.params.servlet.2.bookmarks.1.description",
  2203. "string");
  2204. config.shortDesc(
  2205. "mainport.params.servlet.2.bookmarks.1.description",
  2206. "The description of the second bookmark on the web proxy");
  2207. config.setExpert("mainport.params.servlet.2.bookmarks.2.key", true);
  2208. config.argDesc(
  2209. "mainport.params.servlet.2.bookmarks.2.key",
  2210. "freenet key");
  2211. config.shortDesc(
  2212. "mainport.params.servlet.2.bookmarks.2.key",
  2213. "The third bookmark for the web proxy");
  2214. config.setExpert("mainport.params.servlet.2.bookmarks.2.title", true);
  2215. config.argDesc("mainport.params.servlet.2.bookmarks.2.title", "string");
  2216. config.shortDesc(
  2217. "mainport.params.servlet.2.bookmarks.2.title",
  2218. "The title for the third bookmark for the web proxy");
  2219. config.setExpert(
  2220. "mainport.params.servlet.2.bookmarks.2.activelinkFile",
  2221. true);
  2222. config.argDesc(
  2223. "mainport.params.servlet.2.bookmarks.2.activelinkFile",
  2224. "string");
  2225. config.shortDesc(
  2226. "mainport.params.servlet.2.bookmarks.2.activelinkFile",
  2227. "The name of the activelink image within the key for the third bookmark");
  2228. config.setExpert(
  2229. "mainport.params.servlet.2.bookmarks.2.description",
  2230. true);
  2231. config.argDesc(
  2232. "mainport.params.servlet.2.bookmarks.2.description",
  2233. "string");
  2234. config.shortDesc(
  2235. "mainport.params.servlet.2.bookmarks.2.description",
  2236. "The description of the third bookmark on the web proxy");
  2237. // config.setExpert("mainport.params.servlet.2.bookmarks.3.key", true);
  2238. // config.argDesc(
  2239. // "mainport.params.servlet.2.bookmarks.3.key",
  2240. // "freenet key");
  2241. // config.shortDesc(
  2242. // "mainport.params.servlet.2.bookmarks.3.key",
  2243. // "The fourth bookmark for the web proxy");
  2244. // config.setExpert("mainport.params.servlet.2.bookmarks.3.title", true);
  2245. // config.argDesc("mainport.params.servlet.2.bookmarks.3.title", "string");
  2246. // config.shortDesc(
  2247. // "mainport.params.servlet.2.bookmarks.3.title",
  2248. // "The title for the fourth bookmark for the web proxy");
  2249. // config.setExpert(
  2250. // "mainport.params.servlet.2.bookmarks.3.activelinkFile",
  2251. // true);
  2252. // config.argDesc(
  2253. // "mainport.params.servlet.2.bookmarks.3.activelinkFile",
  2254. // "string");
  2255. // config.shortDesc(
  2256. // "mainport.params.servlet.2.bookmarks.3.activelinkFile",
  2257. // "The name of the activelink image within the key for the fourth bookmark");
  2258. // config.setExpert(
  2259. // "mainport.params.servlet.2.bookmarks.3.description",
  2260. // true);
  2261. // config.argDesc(
  2262. // "mainport.params.servlet.2.bookmarks.3.description",
  2263. // "string");
  2264. // config.shortDesc(
  2265. // "mainport.params.servlet.2.bookmarks.3.description",
  2266. // "The description of the fourth bookmark on the web proxy");
  2267. //
  2268. // config.setExpert("mainport.params.servlet.2.bookmarks.4.key", true);
  2269. // config.argDesc(
  2270. // "mainport.params.servlet.2.bookmarks.4.key",
  2271. // "freenet key");
  2272. // config.shortDesc(
  2273. // "mainport.params.servlet.2.bookmarks.4.key",
  2274. // "The fifth bookmark for the web proxy");
  2275. // config.setExpert("mainport.params.servlet.2.bookmarks.4.title", true);
  2276. // config.argDesc("mainport.params.servlet.2.bookmarks.4.title", "string");
  2277. // config.shortDesc(
  2278. // "mainport.params.servlet.2.bookmarks.4.title",
  2279. // "The title for the fifth bookmark for the web proxy");
  2280. // config.setExpert(
  2281. // "mainport.params.servlet.2.bookmarks.4.activelinkFile",
  2282. // true);
  2283. // config.argDesc(
  2284. // "mainport.params.servlet.2.bookmarks.4.activelinkFile",
  2285. // "string");
  2286. // config.shortDesc(
  2287. // "mainport.params.servlet.2.bookmarks.4.activelinkFile",
  2288. // "The name of the activelink image within the key for the fifth bookmark");
  2289. // config.setExpert(
  2290. // "mainport.params.servlet.2.bookmarks.4.description",
  2291. // true);
  2292. // config.argDesc(
  2293. // "mainport.params.servlet.2.bookmarks.4.description",
  2294. // "string");
  2295. // config.shortDesc(
  2296. // "mainport.params.servlet.2.bookmarks.4.description",
  2297. // "The description of the fifth bookmark on the web proxy");
  2298. //
  2299. // mainport.params.servlet.3.uri
  2300. config.setExpert("mainport.params.servlet.3.uri", true);
  2301. config.argDesc("mainport.params.servlet.3.uri", "path");
  2302. config.shortDesc(
  2303. "mainport.params.servlet.3.uri",
  2304. "Path within mainport for the Images Servlet");
  2305. config.longDesc(
  2306. "mainport.params.servlet.3.uri",
  2307. "Path within mainport for the Images - this serves static images needed by fproxy and the Node Info Servlet");
  2308. // mainport.params.servlet.3.method
  2309. config.setExpert("mainport.params.servlet.3.method", true);
  2310. config.argDesc("mainport.params.servlet.3.method", "HTTP method");
  2311. config.shortDesc(
  2312. "mainport.params.servlet.3.method",
  2313. "HTTP method for Images Servlet. Leave this alone.");
  2314. // mainport.params.servlet.3.class
  2315. config.setExpert("mainport.params.servlet.3.class", true);
  2316. config.argDesc("mainport.params.servlet.3.class", "servlet class");
  2317. config.shortDesc(
  2318. "mainport.params.servlet.3.class",
  2319. "servlet class to run Images Servlet. Leave this alone");
  2320. // mainport.params.servlet.3.name
  2321. config.setExpert("mainport.params.servlet.3.name", true);
  2322. config.argDesc("mainport.params.servlet.3.name", "string");
  2323. config.shortDesc(
  2324. "mainport.params.servlet.3.name",
  2325. "name of (usually) Images Servlet. Leave this alone.");
  2326. // mainport.params.servlet.4.uri
  2327. config.setExpert("mainport.params.servlet.4.uri", true);
  2328. config.argDesc("mainport.params.servlet.4.uri", "path");
  2329. config.shortDesc(
  2330. "mainport.params.servlet.4.uri",
  2331. "Path within mainport for the Insert Servlet");
  2332. config.longDesc(
  2333. "mainport.params.servlet.4.uri",
  2334. "Path within mainport for the Insert Servlet - used to insert files into freenet from the web interface");
  2335. // mainport.params.servlet.4.method
  2336. config.setExpert("mainport.params.servlet.4.method", true);
  2337. config.argDesc("mainport.params.servlet.4.method", "HTTP method");
  2338. config.shortDesc(
  2339. "mainport.params.servlet.4.method",
  2340. "HTTP method for Insert "
  2341. + "Servlet (needs BOTH GET for status and PUT for uploads). "
  2342. + "Leave this alone.");
  2343. // mainport.params.servlet.4.class
  2344. config.setExpert("mainport.params.servlet.4.class", true);
  2345. config.argDesc("mainport.params.servlet.4.class", "servlet class");
  2346. config.shortDesc(
  2347. "mainport.params.servlet.4.class",
  2348. "servlet class to run Insert Servlet. Leave this alone");
  2349. // mainport.params.servlet.4.name
  2350. config.setExpert("mainport.params.servlet.4.name", true);
  2351. config.argDesc("mainport.params.servlet.4.name", "string");
  2352. config.shortDesc(
  2353. "mainport.params.servlet.4.name",
  2354. "name of (usually) Insert Servlet. Leave this alone.");
  2355. // mainport.params.servlet.4.params.insertHtl
  2356. config.setExpert("mainport.params.servlet.4.params.insertHtl", true);
  2357. config.argDesc(
  2358. "mainport.params.servlet.4.params.insertHtl",
  2359. "integer between 0 and maxHopsToLive");
  2360. config.shortDesc(
  2361. "mainport.params.servlet.4.params.insertHtl",
  2362. "hops to live (HTL) of inserts");
  2363. config.longDesc(
  2364. "mainport.params.servlet.4.params.insertHtl",
  2365. "Hops-to-Live value (HTL) of inserts through the web interface");
  2366. // mainport.params.servlet.4.params.sfInsertThreads
  2367. config.setExpert(
  2368. "mainport.params.servlet.4.params.sfInsertThreads",
  2369. true);
  2370. config.argDesc(
  2371. "mainport.params.servlet.4.params.sfInsertThreads",
  2372. "integer");
  2373. config.shortDesc(
  2374. "mainport.params.servlet.4.params.sfInsertThreads",
  2375. "threads to use to insert a splitfile");
  2376. config.longDesc(
  2377. "mainport.params.servlet.4.params.sfInsertThreads",
  2378. "Number of threads to allocate to insert a splitfile through the web interface");
  2379. // mainport.params.servlet.4.params.sfInsertRetries
  2380. config.setExpert(
  2381. "mainport.params.servlet.4.params.sfInsertRetries",
  2382. true);
  2383. config.argDesc(
  2384. "mainport.params.servlet.4.params.sfInsertRetries",
  2385. "integer");
  2386. config.shortDesc(
  2387. "mainport.params.servlet.4.params.sfInsertRetries",
  2388. "Number of retries if a block insert fails");
  2389. // mainport.params.servlet.4.params.sfRefreshIntervalSecs
  2390. config.setExpert(
  2391. "mainport.params.servlet.4.params.sfRefreshIntervalSecs",
  2392. true);
  2393. config.argDesc(
  2394. "mainport.params.servlet.4.params.sfRefreshIntervalSecs",
  2395. "<seconds>");
  2396. config.shortDesc(
  2397. "mainport.params.servlet.4.params.sfRefreshIntervalSecs",
  2398. "How frequently to update insert status");
  2399. // mainport.params.servlet.6.uri
  2400. config.setExpert("mainport.params.servlet.6.uri", true);
  2401. config.argDesc("mainport.params.servlet.6.uri", "path");
  2402. config.shortDesc(
  2403. "mainport.params.servlet.6.uri",
  2404. "Path within mainport for the Insert Servlet");
  2405. config.longDesc(
  2406. "mainport.params.servlet.6.uri",
  2407. "Path within mainport for the Insert Servlet - used to insert files into freenet from the web interface");
  2408. // mainport.params.servlet.6.method
  2409. config.setExpert("mainport.params.servlet.6.method", true);
  2410. config.argDesc("mainport.params.servlet.6.method", "HTTP method");
  2411. config.shortDesc(
  2412. "mainport.params.servlet.6.method",
  2413. "HTTP method for Insert Servlet (should be PUT). Leave this alone.");
  2414. // mainport.params.servlet.6.class
  2415. config.setExpert("mainport.params.servlet.6.class", true);
  2416. config.argDesc("mainport.params.servlet.6.class", "servlet class");
  2417. config.shortDesc(
  2418. "mainport.params.servlet.6.class",
  2419. "servlet class to run Insert Servlet. Leave this alone");
  2420. // mainport.params.servlet.6.name
  2421. config.setExpert("mainport.params.servlet.6.name", true);
  2422. config.argDesc("mainport.params.servlet.6.name", "string");
  2423. config.shortDesc(
  2424. "mainport.params.servlet.6.name",
  2425. "name of (usually) Insert Servlet. Leave this alone.");
  2426. // mainport.params.servlet.6.params.insertHtl
  2427. config.setExpert("mainport.params.servlet.6.params.insertHtl", true);
  2428. config.argDesc(
  2429. "mainport.params.servlet.6.params.insertHtl",
  2430. "integer between 0 and maxHopsToLive");
  2431. config.shortDesc(
  2432. "mainport.params.servlet.6.params.insertHtl",
  2433. "hops to live (HTL) of inserts");
  2434. config.longDesc(
  2435. "mainport.params.servlet.6.params.insertHtl",
  2436. "Hops-to-Live value (HTL) of inserts through the web interface");
  2437. // mainport.params.servlet.6.params.sfInsertThreads
  2438. config.setExpert(
  2439. "mainport.params.servlet.6.params.sfInsertThreads",
  2440. true);
  2441. config.argDesc(
  2442. "mainport.params.servlet.6.params.sfInsertThreads",
  2443. "integer");
  2444. config.shortDesc(
  2445. "mainport.params.servlet.6.params.sfInsertThreads",
  2446. "threads to use to insert a splitfile");
  2447. config.longDesc(
  2448. "mainport.params.servlet.6.params.sfInsertThreads",
  2449. "Number of threads to allocate to insert a splitfile through the web interface");
  2450. // mainport.params.servlet.6.params.sfInsertRetries
  2451. config.setExpert(
  2452. "mainport.params.servlet.6.params.sfInsertRetries",
  2453. true);
  2454. config.argDesc(
  2455. "mainport.params.servlet.6.params.sfInsertRetries",
  2456. "integer");
  2457. config.shortDesc(
  2458. "mainport.params.servlet.6.params.sfInsertRetries",
  2459. "Number of retries if a block insert fails");
  2460. // mainport.params.servlet.6.params.sfRefreshIntervalSecs
  2461. config.setExpert(
  2462. "mainport.params.servlet.6.params.sfRefreshIntervalSecs",
  2463. true);
  2464. config.argDesc(
  2465. "mainport.params.servlet.6.params.sfRefreshIntervalSecs",
  2466. "<seconds>");
  2467. config.shortDesc(
  2468. "mainport.params.servlet.6.params.sfRefreshIntervalSecs",
  2469. "How frequently to update insert status");
  2470. // mainport.params.servlet.5.uri
  2471. config.setExpert("mainport.params.servlet.5.uri", true);
  2472. config.argDesc("mainport.params.servlet.5.uri", "path");
  2473. config.shortDesc(
  2474. "mainport.params.servlet.5.uri",
  2475. "Path within mainport for the Node Status Servlet");
  2476. config.longDesc(
  2477. "mainport.params.servlet.5.uri",
  2478. "Path within mainport for the Node Status Servlet - displays detailed information about node status. Disabled if publicNode is on.");
  2479. // mainport.params.servlet.5.method
  2480. config.setExpert("mainport.params.servlet.5.method", true);
  2481. config.argDesc("mainport.params.servlet.5.method", "HTTP method");
  2482. config.shortDesc(
  2483. "mainport.params.servlet.5.method",
  2484. "HTTP method for Node Status Servlet. Leave this alone.");
  2485. // mainport.params.servlet.5.class
  2486. config.setExpert("mainport.params.servlet.5.class", true);
  2487. config.argDesc("mainport.params.servlet.5.class", "servlet class");
  2488. config.shortDesc(
  2489. "mainport.params.servlet.5.class",
  2490. "servlet class to run Node Status Servlet. Leave this alone");
  2491. // mainport.params.servlet.5.name
  2492. config.setExpert("mainport.params.servlet.5.name", true);
  2493. config.argDesc("mainport.params.servlet.5.name", "string");
  2494. config.shortDesc(
  2495. "mainport.params.servlet.5.name",
  2496. "name of (usually) Node Status Servlet. Leave this alone.");
  2497. // mainport.params.servlet.7.uri
  2498. config.setExpert("mainport.params.servlet.7.uri", true);
  2499. config.argDesc("mainport.params.servlet.7.uri", "path");
  2500. config.shortDesc(
  2501. "mainport.params.servlet.7.uri",
  2502. "Path within mainport for the SplitFile Download Servlet");
  2503. config.longDesc(
  2504. "mainport.params.servlet.7.uri",
  2505. "Path within mainport for the SplitFile Download Servlet - used to download large files through the web interface");
  2506. // mainport.params.servlet.7.method
  2507. config.setExpert("mainport.params.servlet.7.method", true);
  2508. config.argDesc("mainport.params.servlet.7.method", "HTTP method");
  2509. config.shortDesc(
  2510. "mainport.params.servlet.7.method",
  2511. "HTTP method for SplitFile Download Servlet. Leave this alone.");
  2512. // mainport.params.servlet.7.class
  2513. config.setExpert("mainport.params.servlet.7.class", true);
  2514. config.argDesc("mainport.params.servlet.7.class", "servlet class");
  2515. config.shortDesc(
  2516. "mainport.params.servlet.7.class",
  2517. "servlet class to run SplitFile Download Servlet. Leave this alone");
  2518. // mainport.params.servlet.7.name
  2519. config.setExpert("mainport.params.servlet.7.name", true);
  2520. config.argDesc("mainport.params.servlet.7.name", "string");
  2521. config.shortDesc(
  2522. "mainport.params.servlet.7.name",
  2523. "name of (usually) SplitFile Download Servlet. Leave this alone.");
  2524. // mainport.params.servlet.7.params.requestHtl
  2525. config.setExpert("mainport.params.servlet.7.params.requestHtl", true);
  2526. config.argDesc(
  2527. "mainport.params.servlet.7.params.requestHtl",
  2528. "integer value between 0 and maxHopsToLive");
  2529. config.shortDesc(
  2530. "mainport.params.servlet.7.params.requestHtl",
  2531. "request HTL getting metadata in splitfile servlet");
  2532. config.longDesc(
  2533. "mainport.params.servlet.7.params.requestHtl",
  2534. "Hops-To-Live of requests for the metadata of the splitfiles downloading splitfiles from the web interface.");
  2535. // mainport.params.servlet.7.params.sfBlockRequestHtl
  2536. config.setExpert(
  2537. "mainport.params.servlet.7.params.sfBlockRequestHtl",
  2538. true);
  2539. config.argDesc(
  2540. "mainport.params.servlet.7.params.sfBlockRequestHtl",
  2541. "integer value between 0 and maxHopsToLive");
  2542. config.shortDesc(
  2543. "mainport.params.servlet.7.params.sfBlockRequestHtl",
  2544. "initial request HTL for blocks in splitfile downloads");
  2545. config.longDesc(
  2546. "mainport.params.servlet.7.params.sfBlockRequestHtl",
  2547. "initial Hops-To-Live (HTL) of requests for blocks downloading splitfiles");
  2548. // mainport.params.servlet.7.params.sfRequestRetries
  2549. config.setExpert(
  2550. "mainport.params.servlet.7.params.sfRequestRetries",
  2551. true);
  2552. config.argDesc(
  2553. "mainport.params.servlet.7.params.sfRequestRetries",
  2554. "positive integer");
  2555. config.shortDesc(
  2556. "mainport.params.servlet.7.params.sfRequestRetries",
  2557. "Number of retries on each block in a splitfile download");
  2558. // mainport.params.servlet.7.params.maxRetries
  2559. config.setExpert(
  2560. "mainport.params.servlet.7.params.maxRetries",
  2561. true);
  2562. config.argDesc(
  2563. "mainport.params.servlet.7.params.maxRetries",
  2564. "positive integer");
  2565. config.shortDesc(
  2566. "mainport.params.servlet.7.params.maxRetries",
  2567. "Maximum number of retries per block for a splitfile");
  2568. // mainport.params.servlet.7.params.sfRetryHtlIncrement
  2569. config.setExpert(
  2570. "mainport.params.servlet.7.params.sfRetryHtlIncrement",
  2571. true);
  2572. config.argDesc(
  2573. "mainport.params.servlet.7.params.sfRetryHtlIncrement",
  2574. "positive integer");
  2575. config.shortDesc(
  2576. "mainport.params.servlet.7.params.sfRetryHtlIncrement",
  2577. "Amount to increase the HTL by on each retry");
  2578. // mainport.params.servlet.7.params.sfRequestThreads
  2579. config.setExpert(
  2580. "mainport.params.servlet.7.params.sfRequestThreads",
  2581. true);
  2582. config.argDesc(
  2583. "mainport.params.servlet.7.params.sfRequestThreads",
  2584. "positive integer");
  2585. config.shortDesc(
  2586. "mainport.params.servlet.7.params.sfRequestThreads",
  2587. "Number of threads to use to download a splitfile via the web interface");
  2588. // mainport.params.servlet.7.params.sfDoParanoidChecks
  2589. config.setExpert(
  2590. "mainport.params.servlet.7.params.sfDoParanoidChecks",
  2591. true);
  2592. config.argDesc(
  2593. "mainport.params.servlet.7.params.sfDoParanoidChecks",
  2594. "true|false");
  2595. config.shortDesc(
  2596. "mainport.params.servlet.7.params.sfDoParanoidChecks",
  2597. "Whether to run paranoid checks on blocks downloaded as part of a splitfile");
  2598. // mainport.params.servlet.7.params.sfRefreshIntervalSecs
  2599. config.setExpert(
  2600. "mainport.params.servlet.7.params.sfRefreshIntervalSecs",
  2601. true);
  2602. config.argDesc(
  2603. "mainport.params.servlet.7.params.sfRefreshIntervalSecs",
  2604. "<seconds>");
  2605. config.shortDesc(
  2606. "mainport.params.servlet.7.params.sfRefreshIntervalSecs",
  2607. "How frequently to update the splitfile user interface while downloading");
  2608. // mainport.params.servlet.7.params.sfForceSave
  2609. config.setExpert("mainport.params.servlet.7.params.sfForceSave", true);
  2610. config.argDesc(
  2611. "mainport.params.servlet.7.params.sfForceSave",
  2612. "true|false");
  2613. config.shortDesc(
  2614. "mainport.params.servlet.7.params.sfForceSave",
  2615. "Whether to (by default) force the browser to save splitfiles to disk");
  2616. // mainport.params.servlet.7.params.sfSkipDS
  2617. config.setExpert("mainport.params.servlet.7.params.sfSkipDS", true);
  2618. config.argDesc(
  2619. "mainport.params.servlet.7.params.sfSkipDS",
  2620. "true|false");
  2621. config.shortDesc(
  2622. "mainport.params.servlet.7.params.sfSkipDS",
  2623. "Skip local datastore when downloading splitfiles?");
  2624. config.longDesc(
  2625. "mainport.params.servlet.7.params.sfSkipDS",
  2626. "Whether to "
  2627. + "skip the local datastore when downloading splitfiles. "
  2628. + "If you don't know what this means you don't need it.");
  2629. // mainport.params.servlet.7.params.sfUseUI
  2630. config.setExpert("mainport.params.servlet.7.params.sfUseUI", true);
  2631. config.argDesc(
  2632. "mainport.params.servlet.7.params.sfUseUI",
  2633. "true|false");
  2634. config.shortDesc(
  2635. "mainport.params.servlet.7.params.sfUseUI",
  2636. "Use downloader user interface when downloading files?");
  2637. config.longDesc(
  2638. "mainport.params.servlet.7.params.sfUseUI",
  2639. "Whether to use the downloader user interface when downloading files. If set to no, files will be downloaded directly without showing any progress monitor, but this may take a very long time and most splitfiles do not send any data until the whole file has been downloaded");
  2640. // mainport.params.servlet.7.params.sfRunFilter
  2641. config.setExpert("mainport.params.servlet.7.params.sfRunFilter", true);
  2642. config.argDesc(
  2643. "mainport.params.servlet.7.params.sfRunFilter",
  2644. "true|false");
  2645. config.shortDesc(
  2646. "mainport.params.servlet.7.params.sfRunFilter",
  2647. "Run the anonymity filter on HTML splitfiles?");
  2648. // mainport.params.servlet.7.params.sfRandomSegs
  2649. config.setExpert("mainport.params.servlet.7.params.sfRandomSegs", true);
  2650. config.argDesc(
  2651. "mainport.params.servlet.7.params.sfRandomSegs",
  2652. "true|false");
  2653. config.shortDesc(
  2654. "mainport.params.servlet.7.params.sfRandomSegs",
  2655. "Randomize the order of segment downloads for splitfiles?");
  2656. config.longDesc(
  2657. "mainport.params.servlet.7.params.sfRandomSegs",
  2658. "Whether to randomize the order of segment downloads for splitfiles. Normally this is a good thing.");
  2659. // mainport.params.servlet.7.params.sfFilterParanoidStringCheck
  2660. config.setExpert(
  2661. "mainport.params.servlet.7.params.sfFilterParanoidStringCheck",
  2662. true);
  2663. config.argDesc(
  2664. "mainport.params.servlet.7.params.sfFilterParanoidStringCheck",
  2665. "true|false");
  2666. config.shortDesc(
  2667. "mainport.params.servlet.7.params.sfFilterParanoidStringCheck",
  2668. "Make the anonymity filter on HTML splitfiles really paranoid?");
  2669. config.longDesc(
  2670. "mainport.params.servlet.7.params.sfFilterParanoidStringCheck",
  2671. "Make the anonymity filter on HTML splitfiles really paranoid? Currently this causes strings in CSS to be removed if they contain colons (\":\")");
  2672. // mainport.params.servlet.7.params.sfHealHtl
  2673. config.setExpert("mainport.params.servlet.7.params.sfHealHtl", true);
  2674. config.argDesc(
  2675. "mainport.params.servlet.7.params.sfHealHtl",
  2676. "integer between 0 and maxHopsToLive");
  2677. config.shortDesc(
  2678. "mainport.params.servlet.7.params.sfHealHtl",
  2679. "default HTL of splitfile healing insertions");
  2680. config.longDesc(
  2681. "mainport.params.servlet.7.params.sfHealHtl",
  2682. "Default HTL of inserts caused by splitfile healing code");
  2683. // mainport.params.servlet.7.params.sfHealPercentage
  2684. config.setExpert(
  2685. "mainport.params.servlet.7.params.sfHealPercentage",
  2686. true);
  2687. config.argDesc(
  2688. "mainport.params.servlet.7.params.sfHealPercentage",
  2689. "0...100");
  2690. config.shortDesc(
  2691. "mainport.params.servlet.7.params.sfHealPercentage",
  2692. "Percentage of missing blocks to reinsert after fetching a redundant splitfile. Reinsertion is done in the background, so the default of 100 is quite reasonable.");
  2693. // mainport.params.servlet.7.params.sfForceSave
  2694. config.setExpert("mainport.params.servlet.7.params.sfForceSave", true);
  2695. config.argDesc(
  2696. "mainport.params.servlet.7.params.sfForceSave",
  2697. "yes|no");
  2698. config.shortDesc(
  2699. "mainport.params.servlet.7.params.sfForceSave",
  2700. "force save splitfile downloads by default?");
  2701. config.longDesc(
  2702. "mainport.params.servlet.7.params.sfForceSave",
  2703. "If true, large \"splitfiles\" will always be saved as application/octet-stream, to force the browser to save the file to disk rather than trying to open it in place.");
  2704. // mainport.params.servlet.7.params.sfDefaultSaveDir
  2705. config.setExpert(
  2706. "mainport.params.servlet.7.params.sfDefaultSaveDir",
  2707. false);
  2708. config.argDesc(
  2709. "mainport.params.servlet.7.params.sfDefaultSaveDir",
  2710. "path to folder");
  2711. config.shortDesc(
  2712. "mainport.params.servlet.7.params.sfDefaultSaveDir",
  2713. "Default folder to save large downloaded files to.");
  2714. config.longDesc(
  2715. "mainport.params.servlet.7.params.sfDefaultSaveDir",
  2716. "Default folder to save large downloaded files to. Defaults to a folder",
  2717. "called \"freenet-downloads\" in your home directory.");
  2718. // mainport.params.servlet.7.params.sfDefaultWriteToDisk
  2719. config.setExpert(
  2720. "mainport.params.servlet.7.params.sfDefaultWriteToDisk",
  2721. true);
  2722. config.argDesc(
  2723. "mainport.params.servlet.7.params.sfDefaultWriteToDisk",
  2724. "yes|no");
  2725. config.longDesc(
  2726. "mainport.params.servlet.7.params.sfDefaultWriteToDisk",
  2727. "Whether to write splitfiles to disk by default, rather than sending them to the browser");
  2728. // mainport.params.servlet.7.params.sfDisableWriteToDisk
  2729. config.setExpert(
  2730. "mainport.params.servlet.7.params.sfDisableWriteToDisk",
  2731. true);
  2732. config.argDesc(
  2733. "mainport.params.servlet.7.params.sfDisableWriteToDisk",
  2734. "yes|no");
  2735. config.longDesc(
  2736. "mainport.params.servlet.7.params.sfDisableWriteToDisk",
  2737. "Set true to disable the option to write splitfile downloads direct to disk rather than streaming them to the browser. Automatically enabled if publicNode is set.");
  2738. // mainport.params.defaultServlet.uri
  2739. config.setExpert("mainport.params.defaultServlet.uri", true);
  2740. config.argDesc("mainport.params.defaultServlet.uri", "path");
  2741. config.shortDesc(
  2742. "mainport.params.defaultServlet.uri",
  2743. "Path within mainport for web interface redirect");
  2744. config.longDesc(
  2745. "mainport.params.defaultServlet.uri",
  2746. "Path within mainport for web interface redirect");
  2747. // mainport.params.defaultServlet.method
  2748. config.setExpert("mainport.params.defaultServlet.method", true);
  2749. config.argDesc("mainport.params.defaultServlet.method", "HTTP method");
  2750. config.shortDesc(
  2751. "mainport.params.defaultServlet.method",
  2752. "HTTP method for web interface redirect. Leave this alone.");
  2753. // mainport.params.defaultServlet.class
  2754. config.setExpert("mainport.params.defaultServlet.class", true);
  2755. config.argDesc("mainport.params.defaultServlet.class", "servlet class");
  2756. config.shortDesc(
  2757. "mainport.params.defaultServlet.class",
  2758. "servlet class to run web interface redirect. Leave this alone");
  2759. // mainport.params.defaultServlet.name
  2760. config.setExpert("mainport.params.defaultServlet.name", true);
  2761. config.argDesc("mainport.params.defaultServlet.name", "string");
  2762. config.shortDesc(
  2763. "mainport.params.defaultServlet.name",
  2764. "name of (usually) web interface redirect. Leave this alone.");
  2765. // mainport.params.defaultServlet.params.targetURL
  2766. config.setExpert(
  2767. "mainport.params.defaultServlet.params.targetURL",
  2768. true);
  2769. config.argDesc(
  2770. "mainport.params.defaultServlet.params.targetURL",
  2771. "path");
  2772. config.shortDesc(
  2773. "mainport.params.defaultServlet.params.targetURL",
  2774. "path in the servlet to the default page");
  2775. // System.err.println("Node.java static initialization end.");
  2776. }
  2777. //=== Static elements
  2778. // ======================================================
  2779. // node specific options
  2780. static public int routeConnectTimeout;
  2781. static public int maxHopsToLive;
  2782. static public float probIncHopsSinceReset;
  2783. static public float cacheProbPerHop;
  2784. static public float minStoreFullPCache;
  2785. static public float minRTFullPRef;
  2786. static public float minRTNodesPRef;
  2787. static public String routingTableImpl;
  2788. static public RunningAverage myPQueryRejected;
  2789. static public int newNodePollInterval = 30000; // 30 seconds
  2790. // announcement options
  2791. static public int announcementAttempts;
  2792. static public int announcementThreads;
  2793. static public int initialRequests;
  2794. static public int initialRequestHTL;
  2795. static public float overloadLow;
  2796. static public float overloadHigh;
  2797. static public boolean doRequestTriageByDelay;
  2798. static public boolean doRequestTriageBySendTime;
  2799. static public int requestDelayCutoff;
  2800. static public int successfulDelayCutoff;
  2801. static public int requestSendTimeCutoff;
  2802. static public int successfulSendTimeCutoff;
  2803. static public double defaultResetProbability;
  2804. static public int lsMaxTableSize;
  2805. static public int lsAcceptRatioSamples;
  2806. static public double lsHalfLifeHours;
  2807. static public boolean doOutLimitCutoff;
  2808. static public boolean doOutLimitConnectCutoff;
  2809. static public float outLimitCutoff;
  2810. static public float outLimitConnectCutoff;
  2811. static public float threadConnectCutoff;
  2812. static public boolean doCPULoad;
  2813. static public int sendingQueueLength;
  2814. static public int sendingQueueBytes;
  2815. static public int rateLimitingInterval = 0;
  2816. // calculated from above 2
  2817. public static final int muxTrailerBufferLength = 65535;
  2818. static public boolean doLoadBalance;
  2819. static public boolean localIsOK;
  2820. static public boolean dontLimitClients;
  2821. static public String mainportURIOverride;
  2822. static public String distributionURIOverride;
  2823. static public int aggressiveGC;
  2824. static public int configUpdateInterval;
  2825. static public int seednodesUpdateInterval;
  2826. static public boolean badAddress = false;
  2827. static public boolean logInputBytes;
  2828. static public boolean logOutputBytes;
  2829. public static int maxLog2DataSize = 20;
  2830. //static public int maxForwardTries;
  2831. static public boolean firstTime = false;
  2832. // node data files
  2833. static public String nodeFile;
  2834. static public File storeFiles[];
  2835. //The lock instance keeping the lock on the above file
  2836. private static FileLock lockFileLock=null;
  2837. // seednodes file
  2838. static public String seedFile;
  2839. // node limits
  2840. static public long storeSize;
  2841. static public int storeBlockSize;
  2842. static public float storeMaxTempFraction;
  2843. static public int rtMaxRefs, rtMaxNodes;
  2844. static public int listenPort;
  2845. static public String storeType;
  2846. static public int maxNodeConnections;
  2847. static public double maxOpenConnectionsNewbieFraction;
  2848. static public int maxNodeFilesOpen;
  2849. static public int bandwidthLimit, inputBandwidthLimit, outputBandwidthLimit;
  2850. static public int averageBandwidthLimit,
  2851. averageInputBandwidthLimit,
  2852. averageOutputBandwidthLimit;
  2853. static public double lowLevelBWLimitMultiplier;
  2854. // the param value * the fudge factor
  2855. static public double lowLevelBWLimitFudgeFactor;
  2856. static public boolean doLowLevelOutputLimiting, doLowLevelInputLimiting;
  2857. static public boolean doReserveOutputBandwidthForSuccess;
  2858. static public int maxNegotiations;
  2859. static public boolean doEstimatorSmoothing;
  2860. static public boolean useFastEstimators;
  2861. // The maximum number of node references that
  2862. // will be returned by successive calls to
  2863. // Routing.getNextRoute().
  2864. static public int maxRoutingSteps;
  2865. static public float minCP;
  2866. static public int minARKDelay;
  2867. static public int failuresLookupARK;
  2868. static public float maxARKThreadsFraction;
  2869. // datastore encryption
  2870. static public String storeCipherName;
  2871. static public int storeCipherWidth;
  2872. static public File routingDir;
  2873. static public boolean useDSIndex;
  2874. // So we can keep track of how long the
  2875. // node has been running. Approximate, but good enough.
  2876. static final public long startupTimeMs = System.currentTimeMillis();
  2877. // remote admin stuff
  2878. static private String adminPassword;
  2879. static private Identity adminPeer;
  2880. // common service ports
  2881. static public int distributionPort;
  2882. static public int fproxyPort;
  2883. // thread management. Parameters read in Main.java
  2884. static public int maxThreads; // maximumThreads parameter.
  2885. static public int targetMaxThreads;
  2886. static public String threadFactoryName;
  2887. static public int tfTolerableQueueDelay;
  2888. static public int tfAbsoluteMaxThreads;
  2889. static protected ThreadFactory threadFactory;
  2890. // client stuff
  2891. static public String filterPassThroughMimeTypes;
  2892. static public boolean httpInserts;
  2893. static public boolean fcpInserts;
  2894. static public String uiTemplateSet = Node.uiTemplateSet + "";
  2895. static public Bandwidth ibw, obw;
  2896. static public boolean defaultToSimpleUIMode;
  2897. static public boolean defaultToOCMHTMLPeerHandlerMode;
  2898. static public RecentKeyList recentKeys;
  2899. private static Object syncCountsByBackoffCount = new Object();
  2900. private static long[] successesByBackoffCount;
  2901. private static long[] failuresByBackoffCount;
  2902. public static boolean isAuthorized(Identity id, String p) {
  2903. if (adminPassword != null
  2904. && !adminPassword.equals("")
  2905. && adminPeer != null) {
  2906. return adminPassword.equals(p) && adminPeer.equals(id);
  2907. } else if (adminPassword != null && adminPassword.length()!=0) {
  2908. return adminPassword.equals(p);
  2909. } else if (adminPeer != null) {
  2910. return adminPeer.equals(id);
  2911. } else { // no remote admin
  2912. return false;
  2913. }
  2914. }
  2915. /**
  2916. * @throws CoreException
  2917. * if initialization has already occurred
  2918. */
  2919. public static void init(Params params) throws CoreException {
  2920. // Init the core settings
  2921. Core.init(params);
  2922. // set keytypes
  2923. try {
  2924. Key.addKeyType(freenet.keys.SVK.keyNumber, freenet.keys.SVK.class);
  2925. Key.addKeyType(freenet.keys.CHK.keyNumber, freenet.keys.CHK.class);
  2926. } catch (KeyException e) {
  2927. String s = "Failed initializing Key classes: " + e;
  2928. logger.log(Node.class, s, e, Logger.ERROR);
  2929. System.err.println(s);
  2930. e.printStackTrace(System.err);
  2931. CoreException ce = new CoreException(s);
  2932. ce.initCause(e);
  2933. throw ce;
  2934. }
  2935. String[] keyTypes = params.getList("keyTypes");
  2936. for (int i = 1; keyTypes != null && i < keyTypes.length; i += 2) {
  2937. try {
  2938. Key.addKeyType(
  2939. Integer.parseInt(keyTypes[i - 1]),
  2940. Class.forName(keyTypes[i]));
  2941. } catch (ClassNotFoundException e) {
  2942. logger.log(
  2943. Node.class,
  2944. "No such class: "
  2945. + keyTypes[i]
  2946. + " for Key type "
  2947. + keyTypes[i
  2948. - 1],
  2949. Logger.ERROR);
  2950. } catch (ClassCastException e) {
  2951. logger.log(
  2952. Node.class,
  2953. "Class " + keyTypes[i] + " is not a Key",
  2954. Logger.ERROR);
  2955. } catch (KeyException e) {
  2956. String s = "Failed initializing Key classes: " + e;
  2957. logger.log(Node.class, s, e, Logger.ERROR);
  2958. System.err.println(s);
  2959. e.printStackTrace(System.err);
  2960. CoreException ce = new CoreException(s);
  2961. ce.initCause(e);
  2962. throw ce;
  2963. }
  2964. }
  2965. myPQueryRejected = new SimpleBinaryRunningAverage(1000, 1.0);
  2966. // set network parameters
  2967. newNodePollInterval = params.getInt("newNodePollInterval");
  2968. recentKeys = new RecentKeyList(512, Core.getRandSource());
  2969. routeConnectTimeout = params.getInt("routeConnectTimeout");
  2970. maxHopsToLive = params.getInt("maxHopsToLive");
  2971. maxLog2DataSize = params.getInt("maxLog2DataSize");
  2972. probIncHopsSinceReset = params.getFloat("probIncHopsSinceReset");
  2973. cacheProbPerHop = params.getFloat("cacheProbPerHop");
  2974. minStoreFullPCache = params.getFloat("minStoreFullPCache");
  2975. minRTFullPRef = params.getFloat("minRTFullPRef");
  2976. minRTNodesPRef = params.getFloat("minRTNodesPRef");
  2977. //routingTableImpl = params.getString("routingTableImpl");
  2978. maxNegotiations = params.getInt("maxNegotiations");
  2979. routingTableImpl = "ng";
  2980. announcementAttempts = params.getInt("announcementAttempts");
  2981. announcementThreads = params.getInt("announcementThreads");
  2982. initialRequests = params.getInt("initialRequests");
  2983. initialRequestHTL = params.getInt("initialRequestHTL");
  2984. //maxForwardTries = Defaults.getInt("maxForwardTries", params);
  2985. int maxRequestsPerInterval = params.getInt("maxRequestsPerInterval");
  2986. if (maxRequestsPerInterval > 0)
  2987. outboundRequestLimit =
  2988. new LimitCounter(
  2989. params.getInt("maxRequestsInterval"),
  2990. maxRequestsPerInterval);
  2991. lowLevelBWLimitFudgeFactor =
  2992. params.getFloat("lowLevelBWLimitFudgeFactor");
  2993. lowLevelBWLimitMultiplier =
  2994. params.getFloat("lowLevelBWLimitMultiplier")
  2995. * lowLevelBWLimitFudgeFactor;
  2996. // doLowLevelOutputLimiting = false;
  2997. // doLowLevelInputLimiting = false;
  2998. doLowLevelOutputLimiting =
  2999. params.getBoolean("doLowLevelOutputLimiting");
  3000. doLowLevelInputLimiting = params.getBoolean("doLowLevelInputLimiting");
  3001. doReserveOutputBandwidthForSuccess =
  3002. params.getBoolean("doReserveOutputBandwidthForSuccess");
  3003. bandwidthLimit = params.getInt("bandwidthLimit");
  3004. inputBandwidthLimit = params.getInt("inputBandwidthLimit");
  3005. outputBandwidthLimit = params.getInt("outputBandwidthLimit");
  3006. averageBandwidthLimit = params.getInt("averageBandwidthLimit");
  3007. averageInputBandwidthLimit =
  3008. params.getInt("averageInputBandwidthLimit");
  3009. averageOutputBandwidthLimit =
  3010. params.getInt("averageOutputBandwidthLimit");
  3011. if (inputBandwidthLimit == 0
  3012. && outputBandwidthLimit == 0
  3013. && averageInputBandwidthLimit == 0
  3014. && averageOutputBandwidthLimit == 0) {
  3015. if (bandwidthLimit != 0 || averageBandwidthLimit != 0) {
  3016. String err =
  3017. "Overall bandwidth limit NO LONGER SUPPORTED! - approximating by setting each direction to half the specified limit";
  3018. logger.log(Node.class, err, Logger.ERROR);
  3019. System.err.println(err);
  3020. System.out.println(err);
  3021. outputBandwidthLimit = bandwidthLimit / 2;
  3022. inputBandwidthLimit = bandwidthLimit / 2;
  3023. }
  3024. }
  3025. if (doLowLevelInputLimiting) {
  3026. ibw =
  3027. inputBandwidthLimit == 0
  3028. ? null
  3029. : new Bandwidth(
  3030. (int) (inputBandwidthLimit * lowLevelBWLimitMultiplier),
  3031. (int) (averageInputBandwidthLimit
  3032. * lowLevelBWLimitMultiplier),
  3033. Bandwidth.RECEIVED);
  3034. } else
  3035. ibw = null;
  3036. if (doLowLevelOutputLimiting) {
  3037. obw =
  3038. outputBandwidthLimit == 0
  3039. ? null
  3040. : new Bandwidth(
  3041. (int) (outputBandwidthLimit
  3042. * lowLevelBWLimitMultiplier),
  3043. (int) (averageOutputBandwidthLimit
  3044. * lowLevelBWLimitMultiplier),
  3045. Bandwidth.SENT);
  3046. } else
  3047. obw = null;
  3048. if (params.getBoolean("limitAll")) {
  3049. logger.log(Node.class, "Limiting all connections", Logger.DEBUG);
  3050. tcpAddress.throttleAll = true;
  3051. tcpListener.throttleAll = true;
  3052. }
  3053. try {
  3054. tcpConnection.setInputBandwidth(ibw);
  3055. tcpConnection.setOutputBandwidth(obw);
  3056. } catch (NoClassDefFoundError e) {
  3057. if (e
  3058. .getMessage()
  3059. .indexOf("java/nio/channels/spi/AbstractInterruptibleChannel")
  3060. != -1) {
  3061. String error =
  3062. "Your Java installation is too old (insufficient NIO support). Please update it to 1.4.1 or later; you can do that at http://java.sun.com/ .";
  3063. System.err.println(error);
  3064. logger.log(Node.class, error, Logger.ERROR);
  3065. System.exit(1);
  3066. } else
  3067. throw e;
  3068. }
  3069. // ThrottledInputStream.setThrottle(ibw);
  3070. // ThrottledOutputStream.setThrottle(obw);
  3071. // set storage parameters
  3072. storeSize = params.getLong("storeSize");
  3073. if (storeSize > 0 && storeSize < (101L * (1 << 20))) {
  3074. String error =
  3075. "Store size insufficient to store 1MB chunks! Your datastore is so small that it will not be able to store 1MB chunks, the maximum size of a single data key that most tools insert. You will still be able to fetch them but your node will not be very useful to the network, and consequentially will not perform well. To eliminate this error increase your storeSize to at least 101M. It is currently "
  3076. + storeSize
  3077. + ".";
  3078. System.err.println(error);
  3079. logger.log(Node.class, error, Logger.ERROR);
  3080. }
  3081. storeBlockSize = params.getInt("storeBlockSize");
  3082. storeMaxTempFraction = params.getFloat("storeMaxTempFraction");
  3083. //maxFileSize = cacheSize / params.getInt("storeCacheCount");
  3084. maxNodeConnections = params.getInt("maxNodeConnections");
  3085. maxNodeFilesOpen = params.getInt("maxNodeFilesOpen");
  3086. maxOpenConnectionsNewbieFraction =
  3087. params.getDouble("maxOpenConnectionsNewbieFraction");
  3088. rtMaxRefs = params.getInt("rtMaxRefs");
  3089. if(maxNodeConnections > 0)
  3090. rtMaxNodes = maxNodeConnections * 2;
  3091. else
  3092. rtMaxNodes = params.getInt("rtMaxNodes");
  3093. doEstimatorSmoothing = params.getBoolean("doEstimatorSmoothing");
  3094. useFastEstimators = params.getBoolean("useFastEstimators");
  3095. successesByBackoffCount = new long[rtMaxNodes+1];
  3096. failuresByBackoffCount = new long[rtMaxNodes+1];
  3097. maxRoutingSteps = params.getInt("maxRoutingSteps");
  3098. if(maxRoutingSteps < 0) maxRoutingSteps = rtMaxNodes/4;
  3099. minCP = params.getFloat("minCP");
  3100. failuresLookupARK = params.getInt("failuresLookupARK");
  3101. minARKDelay = params.getInt("minARKDelay");
  3102. maxARKThreadsFraction =
  3103. params.getFloat("maxARKThreadsFraction");
  3104. storeCipherName = params.getString("storeCipherName");
  3105. if (storeCipherName.equals("none")
  3106. || storeCipherName.equals("null")
  3107. || storeCipherName.equals("void"))
  3108. storeCipherName = null;
  3109. storeCipherWidth = params.getInt("storeCipherWidth");
  3110. routingDir = new File(params.getString("routingDir"));
  3111. useDSIndex = params.getBoolean("useDSIndex");
  3112. // get the listening port
  3113. listenPort = params.getInt("listenPort");
  3114. // seednodes file
  3115. seedFile = params.getString("seedFile");
  3116. String[] storeFile = params.getList("storeFile");
  3117. if (storeFile.length == 0
  3118. || storeFile[0] == null
  3119. || storeFile[0].length()==0) {
  3120. storeFile = new String[] { "store" };
  3121. File f = new File("store_" + listenPort);
  3122. if (f.exists()) {
  3123. if (!f.renameTo(new File("store"))) {
  3124. logger.log(
  3125. Node.class,
  3126. "Cannot rename "
  3127. + f
  3128. + " to \"store\". This would be useful"
  3129. + " because then you could change the port"
  3130. + " without causing the datastore to"
  3131. + " disappear, causing a major disk space leak"
  3132. + " and a significant loss of performance.",
  3133. Logger.NORMAL);
  3134. storeFile = new String[] { "store_" + listenPort };
  3135. } else {
  3136. File idx = new File("store", "index");
  3137. if (idx.exists())
  3138. idx.delete();
  3139. idx = new File("store", "index.old");
  3140. if (idx.exists())
  3141. idx.delete();
  3142. }
  3143. }
  3144. }
  3145. storeFiles = new File[storeFile.length];
  3146. for (int i = 0; i < storeFiles.length; ++i) {
  3147. storeFiles[i] = new File(storeFile[i]);
  3148. if (storeFiles[i].exists())
  3149. firstTime = false;
  3150. }
  3151. if ((routingDir == null
  3152. || routingDir.toString().length() == 0)
  3153. && storeFiles[0] != null
  3154. && storeFiles[0].getPath().length() > 0) {
  3155. routingDir =
  3156. storeFiles[0].getAbsoluteFile().getParentFile();
  3157. }
  3158. //The file used to prevent additional instances of a node from starting
  3159. final File lockFile = new File(routingDir, "lock.lck");
  3160. //See if 'we' are already running
  3161. try {
  3162. lockFile.createNewFile();
  3163. } catch (IOException e) {
  3164. //Dont care if we managed to create the file or not (wheter or not it already existed really).
  3165. //What really matters is wheter or not we manage to lock it below
  3166. }
  3167. if(!lockFile.exists()){
  3168. //Hmmm.. this is bad.. better shut down I assume
  3169. logger.log(Node.class, "Lockfile '"+lockFile.getAbsolutePath()+"' doesn't exist after we tried to create it. Permissions problem? Shutting down.",Logger.ERROR);
  3170. System.exit(2);
  3171. }
  3172. try {
  3173. lockFileLock = new FileOutputStream(lockFile).getChannel().tryLock();
  3174. } catch (Exception e) {
  3175. logger.log(Node.class, "Encountered an unexpected error when locking the lockfile '"+lockFile.getAbsolutePath()+"'. Shutting down.",e,Logger.ERROR);
  3176. System.exit(3);
  3177. }
  3178. if(lockFileLock ==null){
  3179. logger.log(Node.class, "Lockfile '"+lockFile.getAbsolutePath()+"' locked by another process. Maybe another node is running? Shutting down.",Logger.ERROR);
  3180. System.exit(4);
  3181. }
  3182. //Unfortunately the below method doesn't work then the JVM is killed bu the user...
  3183. //However, it looks better if we at least _try_ to clean up after us.
  3184. lockFile.deleteOnExit();
  3185. // locate the data files
  3186. nodeFile = params.getString("nodeFile");
  3187. if (nodeFile == null || nodeFile.length()==0) {
  3188. File f = new File("node_" + listenPort);
  3189. nodeFile = "node";
  3190. if (f.exists()) {
  3191. if (!f.renameTo(new File(nodeFile))) {
  3192. logger.log(
  3193. Node.class,
  3194. "Cannot rename "
  3195. + f
  3196. + " to \"node\". This would be useful "
  3197. + " because then you could change the port "
  3198. + " without causing the node identity to"
  3199. + " disappear, taking with it all references to"
  3200. + " your node from the rest of the network.",
  3201. Logger.NORMAL);
  3202. nodeFile = "node_" + listenPort;
  3203. }
  3204. }
  3205. }
  3206. // set admin permisions
  3207. String pword = params.getString("adminPassword");
  3208. if (!"".equals(pword))
  3209. adminPassword = pword;
  3210. FieldSet peer = params.getSet("adminPeer");
  3211. if (peer != null) {
  3212. adminPeer = new DSAIdentity(peer);
  3213. }
  3214. overloadLow = params.getFloat("overloadLow");
  3215. overloadHigh = params.getFloat("overloadHigh");
  3216. if(overloadHigh < 1.0) {
  3217. Core.logger.log(Main.class, "overloadHigh set to "+nfp.format(overloadHigh)+
  3218. " - this will NOT WORK with rate limiting", Logger.ERROR);
  3219. overloadHigh = overloadHighDefault;
  3220. }
  3221. doRequestTriageByDelay = params.getBoolean("doRequestTriageByDelay");
  3222. doRequestTriageBySendTime =
  3223. params.getBoolean("doRequestTriageBySendTime");
  3224. requestDelayCutoff = params.getInt("requestDelayCutoff");
  3225. successfulDelayCutoff = params.getInt("successfulDelayCutoff");
  3226. requestSendTimeCutoff = params.getInt("requestSendTimeCutoff");
  3227. successfulSendTimeCutoff = params.getInt("successfulSendTimeCutoff");
  3228. defaultResetProbability = params.getDouble("defaultResetProbability");
  3229. lsMaxTableSize = params.getInt("lsMaxTableSize");
  3230. lsAcceptRatioSamples = params.getInt("lsAcceptRatioSamples");
  3231. lsHalfLifeHours = params.getDouble("lsHalfLifeHours");
  3232. doOutLimitCutoff = params.getBoolean("doOutLimitCutoff");
  3233. outLimitCutoff = params.getFloat("outLimitCutoff");
  3234. doOutLimitConnectCutoff = params.getBoolean("doOutLimitConnectCutoff");
  3235. outLimitConnectCutoff = params.getFloat("outLimitConnectCutoff");
  3236. threadConnectCutoff = params.getFloat("threadConnectCutoff");
  3237. doCPULoad = params.getBoolean("doCPULoad");
  3238. sendingQueueLength = params.getInt("sendingQueueLength");
  3239. sendingQueueBytes = params.getInt("sendingQueueBytes");
  3240. doLoadBalance = params.getBoolean("doLoadBalance");
  3241. localIsOK = params.getBoolean("localIsOK");
  3242. dontLimitClients = params.getBoolean("dontLimitClients");
  3243. mainportURIOverride = params.getString("mainportURIOverride");
  3244. distributionURIOverride = params.getString("distributionURIOverride");
  3245. aggressiveGC = params.getInt("aggressiveGC");
  3246. configUpdateInterval = params.getInt("configUpdateInterval");
  3247. seednodesUpdateInterval = params.getInt("seednodesUpdateInterval");
  3248. distributionPort = params.getInt("distribution.port");
  3249. fproxyPort = params.getInt("mainport.port");
  3250. filterPassThroughMimeTypes =
  3251. params.getString("filterPassThroughMimeTypes");
  3252. httpInserts = params.getBoolean("httpInserts");
  3253. fcpInserts = params.getBoolean("fcpInserts");
  3254. defaultToSimpleUIMode = params.getBoolean("defaultToSimpleUIMode");
  3255. defaultToOCMHTMLPeerHandlerMode =
  3256. params.getBoolean("defaultToOCMHTMLPeerHandlerMode");
  3257. uiTemplateSet = params.getString("UITemplateSet");
  3258. logOutputBytes = params.getBoolean("logOutputBytes");
  3259. logInputBytes = params.getBoolean("logInputBytes");
  3260. freenet.support.servlet.HtmlTemplate.defaultTemplateSet = uiTemplateSet;
  3261. // If we are in watchme mode, initialize watchme and change the
  3262. // protocol
  3263. // version to prevent spy nodes from polluting the real network
  3264. if (params.getBoolean("watchme")) {
  3265. watchme = new WatchMe();
  3266. watchme.init(params.getInt("watchmeRetries"));
  3267. Version.protocolVersion = Version.protocolVersion + "wm";
  3268. freenet.session.FnpLink.AUTH_LAYER_VERSION = 0x05;
  3269. }
  3270. // Around 1000 seconds.
  3271. // This is the time it would take for a request to start and finish
  3272. // at 1kB/sec.
  3273. // As of 29/7/04, this is relatively rare.
  3274. // So we have a less-alchemical way of setting it, than just "5 minutes sounds good" :).
  3275. rateLimitingInterval = 800*1000 + getRandSource().nextInt(400*1000);
  3276. }
  3277. /**
  3278. * Construct this node's NodeReference from the given private key.
  3279. */
  3280. static NodeReference makeNodeRef(
  3281. Authentity priv,
  3282. Address[] addr,
  3283. SessionHandler sh,
  3284. PresentationHandler ph,
  3285. long ARKversion,
  3286. byte[] ARKcrypt) {
  3287. long[] sessions, presentations;
  3288. Enumeration e;
  3289. sessions = new long[sh.size()];
  3290. e = sh.getLinkManagers();
  3291. for (int i = 0; i < sessions.length; ++i)
  3292. sessions[i] = ((LinkManager) e.nextElement()).designatorNum();
  3293. presentations = new long[ph.size()];
  3294. e = ph.getPresentations();
  3295. for (int i = 0; i < presentations.length; ++i)
  3296. presentations[i] = ((Presentation) e.nextElement()).designatorNum();
  3297. NodeReference nr =
  3298. new NodeReference(
  3299. priv.getIdentity(),
  3300. addr,
  3301. sessions,
  3302. presentations,
  3303. Version.getVersionString(),
  3304. ARKversion,
  3305. ARKcrypt);
  3306. // FIXME - this method should accept an uncast Authentity
  3307. nr.addSignature((DSAAuthentity) priv);
  3308. return nr;
  3309. }
  3310. /**
  3311. * The Directory that stores all the node's data.
  3312. */
  3313. public final Directory dir;
  3314. /**
  3315. * A source of temp file buckets.
  3316. */
  3317. public final BucketFactory bf;
  3318. /**
  3319. * The nodes table of cached documents.
  3320. */
  3321. public final DataStore ds;
  3322. /**
  3323. * The routing table for routing requests on a key.
  3324. */
  3325. public final NodeSortingRoutingTable rt;
  3326. /**
  3327. * The table of recently failed keys.
  3328. */
  3329. public final FailureTable ft;
  3330. /**
  3331. * Queue manager
  3332. */
  3333. public QueueManager queueManager;
  3334. /**
  3335. * Load statistics module.
  3336. */
  3337. public final LoadStats loadStats;
  3338. /**
  3339. * Support for FEC encoding / FEC decoding.
  3340. */
  3341. public static FECTools fecTools = null;
  3342. // REDFLAG: initialize, better interface, i.e make final?
  3343. /**
  3344. * Temp dir for servlets, FEC etc
  3345. */
  3346. public static File tempDir = null;
  3347. // REDFLAG: initialize, better interface, i.e make final?
  3348. /**
  3349. * A node reference to this node. Basically this is who the node is to the
  3350. * network.
  3351. */
  3352. protected NodeReference myRef;
  3353. // FIXME: make protected, use an accessor
  3354. // Only the update-ARK code needs to modify myRef
  3355. public final NodeReference getNodeReference() {
  3356. return myRef;
  3357. }
  3358. public final void setNodeReference(NodeReference newRef) {
  3359. myRef=newRef;
  3360. }
  3361. //A couple of diagnostic variables used in load calculation
  3362. private final RunningAverage routingTimeMinuteAverage;
  3363. private final RunningAverage messageSendTimeRequestMinuteAverage;
  3364. private final IntervalledSum outputBytesLastMinute;
  3365. // Main rate limiting variables
  3366. public ExtrapolatingTimeDecayingEventCounter receivedRequestCounter;
  3367. public ExtrapolatingTimeDecayingEventCounter acceptedExternalRequestCounter;
  3368. RunningAverage globalQuotaAverager;
  3369. // Number of outbound requests per minute the node will make.
  3370. static public LimitCounter outboundRequestLimit;
  3371. public ExtrapolatingTimeDecayingEventCounter sentRequestCounter;
  3372. /** Watchme (aka test network) functionality */
  3373. public static WatchMe watchme = null;
  3374. /**
  3375. * Internal client access.
  3376. */
  3377. public final ClientFactory client;
  3378. /**
  3379. * Creates a new Node.
  3380. *
  3381. * @param privKey
  3382. * The node's private key.
  3383. * @param dir
  3384. * Directory of the node's storage repository.
  3385. * @param bf
  3386. * The source for temp file buckets.
  3387. * @param ds
  3388. * The store where cached data is kept.
  3389. * @param rt
  3390. * The table for routing requests based on key values.
  3391. * @param ft
  3392. * The table that keeps track recently failed keys.
  3393. * @param myRef
  3394. * The NodeReference name to send to other nodes.
  3395. * @param th
  3396. * A transporthandler on which the available transports are
  3397. * registered.
  3398. * @param sh
  3399. * The sessionhandler to use for making connections
  3400. * @param ph
  3401. * The presentationHandler to use for making connections
  3402. * @param loadStats
  3403. * The restored LoadStats object
  3404. */
  3405. public Node(
  3406. Authentity privKey,
  3407. NodeReference myRef,
  3408. Directory dir,
  3409. BucketFactory bf,
  3410. DataStore ds,
  3411. NodeSortingRoutingTable rt,
  3412. FailureTable ft,
  3413. TransportHandler th,
  3414. SessionHandler sh,
  3415. PresentationHandler ph,
  3416. LoadStats loadStats,
  3417. File routingDir) {
  3418. super(privKey, myRef.getIdentity(), th, sh, ph);
  3419. this.myRef = myRef;
  3420. this.dir = dir;
  3421. this.bf = bf;
  3422. this.ds = ds;
  3423. this.ft = ft;
  3424. this.rt = rt;
  3425. this.client = new InternalClient(this);
  3426. this.loadStats = loadStats;
  3427. int ONE_MINUTE_MILLISECONDS_COUNT = 60000; //Just to make my intention somewhat clearer
  3428. //Initialize the routingTime RunningAverage
  3429. RunningAverage r1 = new SimpleIntervalledRunningAverage(ONE_MINUTE_MILLISECONDS_COUNT,100,false);
  3430. routingTimeMinuteAverage = new SynchronizedRunningAverage(r1);
  3431. diagnostics.getExternalContinuousVariable("routingTime").relayReportsTo(routingTimeMinuteAverage,Diagnostics.MEAN_VALUE);
  3432. //Initialize the messageSendTimeRequest average
  3433. messageSendTimeRequestMinuteAverage = new SynchronizedRunningAverage(new SimpleIntervalledRunningAverage(ONE_MINUTE_MILLISECONDS_COUNT,100,false));
  3434. diagnostics.getExternalContinuousVariable("messageSendTimeRequest").relayReportsTo(messageSendTimeRequestMinuteAverage,Diagnostics.MEAN_VALUE);
  3435. //Initialize the outputBytes average
  3436. outputBytesLastMinute = new IntervalledSum(ONE_MINUTE_MILLISECONDS_COUNT);
  3437. diagnostics.getExternalCountingVariable("outputBytes").relayReportsTo(outputBytesLastMinute,Diagnostics.COUNT_CHANGE);
  3438. if(rateLimitingInterval == 0)
  3439. throw new IllegalStateException("Must call init() first!");
  3440. rlwc = new RateLimitingWriterCheckpointed(routingDir);
  3441. rlwc.load();
  3442. }
  3443. final RateLimitingWriterCheckpointed rlwc;
  3444. public void begin(Ticker t,
  3445. OpenConnectionManager ocm, NIOInterface[] inter,
  3446. boolean daemon) throws CoreException {
  3447. connectionOpener =
  3448. new ConnectionOpenerManager(maxNegotiations, rt, ocm, this);
  3449. queueManager = new QueueManager(ocm, (NGRoutingTable)(Main.origRT), t);
  3450. super.begin(t, ocm, inter, daemon);
  3451. }
  3452. protected class NodeBackgroundInserter extends BackgroundInserter {
  3453. public NodeBackgroundInserter(
  3454. int nThreads,
  3455. int maxSize,
  3456. ClientFactory cf,
  3457. BucketFactory bf) {
  3458. super(nThreads, maxSize, cf, bf);
  3459. }
  3460. protected void onDone(
  3461. boolean success,
  3462. int htl,
  3463. freenet.client.FreenetURI uri) {
  3464. super.onDone(success, htl, uri);
  3465. logger.log(
  3466. this,
  3467. "Background healing insert: "
  3468. + (success ? "Success: " : "Failure: ")
  3469. + ((uri == null) ? "(null)" : uri.toString()),
  3470. Logger.DEBUG);
  3471. if (success)
  3472. diagnostics.occurrenceCounting("successBackgroundInsert", 1);
  3473. else
  3474. diagnostics.occurrenceCounting("failureBackgroundInsert", 1);
  3475. }
  3476. protected void logDebug(String s, boolean trace) {
  3477. if (logger.shouldLog(Logger.DEBUG,this)) {
  3478. if (trace)
  3479. logger.log(this, s, Logger.DEBUG);
  3480. else
  3481. logger.log(
  3482. this,
  3483. s,
  3484. new Exception("debug"),
  3485. Logger.DEBUG);
  3486. }
  3487. }
  3488. public void queue(
  3489. Bucket block,
  3490. BucketFactory owner,
  3491. int htl,
  3492. String cipher) {
  3493. super.queue(block, owner, htl, cipher);
  3494. if (logger.shouldLog(Logger.MINOR,this))
  3495. logger.log(
  3496. this,
  3497. "Queued a background insert at HTL " + htl,
  3498. Logger.MINOR);
  3499. diagnostics.occurrenceCounting("queuedBackgroundInsert", 1);
  3500. }
  3501. protected void onRawEvent(freenet.client.ClientEvent e) {
  3502. if (logger.shouldLog(Logger.DEBUG,this)) {
  3503. logger.log(
  3504. this,
  3505. "BI: " + e.getDescription(),
  3506. Logger.DEBUG);
  3507. }
  3508. }
  3509. protected void onStart() {
  3510. if (logger.shouldLog(Logger.MINOR,this)) {
  3511. logger.log(
  3512. this,
  3513. "BackgroundInserter -- thread started.",
  3514. Logger.MINOR);
  3515. }
  3516. }
  3517. protected void onExit() {
  3518. if (logger.shouldLog(Logger.MINOR,this)) {
  3519. logger.log(
  3520. this,
  3521. "BackgroundInserter -- thread exited.",
  3522. Logger.MINOR);
  3523. }
  3524. }
  3525. }
  3526. /** @return something for the logs.. */
  3527. public final String toString() {
  3528. return "Freenet Node: " + HexUtil.bytesToHex(identity.fingerprint());
  3529. }
  3530. /**
  3531. * Returns a peer object for which a connection with a node can be made.
  3532. *
  3533. * @param nr
  3534. * The node for which a Peer object is needed.
  3535. */
  3536. public final Peer getPeer(NodeReference nr) {
  3537. return nr.getPeer(transports, sessions, presentations);
  3538. }
  3539. /**
  3540. * @return Number of jobs running or queued for execution by the node's
  3541. * ThreadManager. Can return -1 if no thread manager is being used.
  3542. */
  3543. public final int activeJobs() {
  3544. return threadFactory.activeThreads();
  3545. }
  3546. public final int availableThreads() {
  3547. return threadFactory.availableThreads();
  3548. }
  3549. public ThreadFactory getThreadFactory() {
  3550. return threadFactory;
  3551. }
  3552. /**
  3553. * @return true if the Node is Rejecting inbound connections, false
  3554. * otherwise.
  3555. */
  3556. public boolean rejectingConnections() {
  3557. return rejectingConnections(null);
  3558. }
  3559. public boolean rejectingConnections(StringBuffer why) {
  3560. int maximumThreads = threadFactory.maximumThreads();
  3561. int activeThreads = threadFactory.activeThreads();
  3562. if ((maximumThreads > 0) && threadConnectCutoff > 0 &&
  3563. (activeThreads >= (maximumThreads*threadConnectCutoff))) {
  3564. if (why != null) {
  3565. why.append("activeThreads(");
  3566. why.append(activeThreads);
  3567. why.append(") >= maximumThreads (");
  3568. why.append(maximumThreads);
  3569. why.append(")");
  3570. }
  3571. return true;
  3572. }
  3573. if (diagnostics != null
  3574. && logOutputBytes
  3575. && doOutLimitConnectCutoff
  3576. && obw != null) {
  3577. double sent =
  3578. diagnostics.getCountingValue(
  3579. "outputBytes",
  3580. Diagnostics.MINUTE,
  3581. Diagnostics.COUNT_CHANGE);
  3582. if (Double.isNaN(sent))
  3583. sent = 0.0;
  3584. double limit = outputBandwidthLimit * 60 * outLimitConnectCutoff;
  3585. if (sent > limit) {
  3586. if (nextLoggedRejectingConns < System.currentTimeMillis()) {
  3587. logger.log(
  3588. this,
  3589. "Rejecting connections because bwlimit exceeded by 200%!",
  3590. Logger.NORMAL);
  3591. nextLoggedRejectingConns =
  3592. System.currentTimeMillis() + 60000;
  3593. }
  3594. if (why != null) {
  3595. why.append("outputBytesPerMinute(");
  3596. why.append(nf1.format(sent));
  3597. why.append(") > outLimitConnectCutoff(");
  3598. why.append(nf1.format(outLimitConnectCutoff));
  3599. why.append(") * outputBandwidthLimit(");
  3600. why.append(nf1.format(outputBandwidthLimit));
  3601. why.append(") * 60 = ");
  3602. why.append(nf1.format(limit));
  3603. }
  3604. return true; // Reject connections - emergency bwlimiting
  3605. }
  3606. }
  3607. if (diagnostics != null && doRequestTriageByDelay) {
  3608. double delay = routingTimeMinuteAverage.currentValue();
  3609. if (Double.isNaN(delay))
  3610. delay = 0.0;
  3611. if (delay > successfulDelayCutoff) {
  3612. if (why != null) {
  3613. why.append("avgRoutingTime(");
  3614. why.append(nf3.format(delay));
  3615. why.append(") > successfulDelayCutoff(");
  3616. why.append(nf3.format(successfulDelayCutoff) + ")");
  3617. }
  3618. return true;
  3619. }
  3620. }
  3621. if (diagnostics != null && doRequestTriageBySendTime) {
  3622. double delay = messageSendTimeRequestMinuteAverage.currentValue();
  3623. if (Double.isNaN(delay))
  3624. delay = 0.0;
  3625. if (delay > successfulSendTimeCutoff) {
  3626. if (why != null) {
  3627. why.append("avgMessageSendTimeRequest(");
  3628. why.append(nf3.format(delay));
  3629. why.append(") > successfulSendTimeCutoff(");
  3630. why.append(nf3.format(successfulSendTimeCutoff));
  3631. why.append(")");
  3632. }
  3633. return true;
  3634. }
  3635. }
  3636. return false;
  3637. }
  3638. long nextLoggedRejectingConns = 0;
  3639. /**
  3640. * @param all
  3641. * if true, only return true if the node is rejecting nearly all
  3642. * incoming reqs
  3643. * @return true if the Node is QueryRejecting inbound requests, false
  3644. * otherwise.
  3645. */
  3646. public boolean rejectingRequests(boolean all) {
  3647. return rejectingRequests(null, all);
  3648. }
  3649. public boolean rejectingRequests(StringBuffer why, boolean all) {
  3650. if (outboundRequestLimit != null && outboundRequestLimit.exceeded()) {
  3651. if (why != null) {
  3652. why.append("outboundRequestLimit exceeded.");
  3653. }
  3654. return true;
  3655. }
  3656. float estimatedLoad = estimatedLoad(false);
  3657. if (estimatedLoad > (all ? overloadHigh : overloadLow)) {
  3658. if (why != null) {
  3659. why.append("Estimated load (");
  3660. why.append(nfp.format(estimatedLoad));
  3661. why.append(") > overload" + (all ? "High" : "Low") + " (");
  3662. why.append(nfp.format(all ? overloadHigh : overloadLow));
  3663. why.append(")");
  3664. }
  3665. return true;
  3666. }
  3667. return false;
  3668. }
  3669. static class TickStat {
  3670. long user;
  3671. long nice;
  3672. long system;
  3673. long spare;
  3674. boolean read(File f) {
  3675. String firstline;
  3676. try {
  3677. FileInputStream fis = new FileInputStream(f);
  3678. ReadInputStream ris = new ReadInputStream(fis);
  3679. firstline = ris.readln();
  3680. ris.close();
  3681. } catch (IOException e) {
  3682. return false;
  3683. }
  3684. logger.log(this, "Read first line: " + firstline, Logger.DEBUG);
  3685. if(!firstline.startsWith("cpu")) return false;
  3686. long[] data = new long[4];
  3687. for(int i = 0; i < 4; i++) {
  3688. firstline = firstline.substring("cpu".length()).trim();
  3689. firstline = firstline + ' ';
  3690. int x = firstline.indexOf(' ');
  3691. if(x == -1)
  3692. return false;
  3693. String firstbit = firstline.substring(0, x);
  3694. try {
  3695. data[i] = Long.parseLong(firstbit);
  3696. } catch (NumberFormatException e) {
  3697. return false;
  3698. }
  3699. firstline = firstline.substring(x);
  3700. }
  3701. user = data[0];
  3702. nice = data[1];
  3703. system = data[2];
  3704. spare = data[3];
  3705. logger.log(this, "Read from file: user " + user + " nice " + nice + " system " +system + " spare " + spare, Logger.DEBUG);
  3706. return true;
  3707. }
  3708. int calculate(TickStat old) {
  3709. long userdiff = user - old.user;
  3710. long nicediff = nice - old.nice;
  3711. long systemdiff = system - old.system;
  3712. long sparediff = spare - old.spare;
  3713. if (userdiff + nicediff + systemdiff + sparediff <= 0)
  3714. return 0;
  3715. logger.log(this, "User changed by " + userdiff + ", Nice: " + nicediff + ", System: " + systemdiff + ", Spare: " + sparediff, Logger.DEBUG);
  3716. int usage = (int) ((100 * (userdiff + nicediff + systemdiff)) / (userdiff + nicediff + systemdiff + sparediff));
  3717. logger.log(this, "CPU usage: " + usage, Logger.DEBUG);
  3718. return usage;
  3719. }
  3720. void copyFrom(TickStat old) {
  3721. user = old.user;
  3722. nice = old.nice;
  3723. system = old.system;
  3724. spare = old.spare;
  3725. }
  3726. }
  3727. int lastCPULoadEstimate = 0;
  3728. long lastCPULoadEstimateTime = 0;
  3729. File proc = File.separator.equals("/") ? new File("/proc/stat") : null;
  3730. TickStat tsOld = new TickStat();
  3731. TickStat tsNew = null;
  3732. float lastEstimatedLoad = 0;
  3733. float lastEstimatedRateLimitingLoad = 0;
  3734. long lastCalculatedEstimatedLoad = -1;
  3735. long lastCalculatedRateLimitingLoad = -1;
  3736. long minLoadEstimationInterval = 1000; // 1 second
  3737. Object loadSync = new Object();
  3738. /**
  3739. * This is a rough estimate based on the number of running jobs. Hopefully
  3740. * we can come up with a better metric later.
  3741. *
  3742. * @param forRateLimiting if true, return the rate limiting load, if false,
  3743. * return the QueryReject load
  3744. * @return a value between (0.0, 1.0), where 0.0 indicates no load and 1.0
  3745. * indicates total overload.
  3746. *
  3747. */
  3748. public final float estimatedLoad(boolean forRateLimiting) {
  3749. return estimatedLoad(null, forRateLimiting);
  3750. }
  3751. public final float estimatedLoad(StringBuffer why, boolean forRateLimiting) {
  3752. double ret;
  3753. long now = System.currentTimeMillis();
  3754. if(why == null) {
  3755. synchronized(loadSync) {
  3756. long last = forRateLimiting ? lastCalculatedRateLimitingLoad :
  3757. lastCalculatedEstimatedLoad;
  3758. if(last + minLoadEstimationInterval > now) {
  3759. return forRateLimiting ? lastEstimatedRateLimitingLoad :
  3760. lastEstimatedLoad;
  3761. }
  3762. }
  3763. }
  3764. // FIXME: make it proportional?
  3765. // FIXME: get rid?
  3766. if (outboundRequestLimit != null && outboundRequestLimit.exceeded()) {
  3767. if (why != null) {
  3768. why.append(
  3769. "Load = 100% because outboundRequestLimit is exceeded.");
  3770. }
  3771. return 1.0F;
  3772. }
  3773. // Thread load
  3774. int maximumThreads = threadFactory.maximumThreads();
  3775. if (maximumThreads <= 0) {
  3776. ret = 0.0;
  3777. if (why != null) {
  3778. why.append(
  3779. "Load due to thread limit = 0% because maximumThreads <= 0");
  3780. }
  3781. } else {
  3782. ret = (double) activeJobs() / (double) maximumThreads;
  3783. if (why != null) {
  3784. why.append("Load due to thread limit = ");
  3785. why.append(nfp.format(ret));
  3786. }
  3787. }
  3788. if (doRequestTriageByDelay && forRateLimiting) {
  3789. double delay = routingTimeMinuteAverage.currentValue();
  3790. if (Double.isNaN(delay))
  3791. delay = 0.0;
  3792. double load;
  3793. load = calculateLoadForUnit("routingTime", "ms", why, delay,
  3794. requestDelayCutoff, successfulDelayCutoff, forRateLimiting);
  3795. if (ret < load)
  3796. ret = load;
  3797. }
  3798. if (doRequestTriageBySendTime && forRateLimiting) {
  3799. double delay = messageSendTimeRequestMinuteAverage.currentValue();
  3800. if (Double.isNaN(delay))
  3801. delay = 0.0;
  3802. double load = calculateLoadForUnit("messageSendTimeRequest", "ms", why,
  3803. delay, requestSendTimeCutoff, successfulSendTimeCutoff,
  3804. forRateLimiting);
  3805. if (load > overloadLow && ret < load)
  3806. ret = load;
  3807. }
  3808. // by backedOffCount
  3809. //if(Main.origRT instanceof NGRoutingTable && forRateLimiting) {
  3810. // int totnod=((NGRoutingTable)Main.origRT).countConnectedN
  3811. // odes();
  3812. // if(totnod>20) {
  3813. // int openod=((NGRoutingTable)Main.origRT).countUn
  3814. // backedOffNodes();
  3815. // double load=(double)(totnod-openod)/(double)totn
  3816. // od;
  3817. // // multiply by 1/x , where x is the desired percent
  3818. // // of backed off routes. As of 08/26, anything below
  3819. // // about 70% is foolhardy
  3820. // load *= 1.333 ; // target 75% closed (25% open)
  3821. // if (load > overloadLow && ret < load)
  3822. // ret = load;
  3823. // if (why != null) {
  3824. // why.append("<br />Load due to backoff = ");
  3825. // why.append(nfp.format(load));
  3826. // why.append(" (");
  3827. // why.append(openod);
  3828. // why.append(" of ");
  3829. // why.append(totnod);
  3830. // why.append(" backed off)");
  3831. // }
  3832. // }
  3833. //}
  3834. if (logOutputBytes
  3835. && (doOutLimitCutoff || forRateLimiting)
  3836. && outputBandwidthLimit > 0) {
  3837. double sent = getBytesSentLastMinute();
  3838. if (Double.isNaN(sent))
  3839. sent = 0.0;
  3840. // Because high level limiting is primarily to limit trailers,
  3841. // We want outLimitCutoff => 100%, on both measures.
  3842. double limit = outputBandwidthLimit * 60.0 * outLimitCutoff;
  3843. if(doReserveOutputBandwidthForSuccess) {
  3844. // Adjust limit to maximum attainable succcess ratio
  3845. double maxRatio = rt.maxPSuccess();
  3846. double actualRatio = Core.diagnostics.getBinomialValue("routingSuccessRatio", Diagnostics.HOUR, Diagnostics.SUCCESS_PROBABILITY);
  3847. Core.logger.log(this, "maxRatio: "+maxRatio+", actualRatio: "+actualRatio,
  3848. Logger.MINOR);
  3849. if((!Double.isInfinite(actualRatio)) && (!Double.isNaN(actualRatio)) &&
  3850. actualRatio > 0.0 && actualRatio <= 1.0 && (!Double.isNaN(maxRatio)) &&
  3851. !Double.isInfinite(maxRatio) && maxRatio > 0.0 && maxRatio <= 1.0) {
  3852. double oldLimit = limit;
  3853. double adjustment = actualRatio / maxRatio;
  3854. if(adjustment < 1.0) limit = limit * adjustment;
  3855. Core.logger.log(this, "Adjusting limit: max ratio="+maxRatio+", actualRatio="+
  3856. actualRatio+", adjustment: "+adjustment+", limit was: "+oldLimit+
  3857. ", limit now: "+limit, Logger.MINOR);
  3858. }
  3859. }
  3860. double load = sent / limit;
  3861. if (why != null) {
  3862. why.append("<br />Load due to output bandwidth limiting = ");
  3863. why.append(nfp.format(load));
  3864. why.append(" because outputBytes(");
  3865. why.append(nf03.format(sent));
  3866. why.append(") " + (sent > limit ? ">" : "<=") + " limit (");
  3867. why.append(nf03.format(limit));
  3868. why.append(" ) = outLimitCutoff (");
  3869. why.append(nf03.format(outLimitCutoff));
  3870. why.append(") * outputBandwidthLimit (");
  3871. why.append(nf03.format(outputBandwidthLimit));
  3872. why.append(") * 60");
  3873. }
  3874. if (ret < load)
  3875. ret = load;
  3876. }
  3877. if (doCPULoad && File.separator.equals("/") && forRateLimiting) {
  3878. if (now - lastCPULoadEstimateTime > 1000) {
  3879. try {
  3880. lastCPULoadEstimateTime = now;
  3881. if (tsNew == null) {
  3882. tsOld.read(proc);
  3883. tsNew = new TickStat();
  3884. } else {
  3885. if (!tsNew.read(proc)) {
  3886. logger.log(this, "Failed to parse /proc",
  3887. Logger.MINOR);
  3888. }
  3889. lastCPULoadEstimate = tsNew.calculate(tsOld);
  3890. tsOld.copyFrom(tsNew);
  3891. }
  3892. } catch (Throwable t) {
  3893. lastCPULoadEstimate = 0;
  3894. logger.log(this, "Failed real-CPU-load estimation: "
  3895. + t, t, Logger.NORMAL);
  3896. }
  3897. }
  3898. float f = (float)(((lastCPULoadEstimate) / 100.0F) / 0.75);
  3899. // target 75% cpu usage - FIXME
  3900. if(why != null) {
  3901. why.append("<br />\nLoad due to CPU usage = ");
  3902. why.append(nfp.format(f));
  3903. why.append(" = ");
  3904. why.append(lastCPULoadEstimate);
  3905. why.append("% / 0.75");
  3906. }
  3907. if (f > ret) ret = f;
  3908. }
  3909. // Predicted inbound bandwidth load
  3910. if(Main.origRT instanceof NGRoutingTable && forRateLimiting) {
  3911. double sentRequestsHour = sentRequestCounter.getExtrapolatedEventsPerHour();
  3912. double pTransfer = ((NGRoutingTable)Main.origRT).pTransferGivenRequest();
  3913. double stdFileSize = calculateStandardFileSize();
  3914. double bytesExpected = sentRequestsHour * pTransfer *
  3915. stdFileSize;
  3916. double maxBytesPerMinute;
  3917. String reason;
  3918. if(inputBandwidthLimit > 0) {
  3919. maxBytesPerMinute = inputBandwidthLimit * 60;
  3920. reason = " (set input limit) ";
  3921. } else {
  3922. maxBytesPerMinute = tcpConnection.maxSeenIncomingBytesPerMinute();
  3923. reason = " (max observed bytes per minute) ";
  3924. // Assume output is at least as wide as input
  3925. // If this is wrong, set inputBandwidthLimit
  3926. double altMaxBytesPerMinute = outputBandwidthLimit * 60 * 4;
  3927. if(altMaxBytesPerMinute > maxBytesPerMinute) {
  3928. maxBytesPerMinute = altMaxBytesPerMinute;
  3929. reason = " (output limit assumed smaller than input capacity) ";
  3930. }
  3931. }
  3932. double maxBytes = maxBytesPerMinute * (60 * 1.1);
  3933. double myLoad = maxBytes==0?0:bytesExpected / maxBytes;
  3934. if(ret < myLoad) ret = myLoad;
  3935. if(why != null) {
  3936. why.append("<br />\nLoad due to expected inbound transfers: ");
  3937. why.append(nfp.format(myLoad));
  3938. why.append(" because: ");
  3939. why.append(sentRequestsHour);
  3940. why.append(" req/hr * ");
  3941. why.append(pTransfer);
  3942. why.append(" (pTransfer) * ");
  3943. why.append(stdFileSize);
  3944. why.append(" bytes = ");
  3945. why.append((long)bytesExpected);
  3946. why.append(" bytes/hr expected from current requests, but maxInputBytes/minute = ");
  3947. why.append((long)maxBytesPerMinute);
  3948. why.append(reason);
  3949. why.append(" * 60 * 1.1 = ");
  3950. why.append((long)maxBytes);
  3951. why.append(" bytes/hr target");
  3952. }
  3953. }
  3954. // Predicted outbound bandwidth load
  3955. if(Main.origRT instanceof NGRoutingTable && forRateLimiting &&
  3956. outputBandwidthLimit > 0 && acceptedExternalRequestCounter.countEvents() > 10) {
  3957. double receivedRequestsHour = acceptedExternalRequestCounter.getExtrapolatedEventsPerHour();
  3958. double pTransfer = ((NGRoutingTable)Main.origRT).pTransferGivenInboundRequest();
  3959. double stdFileSize = calculateStandardFileSize();
  3960. double bytesExpected = receivedRequestsHour * pTransfer *
  3961. stdFileSize;
  3962. double maxBytesPerMinute;
  3963. maxBytesPerMinute = outputBandwidthLimit * 60 * 0.7; // assume significant overhead
  3964. double maxBytes = maxBytesPerMinute * 60;
  3965. double myLoad = maxBytes==0?0:bytesExpected / maxBytes;
  3966. if(ret < myLoad) ret = myLoad;
  3967. if(why != null) {
  3968. why.append("<br />\nLoad due to expected outbound transfers: ");
  3969. why.append(nfp.format(myLoad));
  3970. why.append(" because: ");
  3971. why.append(receivedRequestsHour);
  3972. why.append(" req/hr * ");
  3973. why.append(pTransfer);
  3974. why.append("(");
  3975. why.append(((NGRoutingTable)Main.origRT).whyPTransferGivenInboundRequest());
  3976. why.append(") (pTransfer) * ");
  3977. why.append(stdFileSize);
  3978. why.append(" bytes = ");
  3979. why.append((long)bytesExpected);
  3980. why.append(" bytes/hr expected from current requests, but maxOutputBytes/minute = ");
  3981. why.append((long)maxBytesPerMinute);
  3982. why.append(" * 60 = ");
  3983. why.append((long)maxBytes);
  3984. why.append(" bytes/hr target");
  3985. }
  3986. }
  3987. // if(forRateLimiting) {
  3988. // // Propagation
  3989. // double outgoingRequestRate = sentRequestCounter.getExtrapolatedEventsPerHour();
  3990. // double incomingRequestRate = acceptedExternalRequestCounter.getExtrapolatedEventsPerHour();
  3991. // /**
  3992. // * Don't use it until we have received a certain number of requests.
  3993. // * Otherwise fetches on startup will cause MAJOR problems.
  3994. // */
  3995. // if(acceptedExternalRequestCounter.countEvents() > 10) {
  3996. // double myLoad = outgoingRequestRate / incomingRequestRate;
  3997. // if(ret < myLoad) ret = myLoad;
  3998. // if(why != null) {
  3999. // why.append("<br />Load due to propagation = ");
  4000. // why.append(nfp.format(myLoad));
  4001. // why.append(" = ");
  4002. // why.append(outgoingRequestRate);
  4003. // why.append(" / ");
  4004. // why.append(incomingRequestRate);
  4005. // }
  4006. // }
  4007. // }
  4008. //
  4009. // // Backoff load
  4010. // if (forRateLimiting) {
  4011. // double meanLogBackoffLoad = Core.diagnostics.getContinuousValue("logBackoffLoad", Diagnostics.MINUTE, Diagnostics.MEAN_VALUE);
  4012. // if(!(Double.isNaN(meanLogBackoffLoad))) {
  4013. // double estBackoffLoad = Math.exp(meanLogBackoffLoad);
  4014. // if(estBackoffLoad > ret) ret = estBackoffLoad;
  4015. // if(why != null) {
  4016. // why.append("<br />\nLoad due to backoff: ");
  4017. // why.append(nfp.format(estBackoffLoad));
  4018. // why.append(" = e^");
  4019. // why.append(meanLogBackoffLoad);
  4020. // why.append(" (average logBackoffLoad)");
  4021. // }
  4022. // }
  4023. // }
  4024. // Allow >100% load either way
  4025. // if ((!forRateLimiting) && ret > 1.0f) {
  4026. // ret = 1.0f;
  4027. // }
  4028. synchronized(loadSync) {
  4029. now = System.currentTimeMillis();
  4030. if(forRateLimiting) {
  4031. lastEstimatedRateLimitingLoad = (float) ret;
  4032. lastCalculatedRateLimitingLoad = now;
  4033. } else {
  4034. lastEstimatedLoad = (float) ret;
  4035. lastCalculatedEstimatedLoad = now;
  4036. }
  4037. }
  4038. return (float) ret;
  4039. }
  4040. private double calculateLoadForUnit(String name, String units, StringBuffer why,
  4041. double delay, int delayCutoff, int successCutoff,
  4042. boolean forRateLimiting) {
  4043. double load;
  4044. double denom = successCutoff - delayCutoff;
  4045. if(forRateLimiting) {
  4046. load = delay / delayCutoff;
  4047. } else {
  4048. load = overloadLow
  4049. + (1 - overloadLow)
  4050. * (delay - delayCutoff)
  4051. / (denom == 0.0 ? 1.0 : denom);
  4052. }
  4053. if (why != null) {
  4054. why.append("<br />\nLoad due to "+name+" = ");
  4055. why.append(nfp.format(load) + " = ");
  4056. if(forRateLimiting) {
  4057. why.append((int)delay + units + " / " +
  4058. delayCutoff + units);
  4059. why.append(load > overloadLow ? " > " : " <= ");
  4060. why.append("overloadLow (");
  4061. why.append(nfp.format(overloadLow));
  4062. } else {
  4063. why.append(
  4064. nfp.format(overloadLow)
  4065. + " + "
  4066. + nfp.format(1 - overloadLow)
  4067. + " * ("
  4068. + nf3.format(delay)
  4069. + units
  4070. + " - "
  4071. + nf3.format(delayCutoff)
  4072. + units
  4073. + ") / "
  4074. + nf3.format(denom)
  4075. + units);
  4076. }
  4077. why.append(")");
  4078. }
  4079. return load;
  4080. }
  4081. double lastGlobalQuota;
  4082. long lastGlobalQuotaTime;
  4083. Object lastGlobalQuotaSync = new Object();
  4084. /**
  4085. * @return the target total number of queries per hour that the
  4086. * node can handle, based on the current load and traffic levels.
  4087. * If load is zero returns positive infinity.
  4088. */
  4089. public double getGlobalQuota() {
  4090. /** Cache it for 2 reasons:
  4091. * 1. Save CPU usage.
  4092. * 2. Make the averages more or less averages over time, rather than
  4093. * being biased by message send rates.
  4094. */
  4095. synchronized(lastGlobalQuotaSync) {
  4096. if(System.currentTimeMillis() < lastGlobalQuotaTime + 5000)
  4097. return lastGlobalQuota;
  4098. }
  4099. // First calculate the total number of queries received per hour
  4100. // This is a kind of average, necessarily...
  4101. double requestsPerHour = receivedRequestCounter.getExtrapolatedEventsPerHour();
  4102. Core.diagnostics.occurrenceContinuous("estimatedIncomingRequestsPerHour",
  4103. requestsPerHour);
  4104. if(Double.isInfinite(requestsPerHour)) {
  4105. return Double.POSITIVE_INFINITY;
  4106. }
  4107. double load = estimatedLoad(true);
  4108. /** DO NOT average load.
  4109. * Why?
  4110. * If an external stimulus causes a slightly increased load for
  4111. * a while, and traffic starts to fall, and then the external stimulus
  4112. * is taken away, traffic will CONTINUE FALLING for as long as it
  4113. * takes for the load average to come back down to below 1.0.
  4114. */
  4115. Core.diagnostics.occurrenceContinuous("rateLimitingLoad", load);
  4116. // try {
  4117. // loadAverager.report(rawLoad);
  4118. // } catch (IllegalArgumentException e) {
  4119. // logger.log(this, "Caught exception reporting load to load averager",e,
  4120. // Logger.NORMAL);
  4121. // }
  4122. // double load = loadAverager.currentValue();
  4123. // Core.diagnostics.occurrenceContinuous("rateLimitingLoad", load);
  4124. if(load == 0.0) return Double.POSITIVE_INFINITY;
  4125. double ret = requestsPerHour / load;
  4126. Core.diagnostics.occurrenceContinuous("globalQuotaPerHourRaw", ret);
  4127. // Now clip it to the maximum the link can sustain
  4128. double wasGlobalQuota = ret;
  4129. double maxGlobalQuota = getMaxGlobalQuota();
  4130. if(ret > maxGlobalQuota) ret = maxGlobalQuota;
  4131. logger.log(this, "getGlobalQuota(): requests per hour: "+
  4132. requestsPerHour+", load: "+load+
  4133. ", raw globalQuota="+wasGlobalQuota+", maxGlobalQuota="+
  4134. maxGlobalQuota+", unaveraged globalQuota="+ret, Logger.MINOR);
  4135. // Now we DEFINITELY need to average the output
  4136. globalQuotaAverager.report(ret);
  4137. ret = globalQuotaAverager.currentValue();
  4138. Core.diagnostics.occurrenceContinuous("globalQuotaPerHour", ret);
  4139. logger.log(this, "getGlobalQuota() returning "+ret, Logger.MINOR);
  4140. synchronized(lastGlobalQuotaSync) {
  4141. lastGlobalQuota = ret;
  4142. lastGlobalQuotaTime = System.currentTimeMillis();
  4143. }
  4144. return ret;
  4145. }
  4146. /**
  4147. * @return the upper limit on the globalQuota, calculated from
  4148. * the output and input bandwidth limits.
  4149. */
  4150. public double getMaxGlobalQuota() {
  4151. int limit = 0;
  4152. if(outputBandwidthLimit > 0) limit = outputBandwidthLimit;
  4153. if(inputBandwidthLimit > 0 && inputBandwidthLimit < outputBandwidthLimit)
  4154. limit = inputBandwidthLimit;
  4155. if(limit > 0) {
  4156. double pTransfer = ((NGRoutingTable)Main.origRT).pTransferGivenInboundRequest();
  4157. double maxGlobalQuota = (limit * 60 * 60) /
  4158. (calculateStandardFileSize() * pTransfer);
  4159. return maxGlobalQuota;
  4160. }
  4161. return Double.MAX_VALUE;
  4162. }
  4163. private void accept(
  4164. Key searchKey,
  4165. int hopsToLive,
  4166. String diagAddr,
  4167. String verstr) {
  4168. if (inboundRequests != null && diagAddr != null) {
  4169. inboundRequests.incSuccesses(diagAddr);
  4170. }
  4171. acceptedExternalRequestCounter.logEvent();
  4172. }
  4173. private void reject(
  4174. Key searchKey,
  4175. int hopsToLive,
  4176. String diagAddr,
  4177. String verstr) {
  4178. // Do nothing
  4179. }
  4180. private static final int DEFAULT_FILE_SIZE = 350000;
  4181. // typical value 13/3/04
  4182. public static long calculateStandardFileSize(Node node) {
  4183. if (node == null)
  4184. return DEFAULT_FILE_SIZE;
  4185. else return node.calculateStandardFileSize();
  4186. }
  4187. long lastCalculatedStandardFileSizeTime = -1;
  4188. private boolean isRecalculatingStandardFileSize = false;
  4189. long lastStandardFileSize = 0;
  4190. private final Object fileSizeTimestampSync = new Object();
  4191. //Takes a shot on calculating a mean network file size
  4192. //falls back to 128k if insufficent data is available or this NGRT is
  4193. //unable to ask the store (== if this NGRT doesn't know what node it is
  4194. // used in)
  4195. public long calculateStandardFileSize() {
  4196. long now = System.currentTimeMillis();
  4197. //Avoid contention for the lastUpdatedNewNodeStatsLock lock if possible
  4198. if (isRecalculatingStandardFileSize || now - lastCalculatedStandardFileSizeTime < 60*1000)
  4199. return lastStandardFileSize;
  4200. //Then test again, holding the proper lock, just to be _sure_ that we should run
  4201. synchronized(fileSizeTimestampSync){
  4202. if (isRecalculatingStandardFileSize || now - lastCalculatedStandardFileSizeTime < 60*1000)
  4203. return lastStandardFileSize;
  4204. isRecalculatingStandardFileSize = true;
  4205. }
  4206. try{
  4207. long keys = dir.countKeys();
  4208. if (keys > 16) {
  4209. lastStandardFileSize = dir.used() / keys;
  4210. lastCalculatedStandardFileSizeTime = now;
  4211. return lastStandardFileSize;
  4212. } else
  4213. return DEFAULT_FILE_SIZE;
  4214. }finally{
  4215. lastCalculatedStandardFileSizeTime = now;
  4216. isRecalculatingStandardFileSize = false;
  4217. }
  4218. }
  4219. public void logRequest(Key k) {
  4220. receivedRequestCounter.logEvent();
  4221. }
  4222. /**
  4223. * Hook for rate limiting.
  4224. */
  4225. public boolean acceptRequest(
  4226. Key searchKey,
  4227. int hopsToLive,
  4228. Address source,
  4229. String verstr) {
  4230. String diagAddr = null;
  4231. if (inboundRequests != null) {
  4232. if (source != null) {
  4233. diagAddr = source.toString();
  4234. inboundRequests.incTotal(diagAddr);
  4235. inboundRequests.setLastVersion(diagAddr, verstr);
  4236. }
  4237. }
  4238. float load = estimatedLoad(false);
  4239. if ((outboundRequestLimit == null
  4240. || (!outboundRequestLimit.exceeded()))
  4241. && load < overloadLow) {
  4242. accept(searchKey, hopsToLive, diagAddr, verstr);
  4243. return true;
  4244. }
  4245. // Node is loaded
  4246. if (load < overloadHigh) {
  4247. if (searchKey != null
  4248. && ds.contains(searchKey)) {
  4249. accept(searchKey, hopsToLive, diagAddr, verstr);
  4250. return true;
  4251. } else {
  4252. // Give the request another chance
  4253. // 0.0 = (almost) always accept
  4254. // 1.0 = (almost) never accept
  4255. double rankFraction;
  4256. if (Main.origRT instanceof NGRoutingTable &&
  4257. searchKey != null) {
  4258. /** Selective request accept/reject, based on estimate.
  4259. * a.k.a. unobtanium accept.
  4260. *
  4261. * We want to accept the top x% of incoming requests, where
  4262. * x depends on load, by their estimates (lower is better).
  4263. *
  4264. * So we route the request and see what the estimate is for
  4265. * the first node on the list.
  4266. */
  4267. NGRouting routes = (NGRouting) (Main.origRT.route(searchKey, hopsToLive, calculateStandardFileSize(),
  4268. /* searchKey.getExpectedTransmissionLength(), */ //Don't bias the estimate with the size of the key
  4269. false, false, false, false, false));
  4270. if (routes.getNextRoute() == null) {
  4271. // Sh*t happens
  4272. // No currently contactable nodes we could route to
  4273. rankFraction = Math.random();
  4274. logger.log(this, "Initial getNextRoute() call during load calculation returned no estimate, using random value "
  4275. + "for rankFraktion, routes=" + routes, Logger.MINOR);
  4276. } else {
  4277. double estimate = routes.lastEstimatedTime();
  4278. routes.terminateNoDiagnostic();
  4279. rankFraction = getRankFraction(estimate);
  4280. if(logger.shouldLog(Logger.DEBUG, this))
  4281. logger.log(this, "Unobtanium: key=" + searchKey + ", hopsToLive=" + hopsToLive + " -> estimate: " + estimate
  4282. + " -> rank: " + rankFraction, Logger.MINOR);
  4283. }
  4284. } else {
  4285. rankFraction = Math.random();
  4286. }
  4287. // If loadThreshold is higher than load, reject
  4288. // Therefore loadThreshold high = accept more requests
  4289. double loadThreshold =
  4290. overloadLow + (1.0-rankFraction) * (overloadHigh - overloadLow);
  4291. logger.log(
  4292. this,
  4293. "Unobtanium: "
  4294. + (load <= loadThreshold ? "ACCEPTING" : "REJECTING")
  4295. + " load threshold = "
  4296. + loadThreshold
  4297. + ", load="
  4298. + load
  4299. + ", rank="
  4300. + rankFraction,
  4301. Logger.MINOR);
  4302. if (load <= loadThreshold) {
  4303. accept(searchKey, hopsToLive, diagAddr, verstr);
  4304. return true;
  4305. }
  4306. }
  4307. reject(searchKey, hopsToLive, diagAddr, verstr);
  4308. return false;
  4309. }
  4310. // Over overloadHigh, we don't accept ANYTHING
  4311. reject(searchKey, hopsToLive, diagAddr, verstr);
  4312. // Node is overloaded
  4313. return false;
  4314. }
  4315. protected Object selectiveAcceptRankingSync = new Object();
  4316. protected final int SELECTIVE_ACCEPT_REQUESTS = 100;
  4317. protected Comparable[] selectiveAcceptList =
  4318. new Comparable[SELECTIVE_ACCEPT_REQUESTS];
  4319. protected int selectiveAcceptListPosition = 0;
  4320. /**
  4321. * Return the rank of the request by estimate in a list of recent requests
  4322. *
  4323. * @param estimate
  4324. * @return rank between 0.0 and 1.0. 1.0=estimate is higher than any in
  4325. * list. 0.0=estimate is lower than any in list.
  4326. */
  4327. private double getRankFraction(double estimate) {
  4328. return getRankFraction(new Double(estimate));
  4329. }
  4330. private double getRankFraction(Comparable estimate) {
  4331. if (estimate == null) return 0.0;
  4332. int requestsBelow = 0;
  4333. int curLength = 0;
  4334. synchronized (selectiveAcceptRankingSync) {
  4335. // Iterate the list
  4336. // We want to find:
  4337. // A) the number of items in the list
  4338. // B) the number of items with estimates lower than that of the
  4339. // estimate
  4340. for (curLength = 0;
  4341. curLength < SELECTIVE_ACCEPT_REQUESTS;
  4342. curLength++) {
  4343. Comparable cur = selectiveAcceptList[curLength];
  4344. if (cur == null)
  4345. break;
  4346. if (cur.compareTo(estimate) < 0)
  4347. requestsBelow++;
  4348. }
  4349. selectiveAcceptList[selectiveAcceptListPosition] = estimate;
  4350. selectiveAcceptListPosition++;
  4351. selectiveAcceptListPosition %= SELECTIVE_ACCEPT_REQUESTS;
  4352. }
  4353. if (curLength == 0)
  4354. return 0.0;
  4355. return ((double) requestsBelow) / ((double) curLength);
  4356. }
  4357. //=== communications methods
  4358. // ===============================================
  4359. // /**
  4360. // * Returns a connection that messages can be sent on. This saves a little
  4361. // * time as getPeer is only called if a free connection isn't available.
  4362. // *
  4363. // * @param nr
  4364. // * The node to connect to.
  4365. // * @param timeout
  4366. // * The time to allow in connecting.
  4367. // */
  4368. // public ConnectionHandler makeConnection(NodeReference nr, long timeout)
  4369. // throws CommunicationException {
  4370. // Peer p = getPeer(nr);
  4371. // if (p == null)
  4372. // throw new ConnectFailedException(new VoidAddress(), nr.getIdentity(),
  4373. // "Unusable node ref", true);
  4374. // return makeConnection(p, timeout);
  4375. // }
  4376. // public final ConnectionHandler makeConnection(NodeReference nr)
  4377. // throws CommunicationException {
  4378. // return makeConnection(nr, 0);
  4379. // }
  4380. /**
  4381. * Sends a message accross an open or new connection. This saves a little
  4382. * time as getPeer is only called if a free connection isn't available.
  4383. *
  4384. * @param nr
  4385. * The node to connect to.
  4386. * @param m
  4387. * The message to send.
  4388. * @param timeout
  4389. * The time to allow in connecting.
  4390. * @return The trailing field stream (if there is one).
  4391. */
  4392. public final TrailerWriter sendMessage(
  4393. Message m,
  4394. NodeReference nr,
  4395. long timeout)
  4396. throws SendFailedException {
  4397. return connections.sendMessage(
  4398. m,
  4399. nr.getIdentity(),
  4400. nr,
  4401. timeout,
  4402. PeerPacketMessage.NORMAL,
  4403. presentations.getDefault());
  4404. }
  4405. /**
  4406. * Sends a message accross an open or new connection. This saves a little
  4407. * time as getPeer is only called if a free connection isn't available.
  4408. *
  4409. * @param id
  4410. * The node to connect to.
  4411. * @param m
  4412. * The message to send.
  4413. * @param timeout
  4414. * The time to allow in connecting.
  4415. * @return The trailing field stream (if there is one).
  4416. */
  4417. public final TrailerWriter sendMessage(
  4418. Message m,
  4419. Identity id,
  4420. long timeout)
  4421. throws SendFailedException {
  4422. return connections.sendMessage(
  4423. m,
  4424. id,
  4425. null,
  4426. timeout,
  4427. PeerPacketMessage.NORMAL,
  4428. presentations.getDefault());
  4429. }
  4430. /**
  4431. * Send a message, asynchronously
  4432. *
  4433. * @param m
  4434. * the message
  4435. * @param p
  4436. * the peer
  4437. * @param msgPrio
  4438. * the priority of the message, see PeerHandler
  4439. * @param timeout -
  4440. * number of milliseconds after which the send will be dropped.
  4441. * @param cb
  4442. * callback to be called when the message send has completed
  4443. * (successfully or not) - null if no notification is needed.
  4444. */
  4445. public final void sendMessageAsync(
  4446. Message m,
  4447. Peer p,
  4448. int msgPrio,
  4449. long timeout,
  4450. MessageSendCallback cb) {
  4451. connections.sendMessageAsync(
  4452. m,
  4453. p.getIdentity(),
  4454. null,
  4455. cb,
  4456. timeout,
  4457. msgPrio);
  4458. }
  4459. public final void sendMessageAsync(
  4460. Message m,
  4461. Peer p,
  4462. long timeout,
  4463. MessageSendCallback cb) {
  4464. connections.sendMessageAsync(
  4465. m,
  4466. p.getIdentity(),
  4467. null,
  4468. cb,
  4469. timeout,
  4470. PeerPacketMessage.NORMAL);
  4471. }
  4472. public final void sendMessageAsync(
  4473. Message m,
  4474. NodeReference nr,
  4475. long timeout,
  4476. MessageSendCallback cb) {
  4477. connections.sendMessageAsync(
  4478. m,
  4479. nr.getIdentity(),
  4480. nr,
  4481. cb,
  4482. timeout,
  4483. PeerPacketMessage.NORMAL);
  4484. }
  4485. public final void sendMessageAsync(
  4486. Message m,
  4487. Identity id,
  4488. long timeout,
  4489. MessageSendCallback cb) {
  4490. connections.sendMessageAsync(
  4491. m,
  4492. id,
  4493. null,
  4494. cb,
  4495. timeout,
  4496. PeerPacketMessage.NORMAL);
  4497. }
  4498. public final void sendMessageAsync(
  4499. Message m,
  4500. Identity id,
  4501. int msgPrio,
  4502. long timeout,
  4503. MessageSendCallback cb) {
  4504. connections.sendMessageAsync(m, id, null, cb, timeout, msgPrio);
  4505. }
  4506. public final void sendMessageAsync(
  4507. Message m,
  4508. NodeReference nr,
  4509. int prio,
  4510. long timeout,
  4511. MessageSendCallback cb) {
  4512. connections.sendMessageAsync(
  4513. m,
  4514. nr.getIdentity(),
  4515. nr,
  4516. cb,
  4517. timeout,
  4518. prio);
  4519. }
  4520. public final void unsendMessage(Identity i, MessageSendCallback cb) {
  4521. connections.unsendMessage(i, cb);
  4522. }
  4523. /**
  4524. * Change the HTL given slightly, randomly, if it is high enough.
  4525. * Use with care. Specifically, because of the 50% chance of not
  4526. * decrementing the HTL at maxHTL, should NOT be used on individual
  4527. * blocks. Otherwise you get a telltale distribution of HTLs which
  4528. * can distinguish between first hop and second hop (i.e. you get
  4529. * equal numbers on 16,17,18,19,20 on the first hop, on the second
  4530. * hop you get half as many on 20 and 19 but equal numbers on 15-18,
  4531. * on the third hop... etc). So only use this for individual
  4532. * requests.
  4533. * @param htl
  4534. * @return
  4535. */
  4536. public static int perturbHTL(int htl) {
  4537. float f = getRandSource().nextFloat();
  4538. Core.logger.log(Node.class, "Perturbing HTL: htl="+htl, Logger.MINOR);
  4539. if (maxHopsToLive == 0) return htl;
  4540. if (htl > 3 && ((float)htl / (float)maxHopsToLive) > 0.5) {
  4541. if(htl > (maxHopsToLive - 2)) htl = (maxHopsToLive - 2);
  4542. Core.logger.log(Node.class, "HTL now "+htl, Logger.MINOR);
  4543. f = getRandSource().nextFloat();
  4544. if (f < 0.2)
  4545. htl += 2;
  4546. else if (f < 0.4)
  4547. htl += 1;
  4548. else if (f < 0.6)
  4549. htl += 0;
  4550. else if (f < 0.8)
  4551. htl -= 1;
  4552. else
  4553. htl -= 2;
  4554. }
  4555. Core.logger.log(Node.class, "HTL now: "+htl, Logger.MINOR);
  4556. if (htl > maxHopsToLive)
  4557. htl = maxHopsToLive;
  4558. return htl;
  4559. }
  4560. public boolean shouldCache(freenet.message.StoreData sd) {
  4561. if (logger == null)
  4562. throw new NullPointerException();
  4563. if (sd == null) {
  4564. logger.log(
  4565. this,
  4566. "shouldCache returning true because sd == null",
  4567. Logger.DEBUG);
  4568. return true;
  4569. }
  4570. logger.log(
  4571. this,
  4572. "shouldCache(" + (sd == null ? "(null)" : sd.toString()) + ")",
  4573. Logger.DEBUG);
  4574. if (storeSize == 0) {
  4575. logger.log(
  4576. this,
  4577. "shouldCache returning true because " + "storeSize == 0",
  4578. Logger.DEBUG);
  4579. return true;
  4580. }
  4581. long used = dir.used();
  4582. long target = (long) (storeSize * (double) minStoreFullPCache);
  4583. if (used < target) {
  4584. logger.log(
  4585. this,
  4586. "shouldCache returning true because "
  4587. + "used space ("
  4588. + used
  4589. + ") < target ("
  4590. + target
  4591. + ") "
  4592. + "out of maximum "
  4593. + storeSize,
  4594. Logger.DEBUG);
  4595. return true;
  4596. }
  4597. if (sd.shouldCache(getRandSource(), cacheProbPerHop)) {
  4598. logger.log(
  4599. this,
  4600. "shouldCache returning true because "
  4601. + "sd.shouldCache says so for "
  4602. + sd,
  4603. Logger.DEBUG);
  4604. return true;
  4605. } else {
  4606. logger.log(
  4607. this,
  4608. "shouldCache returning false because "
  4609. + "sd.shouldCache says so for "
  4610. + sd,
  4611. Logger.DEBUG);
  4612. return false;
  4613. }
  4614. }
  4615. public boolean shouldReference(
  4616. NodeReference nr,
  4617. freenet.message.StoreData sd) {
  4618. return rt.shouldReference(nr, sd);
  4619. }
  4620. /**
  4621. * Add a reference for a node.
  4622. *
  4623. * @param nr
  4624. * the reference to be added to the routing table
  4625. * @param k
  4626. * the key this resulted from, which may be ignored by the RT
  4627. * @param estimator
  4628. * FieldSet of initial estimator, or null
  4629. */
  4630. public void reference(Key k, Identity id,
  4631. NodeReference nr, FieldSet estimator) {
  4632. boolean logDEBUG = logger.shouldLog(Logger.DEBUG, this);
  4633. if(logDEBUG) logger.log(this, "referencing: "+k+", "+nr+", "+
  4634. estimator, Logger.DEBUG);
  4635. if(id == null) id = nr.getIdentity();
  4636. if(id == null) {
  4637. Core.logger.log(this, "Referencing: "+k+","+id+","+nr+","+estimator,
  4638. new Exception("debug"), Logger.ERROR);
  4639. return;
  4640. }
  4641. rt.reference(k, id, nr, estimator);
  4642. if(logDEBUG) logger.log(this, "adding peer for: "+id+": "+ nr,
  4643. Logger.DEBUG);
  4644. connections.makePeerHandler(id, nr, presentations.getDefault());
  4645. if(logDEBUG) logger.log(this, "scheduling connection open: "+id+
  4646. ": "+nr, Logger.DEBUG);
  4647. connectionOpener.rescheduleNow();
  4648. if(logDEBUG) logger.log(this, "Referenced "+k+": "+nr+": "+
  4649. estimator, Logger.DEBUG);
  4650. }
  4651. /**
  4652. * Create ConnectionOpeners to open connections to all nodes in the RT,
  4653. * called on startup. Also creates PeerHandlers for each.
  4654. */
  4655. public void scheduleOpenAllConnections() {
  4656. logger.log(this, "Scheduling open on all connections", Logger.MINOR);
  4657. RTDiagSnapshot snap =
  4658. rt.getSnapshot(true);
  4659. IdRefPair[] nodes = snap.getIdRefPairs();
  4660. for(int i=0;i<nodes.length;i++)
  4661. connections.makePeerHandler(nodes[i].id, nodes[i].ref,
  4662. presentations.getDefault());
  4663. logger.log(this, "Scheduling open on all "+nodes.length+" connections",
  4664. Logger.MINOR);
  4665. rescheduleConnectionOpener();
  4666. logger.log(this, "Scheduled open on all connections",
  4667. Logger.MINOR);
  4668. }
  4669. public void rescheduleConnectionOpener() {
  4670. if(connectionOpener != null)
  4671. connectionOpener.reschedule();
  4672. }
  4673. public int getMaxPacketLength() {
  4674. if (obw != null)
  4675. return obw.maximumPacketLength();
  4676. else
  4677. return 1492; // fixme
  4678. }
  4679. /**
  4680. * @return
  4681. */
  4682. public int getMaxTrailerChunkSize() {
  4683. if (obw != null) {
  4684. int i = obw.maximumPacketLength();
  4685. i = i / 5;
  4686. /** Impose a minimum:
  4687. * The chunk overhead is 10 bytes
  4688. * Lets say the maximum acceptable overhead is 5%
  4689. * That makes 200 bytes a reasonable minimum.
  4690. */
  4691. if(i < 200) i = 200;
  4692. return i;
  4693. } else {
  4694. return 500;
  4695. }
  4696. }
  4697. long lastReportedRequestInterval = -1;
  4698. public double getBytesSentLastMinute()
  4699. {
  4700. return outputBytesLastMinute.currentSum();
  4701. }
  4702. /**
  4703. * @param success whether the request succeeded
  4704. * @param backedOffCount the number of nodes that were tried and unavailable
  4705. * due to backoff or rate limiting, before we reached a node that eventually
  4706. * sent us a DNF or a transfer.
  4707. */
  4708. public void routingRequestEndedWithBackedOffCount(boolean success, int backedOffCount) {
  4709. if(backedOffCount > rtMaxNodes) backedOffCount = rtMaxNodes;
  4710. if(backedOffCount < 0) backedOffCount = 0;
  4711. synchronized(Node.syncCountsByBackoffCount) {
  4712. if(success)
  4713. Node.successesByBackoffCount[backedOffCount]++;
  4714. else
  4715. Node.failuresByBackoffCount[backedOffCount]++;
  4716. }
  4717. }
  4718. public String routingResultsByBackoffCount() {
  4719. StringBuffer sb = new StringBuffer();
  4720. synchronized(Node.syncCountsByBackoffCount) {
  4721. sb.append("Backoff count Successes Failures\n");
  4722. for(int i=0;i<=rtMaxNodes;i++) {
  4723. long successes = Node.successesByBackoffCount[i];
  4724. long failures = Node.failuresByBackoffCount[i];
  4725. String s1 = Integer.toString(i);
  4726. sb.append(s1);
  4727. for(int j=0;j<20-s1.length();j++) sb.append(' ');
  4728. s1 = Long.toString(successes);
  4729. sb.append(s1);
  4730. for(int j=0;j<20-s1.length();j++) sb.append(' ');
  4731. s1 = Long.toString(failures);
  4732. sb.append(s1);
  4733. for(int j=0;j<20-s1.length();j++) sb.append(' ');
  4734. sb.append(Double.toString(successes/((double)failures+successes)));
  4735. sb.append('\n');
  4736. }
  4737. }
  4738. return sb.toString();
  4739. }
  4740. /**
  4741. * @return
  4742. */
  4743. public double getActualRequestsPerHour() {
  4744. return receivedRequestCounter.getExtrapolatedEventsPerHour();
  4745. }
  4746. /**
  4747. * @return whether we want a single incoming connection, right now.
  4748. */
  4749. public boolean wantIncomingConnection() {
  4750. // Is the last node in the RT newbie?
  4751. return connections.wantUnkeyedReference();
  4752. }
  4753. /**
  4754. * @return the highest seen build number for nodes of the same
  4755. * type as us. Unlike Version, we actually check that more than
  4756. * one node has this :).
  4757. */
  4758. public int getHighestSeenBuild() {
  4759. return connections.getHighestSeenBuild(this);
  4760. }
  4761. public BackgroundInserter newBackgroundInserter(int i, int j, ClientFactory factory, BucketFactory bf2) {
  4762. return new NodeBackgroundInserter(i,j,factory,bf2);
  4763. }
  4764. /**
  4765. * @return true if this particular request should be routed
  4766. * to the newest node first.
  4767. */
  4768. public static boolean shouldRouteByNewness() {
  4769. return (getRandSource().nextInt(20) == 0);
  4770. }
  4771. /**
  4772. * Get a string-format address for a given identity
  4773. * @param origPeer
  4774. * @return
  4775. */
  4776. public String getStringAddress(Identity origPeer) {
  4777. NodeReference ref = rt.getNodeReference(origPeer);
  4778. if(ref == null) return "(null)";
  4779. return ref.firstPhysicalToString();
  4780. }
  4781. static final int PADDING_CHUNK_SIZE = 160;
  4782. /**
  4783. * Pad a packet size up to a reasonable level that minimizes the
  4784. * amount of information given away.
  4785. * For now, lets round to the nearest PADDING_CHUNK_SIZE bytes.
  4786. */
  4787. public static int padPacketSize(int totalLength) {
  4788. if(totalLength % PADDING_CHUNK_SIZE == 0) return totalLength;
  4789. return ((totalLength / PADDING_CHUNK_SIZE) + 1) * PADDING_CHUNK_SIZE;
  4790. }
  4791. public static int minPaddingChunkSize() {
  4792. return PADDING_CHUNK_SIZE;
  4793. }
  4794. public Checkpointed getRateLimitingWriterCheckpoint() {
  4795. return rlwc;
  4796. }
  4797. /**
  4798. * Log a sent request
  4799. */
  4800. public void logOutgoingRequest() {
  4801. sentRequestCounter.logEvent();
  4802. }
  4803. }