libtorrent icon indicating copy to clipboard operation
libtorrent copied to clipboard

Add inbound and outbound tunnels length variance in i2p stream settings.

Open ljfp opened this issue 7 months ago • 4 comments

As discussed here: https://github.com/arvidn/libtorrent/issues/7925 libtorrent is lacking the capibility of adding variance to I2P tunnels. Inbound and outbound tunnel length variance is natively handled by I2P https://geti2p.net/en/docs/protocol/i2cp (see inbound.lengthVariance and outbound.lengthVariance) but we need to set those values when creating the tunnel, otherwise they will default to 0.

To test this with a real I2P router, I made a sample program in C++ that uses my version of libtorrent and creates a I2P session setting the inbound and outbound tunnels variance.

tunnel_configuration_test sam_client_tunnel_config

As you can see in the screenshots, the tunnel is configured with the variance I set using libtorrent and my sample program.

ljfp avatar May 06 '25 14:05 ljfp

Full tcpdump of my I2P router when my sample program requested to create the session:

$ sudo tcpdump -i lo port 7656 -A -s 0 -v
tcpdump: listening on lo, link-type EN10MB (Ethernet), snapshot length 262144 bytes
14:33:22.216126 IP (tos 0x0, ttl 64, id 33658, offset 0, flags [DF], proto TCP (6), length 60)
    localhost.44756 > localhost.7656: Flags [S], cksum 0xfe30 (incorrect -> 0xc7f9), seq 1956950885, win 65495, options [mss 65495,sackOK,TS val 1040274752 ecr 0,nop,wscale 7], length 0
E..<.z@.@..?............t..e.........0.........
>.U@........
14:33:22.216142 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    localhost.7656 > localhost.44756: Flags [S.], cksum 0xfe30 (incorrect -> 0x1ba8), seq 2754835671, ack 1956950886, win 65483, options [mss 65495,sackOK,TS val 1040274752 ecr 1040274752,nop,wscale 7], length 0
E..<..@.@.<..............3t.t..f.....0.........
>.U@>.U@....
14:33:22.216156 IP (tos 0x0, ttl 64, id 33659, offset 0, flags [DF], proto TCP (6), length 52)
    localhost.44756 > localhost.7656: Flags [.], cksum 0xfe28 (incorrect -> 0x4264), ack 1, win 512, options [nop,nop,TS val 1040274752 ecr 1040274752], length 0
E..4.{@[email protected]......(.....
>.U@>.U@
14:33:22.216195 IP (tos 0x0, ttl 64, id 33660, offset 0, flags [DF], proto TCP (6), length 82)
    localhost.44756 > localhost.7656: Flags [P.], cksum 0xfe46 (incorrect -> 0x14f8), seq 1:31, ack 1, win 512, options [nop,nop,TS val 1040274752 ecr 1040274752], length 30
E..R.|@.@..'............t..f.3t......F.....
>.U@>.U@HELLO VERSION MIN=3.1 MAX=3.1

14:33:22.216204 IP (tos 0x0, ttl 64, id 38371, offset 0, flags [DF], proto TCP (6), length 52)
    localhost.7656 > localhost.44756: Flags [.], cksum 0xfe28 (incorrect -> 0x4246), ack 31, win 512, options [nop,nop,TS val 1040274752 ecr 1040274752], length 0
E..4..@[email protected]........(.....
>.U@>.U@
14:33:22.216853 IP (tos 0x0, ttl 64, id 38372, offset 0, flags [DF], proto TCP (6), length 86)
    localhost.7656 > localhost.44756: Flags [P.], cksum 0xfe4a (incorrect -> 0x43fb), seq 1:35, ack 31, win 512, options [nop,nop,TS val 1040274753 ecr 1040274752], length 34
E..V..@[email protected].....
>.UA>.U@HELLO REPLY RESULT=OK VERSION=3.1

14:33:22.216868 IP (tos 0x0, ttl 64, id 33661, offset 0, flags [DF], proto TCP (6), length 52)
    localhost.44756 > localhost.7656: Flags [.], cksum 0xfe28 (incorrect -> 0x4222), ack 35, win 512, options [nop,nop,TS val 1040274753 ecr 1040274753], length 0
E..4.}@[email protected]......(.....
>.UA>.UA
14:33:22.216960 IP (tos 0x0, ttl 64, id 33662, offset 0, flags [DF], proto TCP (6), length 314)
    localhost.44756 > localhost.7656: Flags [P.], cksum 0xff2e (incorrect -> 0x49f1), seq 31:293, ack 35, win 512, options [nop,nop,TS val 1040274753 ecr 1040274753], length 262
E..:.~@.@..=............t....3t............
>.UA>.UASESSION CREATE STYLE=STREAM ID=c0b3696ac7aee92e5d4a784b82c4ca4a988a341a DESTINATION=TRANSIENT SIGNATURE_TYPE=7 i2cp.leaseSetEncType=4,0 inbound.quantity=3 outbound.quantity=3 inbound.length=3 outbound.length=3 inbound.lengthVariance=2 outbound.lengthVariance=-3

14:33:22.258611 IP (tos 0x0, ttl 64, id 38373, offset 0, flags [DF], proto TCP (6), length 52)
    localhost.7656 > localhost.44756: Flags [.], cksum 0xfe28 (incorrect -> 0x40f2), ack 293, win 512, options [nop,nop,TS val 1040274795 ecr 1040274753], length 0
E..4..@[email protected]........(.....
>.Uk>.UA
14:38:23.299341 IP (tos 0x0, ttl 64, id 38374, offset 0, flags [DF], proto TCP (6), length 303)
    localhost.7656 > localhost.44756: Flags [P.], cksum 0xff23 (incorrect -> 0x9f04), seq 35:286, ack 293, win 512, options [nop,nop,TS val 1040575835 ecr 1040274753], length 251
E../..@[email protected]........#.....
>..[>.UASESSION STATUS RESULT=I2P_ERROR MESSAGE="Error creating I2PSocketManager: [SAM TCP Client #980(GOTDATE)]: Failed to build tunnels - No tunnels built after waiting 5 minutes. Your network connection may be down, or there is severe network congestion."

14:38:23.300207 IP (tos 0x0, ttl 64, id 8125, offset 0, flags [DF], proto TCP (6), length 60)
    localhost.45840 > localhost.7656: Flags [S], cksum 0xfe30 (incorrect -> 0xe94d), seq 2799682425, win 65495, options [mss 65495,sackOK,TS val 1040575836 ecr 0,nop,wscale 7], length 0
E..<..@[email protected].........
>..\........
14:38:23.300225 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
    localhost.7656 > localhost.45840: Flags [S.], cksum 0xfe30 (incorrect -> 0x7d61), seq 87898952, ack 2799682426, win 65483, options [mss 65495,sackOK,TS val 1040575836 ecr 1040575836,nop,wscale 7], length 0
E..<..@.@.<..............=;H...z.....0.........
>..\>..\....
14:38:23.300243 IP (tos 0x0, ttl 64, id 8126, offset 0, flags [DF], proto TCP (6), length 52)
    localhost.45840 > localhost.7656: Flags [.], cksum 0xfe28 (incorrect -> 0xa41d), ack 1, win 512, options [nop,nop,TS val 1040575836 ecr 1040575836], length 0
E..4..@[email protected].=;I.....(.....
>..\>..\
14:38:23.300278 IP (tos 0x0, ttl 64, id 8127, offset 0, flags [DF], proto TCP (6), length 82)
    localhost.45840 > localhost.7656: Flags [P.], cksum 0xfe46 (incorrect -> 0x76b1), seq 1:31, ack 1, win 512, options [nop,nop,TS val 1040575836 ecr 1040575836], length 30
E..R..@[email protected].=;I.....F.....
>..\>..\HELLO VERSION MIN=3.1 MAX=3.1

14:38:23.300287 IP (tos 0x0, ttl 64, id 48331, offset 0, flags [DF], proto TCP (6), length 52)
    localhost.7656 > localhost.45840: Flags [.], cksum 0xfe28 (incorrect -> 0xa3ff), ack 31, win 512, options [nop,nop,TS val 1040575836 ecr 1040575836], length 0
E..4..@.@................=;I.........(.....
>..\>..\
14:38:23.300921 IP (tos 0x0, ttl 64, id 48332, offset 0, flags [DF], proto TCP (6), length 86)
    localhost.7656 > localhost.45840: Flags [P.], cksum 0xfe4a (incorrect -> 0xa5b4), seq 1:35, ack 31, win 512, options [nop,nop,TS val 1040575837 ecr 1040575836], length 34
E..V..@.@................=;I.........J.....
>..]>..\HELLO REPLY RESULT=OK VERSION=3.1

14:38:23.300937 IP (tos 0x0, ttl 64, id 8128, offset 0, flags [DF], proto TCP (6), length 52)
    localhost.45840 > localhost.7656: Flags [.], cksum 0xfe28 (incorrect -> 0xa3db), ack 35, win 512, options [nop,nop,TS val 1040575837 ecr 1040575837], length 0
E..4..@.@....................=;k.....(.....
>..]>..]
14:38:23.301057 IP (tos 0x0, ttl 64, id 8129, offset 0, flags [DF], proto TCP (6), length 110)
    localhost.45840 > localhost.7656: Flags [P.], cksum 0xfe62 (incorrect -> 0x4802), seq 31:89, ack 35, win 512, options [nop,nop,TS val 1040575837 ecr 1040575837], length 58
E..n..@.@....................=;k.....b.....
>..]>..]STREAM ACCEPT ID=c0b3696ac7aee92e5d4a784b82c4ca4a988a341a

Relevant parts are:

SESSION CREATE STYLE=STREAM ID=a2820623e0946476dad2e0caa8f6f1e1495dc1e7 DESTINATION=TRANSIENT SIGNATURE_TYPE=7 i2cp.leaseSetEncType=4,0 inbound.quantity=3 outbound.quantity=3 inbound.length=3 outbound.length=3 inbound.lengthVariance=2 outbound.lengthVariance=-3

where you can see that the parameters were successfully included in the SESSION CREATE command.

And also

SESSION STATUS RESULT=OK

where you can see that the session was successfully instantiated.

ljfp avatar May 06 '25 15:05 ljfp

Oh, I almost forget to include the sample program I used to test this:

test_i2p_variance.cpp

#include <iostream>
#include <libtorrent/session.hpp>
#include <libtorrent/settings_pack.hpp>

int main()
{
    lt::settings_pack pack;
    pack.set_str(lt::settings_pack::i2p_hostname, "127.0.0.1");
    pack.set_int(lt::settings_pack::i2p_port, 7656);

    pack.set_int(lt::settings_pack::i2p_inbound_length_variance, 2);
    pack.set_int(lt::settings_pack::i2p_outbound_length_variance, -3);

    lt::session ses(pack);
    lt::settings_pack current = ses.get_settings();

    std::cout << "I2P settings in created session:\n";
    std::cout << "  i2p_inbound_length_variance: "
              << current.get_int(lt::settings_pack::i2p_inbound_length_variance) << "\n";
    std::cout << "  i2p_outbound_length_variance: "
              << current.get_int(lt::settings_pack::i2p_outbound_length_variance) << "\n";
    std::cout << "\nPress Enter to exit...\n";
    std::cin.get();

    return 0;
}

ljfp avatar May 06 '25 15:05 ljfp

@arvidn I've moved the new settings to the end of the enum to avoid breaking the ABI. I've also added a new entry to the Changelog.

ljfp avatar May 12 '25 18:05 ljfp

@arvidn anything else I should address?

ljfp avatar Jun 02 '25 18:06 ljfp

sorry for the delay

arvidn avatar Jun 28 '25 14:06 arvidn