Skip to content

Default batch size incompatibility between zenoh and zenoh-pico during handshake (TCP unicast) #1078

@lakshjaisinghani

Description

@lakshjaisinghani

Describe the bug

While testing the zenoh-pico subscriber demo (z_sub.c) with thezenoh publisher example (z_pub.rs) with TCP unicast, I encountered an issue where zenoh-pico resets the TCP connection during the handshake due to incompatible batch sizes even though the default batch size should have been the same as default configs were used.

Currently, zenoh-pico rejects the connection rather than negotiates the batch size. Is this intended behavior?

According to the documentation:
Batch Size - It indicates the maximum size of a batch the sender of the INIT message is willing to accept when reading from the network.

To reproduce

Steps

  1. Build zenoh-pico in debug mode and run the z_sub example using tcp unicast only.
./build/examples/z_sub -m peer -l tcp/localhost:7447
  1. Run the z_pub.rs from zenoh. Use tcp unicast in a config.
# example config
{
  mode: "peer",

  /// Connect to specific endpoint
  connect: {
    endpoints: [
      "tcp/localhost:7447"
    ],
  },
}
cargo run --example z_pub -- -c <path-to-config>
  1. Check debug logs from zenoh-pico subscriber. You should see:
...
[2025-10-31T16:43:54Z DEBUG ::_z_unicast_handshake_listen] Received Z_INIT(Syn)
[2025-10-31T16:43:54Z INFO ::_zp_unicast_accept_task] Connection accept handshake failed with error -101

Root cause

I added more debug statements to src/transport/unicast/transport.c and ran the subscriber again.

[2025-10-31T16:21:06Z INFO ::_z_unicast_handshake_listen] Comparing capabilities - Zenoh (rust) vs Zenoh Pico:
[2025-10-31T16:21:06Z INFO ::_z_unicast_handshake_listen]   seq_num_res: 2 vs 2
[2025-10-31T16:21:06Z INFO ::_z_unicast_handshake_listen]   req_id_res: 2 vs 2
[2025-10-31T16:21:06Z INFO ::_z_unicast_handshake_listen]   batch_size: 65480 vs 65535
[2025-10-31T16:21:06Z INFO ::_zp_unicast_accept_task] Connection accept handshake failed with error -101

Even though zenoh has 65535 set as the default batch size, it declares its batch size as 65480 during the handshake. I'm assuming this is an overhead adjustment for TCP/IP headers (55 bytes).

src/transport/unicast/transport.c checks whether the remote node has sufficient capabilities and returns an error if not:

if ((tmsg._body._init._seq_num_res < iam._body._init._seq_num_res) ||
    (tmsg._body._init._req_id_res < iam._body._init._req_id_res) ||
    (tmsg._body._init._batch_size < iam._body._init._batch_size)) {
    _z_t_msg_clear(&tmsg);
    _Z_ERROR_RETURN(_Z_ERR_TRANSPORT_OPEN_SN_RESOLUTION);
}

Should zenoh-pico negotiate down to the lower batch size instead of rejecting the connection?

System info

  • Platform: Ubuntu 22.04
  • Zenoh version: 1.6.2

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions