I2Speed

From I2P Wiki
Jump to navigation Jump to search
Warning: The main site (http://i2speed.i2p) has been down since early 2022[1] and the last version (1.5.0 on Postman's tracker[2]) may be too old for the current I2P network (Java I2P is 2.4.0 at the time of this warning). Continue with caution.

On I2Speed we are offering background, hints and code for a better i2p experience, aiming at all levels of users from beginner to developer.

Background

Anybody who wants to upload/download stuff faster using I2P should consider the facts given here.

Basically for any data transfer your local application uses tunnels to remote peers. Two parallel connections to the same peer will use the same tunnel, share the bandwidth and slow down transfers by a factor of two. This is why it is a bad idea to post multiple similar torrents at the same time. They will attract the same set of leechers with all tunnels shared between all torrents. Some applications like MuWire also load tremendous amounts of overhead onto their tunnels (currently 1 GB in/out per day for an idle instance).

So users requested applications to use multiple tunnels, in order to at least get unused tunnels for additional connections. First the devs increased the max number of tunnels, only to drop back to use them "as needed". Background for this is that I2P selects random tunnels for new connections instead of unused ones. This is why high tunnel quantities were demanded just to increase the probability of getting unused tunnels. I2Speed corrects this, handing out fresh tunnels when possible and distributing connections evenly over tunnels. Although tunnels are expensive to build, today there are lots of unused ones on the live net, just because they were configured, but not randomly selected.

Furthermore, tunnels are built using a set of known fast peers, for which I2Speed raises the limit from 50 to 100, but actually the peers qualified as fast always range in the 50 area. If you build lots of tunnels, they will all share those fast peers that in turn will probably be selected too by other I2P users. Running two or more I2p routers in parallel, distributing your local tunnels, will definitely help a bit.

On the lowest level then there is the actual transmission over the wire. Here I2Speed allows much faster transfer speeds especially when using UDP, but you still depend on the speed of the other hops in your tunnels.

FAQ

How compatible is I2Speed? 100%. There is no change to cryptography or communication protocols. You can always revert by installing the i2pupdate.zip from the stock I2P distribution.

Is I2Speed safe? 100%. You do not need to download any prebuilt stuff. Our full source as well as a commented diff is on MuWire for review or to build yourself.

Starting is so slow! After changing versions I2P might generate a new router identity. See event log. Will take 48 hours to fully integrate into the network. If it stays idle for minutes, try a restart.

Do you stay current? Absolutely. We have been backporting our improvements to I2P for years and will update within days after new I2P source comes out.

When will your improvements appear in the I2P standard release? We do not know. Some issues adressed by us were first discussed by a guy called zab (the MuWire dev) years ago and no skillful dev cared. Especially our UDP stuff is a major overhaul, very diffent from changing some statics there as they did in the last releases. We hope some I2P dev comes around and also sees value in our work. Steal our code!

What about GraalVM? We consider this an exciting technology, but it offers no direct benefit for I2P. We install it for occasional use of JVisualVM (easier to use but not as functional as the tools included with the JDK). If you use a lot of Java apps it saves you repeatedly typing: "-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler"

What are your minimum requirements? We build for Java 11+ because of better memory management, performance enhancements, Graal JIT (if you run 64 bit) and default G1 GC. You may build for Android or Java 8 by downgrading the Java version in "build.properties". Do not try to build and run for single core ARM.

What do I lose? Actually, not much. We took full stats and message time-stamping out of the UDP transport. These rarely used debug functions themselves do not eat much CPU when not debugging, but cause endless calls to the system clock. Debug logging is unchanged wherever possible.

What is "rtr:" ? Wow, you are debugging our stuff. "rtr:" is the number of messages currently being retransmitted to this peer. Easier to see if you go to /peers, last item in the CWND column.

TCP or UDP? You will always need some dozen UDP connections for reliable address detection and network integration. Shutting off the NTCP transport takes some burden off the network, but can cost you up to one third of throughput. Even with I2Speed processing a message over UDP takes a bit more CPU (but will use less on the entire path to the final destination including your internet gateway). That said there is a reason why I2P defaults to less TCP than UDP connections. Many internet routers bog down under a high number of TCP connections (well below listed specs). We have seen packet loss and heat problems due to a high number of TCP connections through consumer grade equipment.

Do you provide enhancements for Snark? Snark benefits from any improvement to router functions. In our view Snark is a leeching tool that works for that purpose most of the time. We prefer BiglyBT. It supports everything people have demanded from Snark in discussions over the last years.

Technical Overview

This is a high-level overview of our work, detailed descriptions for interested devs to follow.

  • Math libraries on the Mac were built using latest GMP 6.1.2 and latest Apple compilers. Support for Skylake and Nehalem architectures added. 32-bit support and debug stuff stripped from all Mac components.
  • Pre-generation of random numbers and crypto keys is now evenly distributed over time. Now it is made sure that buffers do not run dry under high load, delaying packets by on-the-fly generation. Makes processing of local traffic 25% faster under high load. There even is an auto-turbo mode geared towards massively parallel ARM-boards.
  • Numerous smaller tweaks to the NTCP transport to cut out some ms latency.
  • Several improvements to the multi-threaded design. Threads along with context switches eliminated where easily possible. Different approaches for different platforms. Thread count scales to platform, processor count and type. Threads wait more than 50% less idle on the run queue (Linux).
  • UDP send strategy employs parallel resends and a very fastly tuned send window, aimed at minimizing message loss on failing connections. Tolerates high levels of packet loss (limit 5% for fast connections, more when slower). Helps with WiFi and when running high bandwidth. Top speeds averaging > 200 KBps (single connection) outperforming TCP.
  • excessive locking resolved within the UDP transport, cutting down noticably on CPU.
  • resolved high frequency of iterations over UDP messages in transit. During lifetime the average message is visited < 10 times versus > 1,000 times before. Clear CPU reduction.
  • Once a message gets in over UDP it is reliably ACKed twice. Saves 1% inbound bandwidth by bringing the duplicates received down to near zero. The real winner here is the avoidance of connection stalls on the remote end.
  • High frequency of calls to the system clock eliminated. Clear CPU reduction.
  • Chooses among twice as many network peers when building tunnels. Useful if you run 100s of local tunnels as we do.
  • Lossless compression for graphics cutting down 28% average on memory usage.

What makes I2Speed WiFi-friendly?

As you may already know, I2P uses two transports, NTCP and SSU, that rely on the internet protocols TCP and UDP respectively. TCP is designed to handle packet loss transparently to the application developer, for UDP this is left to the application itself. I2P models UDP data transmission after TCP since the beginning.

Here we get into trouble when we or someone else routing our tunnels runs on a WiFi network. In WiFi networks packet loss is a frequent condition, ranging from 2% upward to really high numbers on crowded networks. However TCP was designed for fixed networks and takes packet loss as a sign of "network congestion", reducing transfer speeds and retransmitting data. Decades of work have gone into "TCP congestion control", but the underlying assumption of a fixed network now turned partially false.

Lots of academic research have gone into make TCP more compatible with WiFi, but a switch to a new TCP will be more painful than introducing IPv6, if it ever will happen. Protocols like HTSP today drop less important data when their TCP connection is getting slower, which is no option for I2P. I2Speed uses a non-aggressive approach to transmit UDP data in parallel even if there is some packet loss, drastically increasing transfer speed. It is even possible to run a router with TCP completely disabled without noticing any difference.

You as a user benefit even when connected to a fixed network because your I2P peers may sit on WiFi. Since I2P uses "introducers" over UDP in firewalled scenarios and handles most traffic over UDP during the first hours after startup, roaming users on WiFi-laptops will see the highest benefit. Of course I2Speed is 100% compatible with the existing I2P installations and I2P peers.

Also I2Speed will do a good job pumping UDP data through overloaded network equipment, which you should notice as an improvement. However do not overload your own internet gateway! Things will go worse otherwise.

So give us a try: http://i2speed.i2p/i2pupdate.zip

Something to watch out for: we used a quick hack to the CWND column on /peers. First item is current send window normalized to 1,000 ms, second item current messages in transit (unchanged), third item messages waiting on the outbound queue, fourth column messages currently being retransmitted.

External links

References