Skip to content

adding datagram and i2cp options to SessionOptions#11

Merged
altonen merged 8 commits intoeepnet:masterfrom
sjlgasnier:master
Jul 26, 2025
Merged

adding datagram and i2cp options to SessionOptions#11
altonen merged 8 commits intoeepnet:masterfrom
sjlgasnier:master

Conversation

@sjlgasnier
Copy link
Contributor

An humble proposal to resolve issue #10, adding as a bonus (most of the) i2cp options alongside the datagram ones, in case the former become needed in the future.

Copy link
Member

@altonen altonen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR!

src/options.rs Outdated
/// IP address where the datagram socket should be bound to
///
/// Defaults to `0`.
pub datagram_host: u128,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be String and it should default to 127.0.0.1

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, datagram_host and datagram_port can be removed, they're automatically configured.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aren't datagram_host and datagram_port needed for the two methods of #9 ? Unless they are also automatically configured at the datagram message level ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

datagram_host and datagram_port specify the address of the client's socket and they're sent in SESSION CREATE message to the router so it can relay datagrams received from the network to the client.

DatagramOptions should only have the following flags:

[FROM_PORT=nnn]                      # SAM 3.2 or higher only, default 0
[TO_PORT=nnn]                        # SAM 3.2 or higher only, default 0
[PROTOCOL=nnn]                       # SAM 3.2 or higher only, only for RAW sessions, default 18
[SEND_TAGS=nnn]                      # SAM 3.3 or higher only, number of session tags to send
                                     # Overrides crypto.tagsToSend I2CP session option
                                     # Default is router-dependent (40 for Java router)
[TAG_THRESHOLD=nnn]                  # SAM 3.3 or higher only, low session tag threshold
                                     # Overrides crypto.lowTagThreshold I2CP session option
                                     # Default is router-dependent (30 for Java router)
[EXPIRES=nnn]                        # SAM 3.3 or higher only, expiration from now in seconds
                                     # Overrides clientMessageTimeout I2CP session option (which is in ms)
                                     # Default is router-dependent (60 for Java router)
[SEND_LEASESET={true,false}]         # SAM 3.3 or higher only, whether to send our leaseset
                                     # Overrides shouldBundleReplyInfo I2CP session option
                                     # Default is true

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops sorry I misread the docs indeed. Will delete.

src/options.rs Outdated
///
/// Defaults to `2`.
pub num_outbound: usize,
pub inbound_qty: usize,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub inbound_qty: usize,
pub inbound_quantity: usize,

src/options.rs Outdated
/// How many outbound tunnels does the tunnel pool of the session have.
///
/// Defaults to `2`.
pub outbound_qty: usize,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
pub outbound_qty: usize,
pub outbound_quantity: usize,

src/options.rs Outdated
/// Outbound-only sessions (clients) shouldn't be published whereas servers (accepting inbound
/// connections) need to be published.
///
///
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
///
///

src/options.rs Outdated
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct OtherI2CPOptions {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To remain consistent with the current code style, add line breaks between the options

match &self.options.destination {
DestinationKind::Transient => {
command += "DESTINATION=TRANSIENT ";
"RAW" => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't look like DESTINATION is specified for RAW. Could you please reduce code duplication between the three protocol kinds? It should match after parameters.options have been handled and only add FROM_PORT, TO_PORT, PROTOCOL and HEADER if the style indicates datagrams. Otherwise the different styles should be able to use the same code

@sjlgasnier
Copy link
Contributor Author

sjlgasnier commented Jul 19, 2025

I added two methods in datagram.rs that I believe will solve #9
EDIT: that will actually be implemented properly in a subsequent PR

I also deleted the fastreceive option after reading this exchange : eepnet/emissary#28

@sjlgasnier
Copy link
Contributor Author

sjlgasnier commented Jul 19, 2025

I believe the signature type datagram option should be added as well, as new post-quantum crypto types should eventually be approved, numbered from 12 to 20 as per proposal 169 : https://geti2p.net/spec/proposals/169-pq-crypto#signatures

.map_err(From::from)
}

pub(crate) async fn _send_to_with_options(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is to have a public function for Session<Repliable>/Session<Anonymous> like:

#[derive(Default)]
struct DatagramOptions {
    from_port: u16,
    to_port: u16,
}

impl Session<Repliable> {
    pub async fn send_to_with_options(
        &mut self,
        buf: &[u8],
        destination: &str,
        options: DatagramOptions,
    ) -> crate::Result<()> {
        style::Repliable::send_to_with_options(&mut self.context, buf, destination, options).await
    }
}

and the style::Repliable::send_to_with_options() would then fill FROM_PORT/TO_PORT from DatagramOptions. This allows overriding the source/destination port specified in SESSION CREATE message.

These functions must be available on both synchronous and asynchronous APIs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I see, I will rollback these for now and will submit another PR afterwards.

Comment on lines +104 to +124
let socket = UdpSocket::bind(format!("127.0.0.1:{}", options.datagram_port)).await?;
let socket = UdpSocket::bind(format!("127.0.0.1:{}", 0u16)).await?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My mistake, sorry. Please revert this change and keep datagram_port in SessionOptions. I forgot that the port for datagrams is taken from the config

src/options.rs Outdated
Comment on lines +204 to +207
/// (ms) Idle time required
///
/// Defaults to '1800000' ms (i.e. 30 minutes)
pub close_idle_time: usize,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// (ms) Idle time required
///
/// Defaults to '1800000' ms (i.e. 30 minutes)
pub close_idle_time: usize,
/// Idle time required
///
/// Defaults to 30 minutes.
pub close_idle_time: Duration,

Copy link
Member

@altonen altonen Jul 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the comment correct? It's the same for both close_idle_time and reduce_idle_time

src/options.rs Outdated
Comment on lines +253 to +256
/// (ms) Idle time required
///
/// Defaults to '1200000' ms (i.e. 20 minutes)
pub reduce_idle_time: usize,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// (ms) Idle time required
///
/// Defaults to '1200000' ms (i.e. 20 minutes)
pub reduce_idle_time: usize,
/// Idle time required
///
/// Defaults to 20 minutes
pub reduce_idle_time: Duration,

src/options.rs Outdated
Comment on lines +297 to +300
crypto_low_tag_threshold: str::parse::<usize>("30").unwrap(),
crypto_ratchet_inbound_tags: str::parse::<usize>("160").unwrap(),
crypto_ratchet_outbound_tags: str::parse::<usize>("160").unwrap(),
crypto_tags_to_send: str::parse::<usize>("40").unwrap(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these str::parse()ed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was a bit tired aha. Fixed it.

src/options.rs Outdated
outbound_random_key: None,
should_bundle_reply_info: true,
close_on_idle: false,
close_idle_time: str::parse::<usize>("1800000").unwrap(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
close_idle_time: str::parse::<usize>("1800000").unwrap(),
close_idle_time: Duration::from_millis(1800000),

src/options.rs Outdated
lease_set_secret: None,
lease_set_signing_private_key: None,
reduce_on_idle: false,
reduce_idle_time: str::parse::<usize>("1200000").unwrap(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
reduce_idle_time: str::parse::<usize>("1200000").unwrap(),
reduce_idle_time: Duration::from_millis(1200000),

if !self.options.publish {
match parameters.style.as_str() {
"PRIMARY" => {}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove these line breaks between the styles


"DATAGRAM" => {
command += format!(
"FROM_PORT={} TO_PORT={}",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"FROM_PORT={} TO_PORT={}",
"FROM_PORT={} TO_PORT={} ",

Whitespace needed at the end so the command is valid


"RAW" => {
command += format!(
"FROM_PORT={} TO_PORT={} PROTOCOL={} HEADER={}",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ditto

@sjlgasnier
Copy link
Contributor Author

sjlgasnier commented Jul 26, 2025

I would open a PR in emissary to align with the renaming of num_inbound/outbound to inbound/outbound.quantity in yosemite. Very light refactoring.

@altonen
Copy link
Member

altonen commented Jul 26, 2025

I need to cut a new release for yosemite in order for emissary to use these changes and I would like to include both this PR and #9 for the next release. Feel free to make a PR if you want, it should be quite doable as Stream::connect_with_options can be used as an example.

@sjlgasnier
Copy link
Contributor Author

Ah so you mean merging this PR will not automatically cause compatibility issues with emissary-cli>tunnel>client.rs for example ?
If so I will first tackle #9 then wait for the new yosemite release to adapt emissary (?)

Copy link
Member

@altonen altonen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some nits so that documentation looks consistent, otherwise LGTM

src/options.rs Outdated

/// Signature type.
///
/// Default to '7' i.e. EdDSA_SHA512_Ed25519
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Default to '7' i.e. EdDSA_SHA512_Ed25519
/// Default to `7`, i.e., EdDSA-SHA512-Ed25519

src/options.rs Outdated

/// If incoming zero hop tunnel is allowed
///
/// Defaults to 'false'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Defaults to 'false'
/// Defaults to `false`.

src/options.rs Outdated
pub inbound_quantity: usize,

/// How many outbound tunnels does the tunnel pool of the session have.
/// Number of redundant fail-over for tunnels in
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is missing something? It's a half a sentence

Copy link
Contributor Author

@sjlgasnier sjlgasnier Jul 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is how it is described in the I2CP doc. I will rewrite as /// Number of redundant fail-over for inbound tunnels.

Copy link
Member

@altonen altonen Jul 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, sounds weird though. Maybe "Number of redundant, fail-over inbound tunnels" + same for the outbound case

src/options.rs Outdated
Comment on lines +156 to +160
/// Number of IP bytes to match to determine if two routers should not be in the same tunnel. 0
/// to disable.
///
/// Defaults to `0`.
pub inbound_ip_restriction: usize,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Number of IP bytes to match to determine if two routers should not be in the same tunnel. 0
/// to disable.
///
/// Defaults to `0`.
pub inbound_ip_restriction: usize,
/// Number of IP bytes to match to determine if two routers should not be in the same tunnel.
///
/// Defaults to `None`.
pub inbound_ip_restriction: Option<std::num::NonZeroUsize>,

src/options.rs Outdated

/// If outgoing zero hop tunnel is allowed
///
/// Defaults to 'false'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Defaults to 'false'
/// Defaults to `false`.

src/options.rs Outdated

/// Close I2P session when idle
///
/// Defaults to 'false'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Defaults to 'false'
/// Defaults to `false`.

src/options.rs Outdated
Comment on lines +225 to +228
/// (ms) Idle time required before closing session
///
/// Defaults to '1800000' ms (i.e. 30 minutes)
pub close_idle_time: Duration,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// (ms) Idle time required before closing session
///
/// Defaults to '1800000' ms (i.e. 30 minutes)
pub close_idle_time: Duration,
/// Idle time required before closing session
///
/// Defaults to 30 minutes.
pub close_idle_time: Duration,

src/options.rs Outdated

/// The encryption type to be used.
///
/// Defaults to '4' i.e. ECIES-X25519
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Defaults to '4' i.e. ECIES-X25519
/// Defaults to `4`, i.e., ECIES-X25519.

src/options.rs Outdated

/// Reduce tunnel quantity when idle
///
/// Defaults to 'false'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Defaults to 'false'
/// Defaults to `false`.

src/options.rs Outdated
Comment on lines +274 to +277
/// (ms) Idle time required before reducing tunnel quantity
///
/// Defaults to '1200000' ms (i.e. 20 minutes)
pub reduce_idle_time: Duration,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// (ms) Idle time required before reducing tunnel quantity
///
/// Defaults to '1200000' ms (i.e. 20 minutes)
pub reduce_idle_time: Duration,
/// Idle time required before reducing tunnel quantity
///
/// Defaults to 20 minutes.
pub reduce_idle_time: Duration,

@sjlgasnier
Copy link
Contributor Author

Fixed the nits, noticed I had missed a lease set option, and then tried to reorder the options in a somewhat logical order.

@sjlgasnier
Copy link
Contributor Author

sjlgasnier commented Jul 26, 2025

Should I define outbound/inbound_len as std::num::NonZeroUsize for optimization (emissary does not support 0-hop tunnels) ?

@altonen
Copy link
Member

altonen commented Jul 26, 2025

Should I define outbound/inbound_len as std::num::NonZeroUsize for optimization (emissary does not support 0-hop tunnels) ?

yosemite can be used with java/i2pd which support zero-hop tunnels and emissary should eventually support them as well so no need

@altonen altonen merged commit 77357d2 into eepnet:master Jul 26, 2025
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants