Skip to content

All updates to va should perhaps reset resend counter #9

@ThomasHabets

Description

@ThomasHabets

Background

rc, the resend counter, will terminate a connection if exceeded. It is normally reset on received RR response when everything is fully acked (C4.5b in 2017 spec, state diagram for Timer Recovery).

The intention of rc, as I understand it, is to break the connection if the other side is unable to confirm that they heard us.

This is usually done by sending an RR command, and waiting for the response.

The problem

If either the three RR commands heading out, or their responses, are lost, then the connection is cut.

But we are not actually interested in the RR directly. We want to know "are you hearing me, and am I hearing you?".

My suggestion

set rc to 0 whenever we update va.

When we update va it's because we received either an RR with a n nr, or an IFRAME with an nr higher than the last one we got.

Our outgoing IFRAME took the place of the outgoing RR Command, and the packet triggering va update takes the place of the RR Response.

Semantically we have established the same fact: they can hear us, and we can hear them.

I've added an experiment to my implemenation, with results below.

Before

I set up a test that drop packets randomly (well, by a specific random seed so that it's replayable). I also capture both sides of the connection into pcaps.

This test is with a very aggressive 75% packet loss.

Note that even though the client in packet 24 gets an IFRAME with a NR=2 (which, ehem, we already get in the incoming RR Commands, but that's issue #8), it cuts the connection right after.

$ tshark -r target/async_tcp_example_captures/lossy-data/rax25-async-captures-lossy-data-2343790-1778770388883562915/client.pcap 
    1   0.000000      M0TST-1 → M0TST-2      AX.25 15 U P, func=SABM
    2   0.003040      M0TST-2 → M0TST-1      AX.25 15 U F, func=UA
    3   0.003734      M0TST-2 → M0TST-1      AX.25-NoL3 39 Text
    4   0.003867      M0TST-1 → M0TST-2      AX.25-NoL3 21 Text
    5   0.106052      M0TST-1 → M0TST-2      AX.25 15 S P, func=RR, N(R)=1
    6   0.307623      M0TST-1 → M0TST-2      AX.25 15 S P, func=RR, N(R)=1
    7   0.316086      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=1
    8   0.316318      M0TST-1 → M0TST-2      AX.25 15 S F, func=RR, N(R)=1
    9   0.330541      M0TST-2 → M0TST-1      AX.25-NoL3 28 Text
   10   0.331235      M0TST-1 → M0TST-2      AX.25-NoL3 22 Text
   11   0.432554      M0TST-1 → M0TST-2      AX.25 15 S P, func=RR, N(R)=2
   12   0.634387      M0TST-1 → M0TST-2      AX.25 15 S P, func=RR, N(R)=2
   13   0.836089      M0TST-1 → M0TST-2      AX.25 15 S P, func=RR, N(R)=2
   14   0.850344      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=2
   15   0.850608      M0TST-1 → M0TST-2      AX.25 15 S F, func=RR, N(R)=2
   16   1.038495      M0TST-1 → M0TST-2      AX.25 15 S P, func=RR, N(R)=2
   17   1.239945      M0TST-1 → M0TST-2      AX.25 15 S P, func=RR, N(R)=2
   18   1.269953      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=2
   19   1.270211      M0TST-1 → M0TST-2      AX.25 15 S F, func=RR, N(R)=2
   20   1.440963      M0TST-1 → M0TST-2      AX.25 15 S P, func=RR, N(R)=2
   21   1.642432      M0TST-1 → M0TST-2      AX.25 15 S P, func=RR, N(R)=2
   22   1.688341      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=2
   23   1.688612      M0TST-1 → M0TST-2      AX.25 15 S F, func=RR, N(R)=2
   24   1.701733      M0TST-2 → M0TST-1      AX.25-NoL3 29 Text
   25   1.702416      M0TST-1 → M0TST-2      AX.25-NoL3 24 Text
   26   1.803975      M0TST-1 → M0TST-2      AX.25 15 U, func=DM
$ tshark -r target/async_tcp_example_captures/lossy-data/rax25-async-captures-lossy-data-2343790-1778770388883562915/server.pcap 
    1   0.000000      M0TST-1 → M0TST-2      AX.25 15 U P, func=SABM
    2   0.000053      M0TST-2 → M0TST-1      AX.25 15 U F, func=UA
    3   0.000084      M0TST-2 → M0TST-1      AX.25-NoL3 39 Text
    4   0.003616      M0TST-1 → M0TST-2      AX.25-NoL3 21 Text
    5   0.003664      M0TST-2 → M0TST-1      AX.25-NoL3 28 Text
    6   0.104907      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=1
    7   0.306328      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=1
    8   0.322048      M0TST-1 → M0TST-2      AX.25 15 S F, func=RR, N(R)=1
    9   0.322314      M0TST-2 → M0TST-1      AX.25-NoL3 28 Text
   10   0.335849      M0TST-1 → M0TST-2      AX.25-NoL3 22 Text
   11   0.336085      M0TST-2 → M0TST-1      AX.25-NoL3 29 Text
   12   0.437374      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=2
   13   0.638722      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=2
   14   0.840282      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=2
   15   0.856493      M0TST-1 → M0TST-2      AX.25 15 S F, func=RR, N(R)=2
   16   0.856740      M0TST-2 → M0TST-1      AX.25-NoL3 29 Text
   17   1.057522      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=2
   18   1.259900      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=2
   19   1.276182      M0TST-1 → M0TST-2      AX.25 15 S F, func=RR, N(R)=2
   20   1.276429      M0TST-2 → M0TST-1      AX.25-NoL3 29 Text
   21   1.477858      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=2
   22   1.679327      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=2
   23   1.693697      M0TST-1 → M0TST-2      AX.25 15 S F, func=RR, N(R)=2
   24   1.693905      M0TST-2 → M0TST-1      AX.25-NoL3 29 Text
   25   1.706951      M0TST-1 → M0TST-2      AX.25-NoL3 24 Text
   26   1.707232      M0TST-2 → M0TST-1      AX.25-NoL3 31 Text
   27   1.811249      M0TST-1 → M0TST-2      AX.25 15 U, func=DM

After

Notice how the received IFRAME in packet 24 on the client side now makes the connection stay alive, and successfully complete.

$ tshark -r target/async_tcp_example_captures/lossy-data/rax25-async-captures-lossy-data-2344949-1778770617002570576/client.pcap 
    1   0.000000      M0TST-1 → M0TST-2      AX.25 15 U P, func=SABM
    2   0.003138      M0TST-2 → M0TST-1      AX.25 15 U F, func=UA
    3   0.003815      M0TST-2 → M0TST-1      AX.25-NoL3 39 Text
    4   0.004049      M0TST-1 → M0TST-2      AX.25-NoL3 21 Text
    5   0.105564      M0TST-1 → M0TST-2      AX.25 15 S P, func=RR, N(R)=1
    6   0.306603      M0TST-1 → M0TST-2      AX.25 15 S P, func=RR, N(R)=1
    7   0.315614      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=1
    8   0.315872      M0TST-1 → M0TST-2      AX.25 15 S F, func=RR, N(R)=1
    9   0.329554      M0TST-2 → M0TST-1      AX.25-NoL3 28 Text
   10   0.330261      M0TST-1 → M0TST-2      AX.25-NoL3 22 Text
   11   0.432420      M0TST-1 → M0TST-2      AX.25 15 S P, func=RR, N(R)=2
   12   0.633838      M0TST-1 → M0TST-2      AX.25 15 S P, func=RR, N(R)=2
   13   0.834596      M0TST-1 → M0TST-2      AX.25 15 S P, func=RR, N(R)=2
   14   0.843343      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=2
   15   0.843443      M0TST-1 → M0TST-2      AX.25 15 S F, func=RR, N(R)=2
   16   1.036253      M0TST-1 → M0TST-2      AX.25 15 S P, func=RR, N(R)=2
   17   1.237229      M0TST-1 → M0TST-2      AX.25 15 S P, func=RR, N(R)=2
   18   1.250757      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=2
   19   1.250817      M0TST-1 → M0TST-2      AX.25 15 S F, func=RR, N(R)=2
   20   1.439012      M0TST-1 → M0TST-2      AX.25 15 S P, func=RR, N(R)=2
   21   1.639826      M0TST-1 → M0TST-2      AX.25 15 S P, func=RR, N(R)=2
   22   1.656260      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=2
   23   1.656311      M0TST-1 → M0TST-2      AX.25 15 S F, func=RR, N(R)=2
   24   1.659352      M0TST-2 → M0TST-1      AX.25-NoL3 29 Text
   25   1.659596      M0TST-1 → M0TST-2      AX.25-NoL3 24 Text
   26   1.760611      M0TST-1 → M0TST-2      AX.25 15 S P, func=RR, N(R)=3
   27   1.962347      M0TST-1 → M0TST-2      AX.25 15 S P, func=RR, N(R)=3
   28   2.164042      M0TST-1 → M0TST-2      AX.25 15 S P, func=RR, N(R)=3
   29   2.174664      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=3
   30   2.174941      M0TST-1 → M0TST-2      AX.25 15 S F, func=RR, N(R)=3
   31   2.190270      M0TST-2 → M0TST-1      AX.25-NoL3 31 Text
   32   2.191088      M0TST-1 → M0TST-2      AX.25 15 U P, func=DISC
   33   2.204244      M0TST-2 → M0TST-1      AX.25 15 U F, func=UA
$ tshark -r target/async_tcp_example_captures/lossy-data/rax25-async-captures-lossy-data-2344949-1778770617002570576/server.pcap 
    1   0.000000      M0TST-1 → M0TST-2      AX.25 15 U P, func=SABM
    2   0.000064      M0TST-2 → M0TST-1      AX.25 15 U F, func=UA
    3   0.000100      M0TST-2 → M0TST-1      AX.25-NoL3 39 Text
    4   0.004078      M0TST-1 → M0TST-2      AX.25-NoL3 21 Text
    5   0.004141      M0TST-2 → M0TST-1      AX.25-NoL3 28 Text
    6   0.105679      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=1
    7   0.306622      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=1
    8   0.321564      M0TST-1 → M0TST-2      AX.25 15 S F, func=RR, N(R)=1
    9   0.321808      M0TST-2 → M0TST-1      AX.25-NoL3 28 Text
   10   0.334729      M0TST-1 → M0TST-2      AX.25-NoL3 22 Text
   11   0.334965      M0TST-2 → M0TST-1      AX.25-NoL3 29 Text
   12   0.436276      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=2
   13   0.637757      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=2
   14   0.838892      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=2
   15   0.844634      M0TST-1 → M0TST-2      AX.25 15 S F, func=RR, N(R)=2
   16   0.844737      M0TST-2 → M0TST-1      AX.25-NoL3 29 Text
   17   1.046606      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=2
   18   1.247438      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=2
   19   1.250731      M0TST-1 → M0TST-2      AX.25 15 S F, func=RR, N(R)=2
   20   1.250786      M0TST-2 → M0TST-1      AX.25-NoL3 29 Text
   21   1.452287      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=2
   22   1.653105      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=2
   23   1.656276      M0TST-1 → M0TST-2      AX.25 15 S F, func=RR, N(R)=2
   24   1.656326      M0TST-2 → M0TST-1      AX.25-NoL3 29 Text
   25   1.659459      M0TST-1 → M0TST-2      AX.25-NoL3 24 Text
   26   1.659514      M0TST-2 → M0TST-1      AX.25-NoL3 31 Text
   27   1.761420      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=3
   28   1.962816      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=3
   29   2.164288      M0TST-2 → M0TST-1      AX.25 15 S P, func=RR, N(R)=3
   30   2.181316      M0TST-1 → M0TST-2      AX.25 15 S F, func=RR, N(R)=3
   31   2.181579      M0TST-2 → M0TST-1      AX.25-NoL3 31 Text
   32   2.196047      M0TST-1 → M0TST-2      AX.25 15 U P, func=DISC
   33   2.196285      M0TST-2 → M0TST-1      AX.25 15 U F, func=UA

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions