Skip to content

fix(cooperation): give tunnel streams collision-free ids - #807

Merged
re2zero merged 1 commit into
linuxdeepin:masterfrom
re2zero:pms396845/04-stream-ids-v2
Oct 22, 2026
Merged

re2zero merged 1 commit into
linuxdeepin:masterfrom
re2zero:pms396845/04-stream-ids-v2

Conversation

@re2zero

@re2zero re2zero commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Part 4/8 of the reverse tunnel stack (recovery of #800).

This reapplies the reviewed commit on top of the corrected stack because #800 was accidentally merged into its stacked base branch instead of master.

Merge order: #805 → #806 → #807 → #808 → #809 → #810 → #811.
Retargeted to master after #806 merged.

Both peers allocate ids for the streams they initiate, but the ids share
one namespace. Starting both counters at 1 made the barrier stream and a
reverse file transfer collide: the peer rejected the second OPEN as a
duplicate stream, so the transfer never established and stayed at 1%.

Pick a random non-zero id and skip ids already in use locally.

Log: give tunnel streams collision-free ids
PMS: TASK-396845
Influence: concurrent barrier and file-transfer streams no longer collide.

Summary by Sourcery

Ensure concurrently initiated tunnel streams use collision-free IDs so reverse transfers and barrier connections can coexist.

Bug Fixes:

  • Prevent concurrently initiated reverse-tunnel streams from being rejected due to duplicate stream IDs.

Enhancements:

  • Allocate non-zero stream IDs randomly while avoiding IDs already in use locally.

Tests:

  • Add coverage for both peers initiating overlapping streams and verify that both connections remain functional.

@sourcery-ai

sourcery-ai Bot commented Oct 21, 2026

Copy link
Copy Markdown

Reviewer's Guide

The PR eliminates reverse-tunnel stream ID collisions by assigning each locally initiated stream a random non-zero ID that is checked against active local streams, and adds an end-to-end test proving both peers can open concurrent streams without disrupting one another.

Sequence diagram for collision-free concurrent tunnel streams

sequenceDiagram
    participant PeerA
    participant PeerB
    participant ManagerA as TunnelManagerA
    participant ManagerB as TunnelManagerB
    participant Barrier as BarrierStream
    participant Transfer as ReverseFileTransfer

    PeerA->>ManagerA: acceptLocalConnection(serviceId)
    ManagerA->>ManagerA: nextStreamId()
    ManagerA->>ManagerA: QRandomGenerator.generate()
    ManagerA->>Barrier: createStream(non-zero unused id)
    Barrier->>PeerB: OPEN(id)

    PeerB->>ManagerB: acceptLocalConnection(serviceId)
    ManagerB->>ManagerB: nextStreamId()
    ManagerB->>ManagerB: QRandomGenerator.generate()
    ManagerB->>Transfer: createStream(non-zero unused id)
    Transfer->>PeerA: OPEN(id)

    PeerB-->>ManagerB: Find barrier stream by id
    PeerA-->>ManagerA: Find transfer stream by id
    Note over ManagerA,ManagerB: Distinct ids allow both streams to establish concurrently
Loading

File-Level Changes

Change Details Files
Replace per-peer sequential stream IDs with randomized, locally collision-checked IDs.
  • Generate non-zero 32-bit IDs using QRandomGenerator.
  • Retry until the candidate is absent from the manager’s active stream map.
  • Remove the old wrapping counter and route local stream creation through the new allocator.
src/lib/common/manager/tunnelmanager.cpp
src/lib/common/manager/tunnelmanager.h
Add an integration test covering simultaneous stream initiation from both peers.
  • Create two connected tunnel managers with independent echo services.
  • Open and verify a barrier stream, then a concurrent transfer stream initiated by the opposite peer.
  • Verify the original stream remains usable after the second stream opens.
  • Use a timed polling helper to avoid silent test passes on asynchronous timeouts.
tests/manager/tunnelmanager_test.cpp

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

lzwind
lzwind previously approved these changes Oct 22, 2026
@re2zero
re2zero force-pushed the pms396845/04-stream-ids-v2 branch from 4e98d8f to 8e31bef Compare October 22, 2026 07:54
@re2zero
re2zero force-pushed the pms396845/03-server-session-v2 branch from 2ae6ff7 to 57490cf Compare October 22, 2026 07:55
Both peers allocate ids for the streams they initiate, but the ids share
one namespace. Starting both counters at 1 made the barrier stream and a
reverse file transfer collide: the peer rejected the second OPEN as a
duplicate stream, so the transfer never established and stayed at 1%.

Pick a random non-zero id and skip ids already in use locally.

Log: give tunnel streams collision-free ids
PMS: TASK-396845
Influence: concurrent barrier and file-transfer streams no longer collide.
@re2zero
re2zero force-pushed the pms396845/04-stream-ids-v2 branch from 8e31bef to 5e03963 Compare October 22, 2026 08:18
@re2zero
re2zero changed the base branch from pms396845/03-server-session-v2 to master October 22, 2026 08:19
@re2zero
re2zero dismissed lzwind’s stale review October 22, 2026 08:19

The base branch was changed.

@deepin-ci-robot

Copy link
Copy Markdown

deepin pr auto review

🤖 AI 代码审查报告

总体评分: 98 分 (通过阈值: 70分)

Pass


📊 总体评价

项目 结果
审查结论 代码审查通过
评分详情 本次提交修复了 tunnel 流 ID 碰撞问题,将计数器方式改为随机 ID 生成方式,逻辑正确、注释清晰、性能良好且无安全漏洞。 OCR 发现测试代码中存在硬编码字节数的轻微可维护性问题,整体代码质量优秀。

🔍 详细分析

1. 语法逻辑 ✅

评价: 语法正确,逻辑清晰 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: []


2. 代码质量 ✅

评价: 代码结构清晰,注释完整 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: ['建议将测试中的硬编码字节数替换为变量引用 .size(),例如: const QByteArray barrierData = QByteArrayLiteral("barrier"); ASSERT_TRUE(waitFor([&] { return barrierClient.bytesAvailable() >= barrierData.size(); }));']


3. 代码性能 ✅

评价: 性能良好,资源使用合理 ✅ 通过

潜在问题:
✅ 未发现明显问题

建议: []


4. 代码安全 🔒

评价: 存在0个安全漏洞 ✅ 通过

🔐 发现 0 个安全漏洞

安全漏洞详情:
✅ 未发现安全漏洞

建议: []


💡 改进建议代码示例

// 建议优化测试中的硬编码字节数(OCR 指出的低优先级可维护性问题): TEST(TunnelManagerTest, BothSidesCanInitiateStreams) {
    // ... 前置设置省略 ...

    const QByteArray barrierPayload = QByteArrayLiteral("barrier");
    barrierClient.write(barrierPayload);
    ASSERT_TRUE(waitFor([&] { return barrierClient.bytesAvailable() >= barrierPayload.size(); }));
    EXPECT_EQ(barrierClient.readAll(), barrierPayload);

    const QByteArray transferPayload = QByteArrayLiteral("transfer");
    transferClient.write(transferPayload);
    ASSERT_TRUE(waitFor([&] { return transferClient.bytesAvailable() >= transferPayload.size(); }));
    EXPECT_EQ(transferClient.readAll(), transferPayload);

    const QByteArray alivePayload = QByteArrayLiteral("still-alive");
    barrierClient.write(alivePayload);
    ASSERT_TRUE(waitFor([&] { return barrierClient.bytesAvailable() >= alivePayload.size(); }));
    EXPECT_EQ(barrierClient.readAll(), alivePayload);
}

本报告由 AI 代码审查工具自动生成

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: lzwind, re2zero

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@re2zero
re2zero merged commit dbc7be3 into linuxdeepin:master Oct 22, 2026
25 of 26 checks passed
@re2zero
re2zero deleted the pms396845/04-stream-ids-v2 branch October 22, 2026 08:43
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.

3 participants