saltysystems / enet

ENet implementation in Erlang/OTP
Apache License 2.0
9 stars 0 forks source link

correctly order packets on rollover #2

Closed cmdrk closed 2 years ago

cmdrk commented 2 years ago

consider the following scenario: packets come in out of order near the 16-bit overflow:

  [{65535, Data2}
  {65534, Data1}
  {0, Data3},
  {1, Data4}].

So when the lists:keysort(1,N) function in enet_channel_srv is called, it will sort wrongly, e.g.:

  [{0, Data3}
  {1, Data4}
  {65534, Data1},
  {65535, Data2}].

which is obviously not right.

cmdrk commented 2 years ago

Wrote a custom sorting function for this, seems to work at the unit-test level:

-module(wrapped).

-export([sort/1]).

-define(MAX,65536).

sort(List) ->
    F = fun(A,B) ->
            Compare = B - A,
            if
                Compare > 0, Compare =< ?MAX/2 ->
                    true;
                Compare < 0, Compare =< -?MAX/2 ->
                    true;
                true ->
                    false
            end
        end,
    lists:sort(F,List).
Erlang/OTP 25 [erts-13.0.4] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit:ns] [dtrace] [sharing-preserving]

Eshell V13.0.4  (abort with ^G)
1> c(wrapped).
{ok,wrapped}
2> L = [48880,42068,65536,8,3,7,0].
[48880,42068,65536,8,3,7,0]
3> wrapped:sort(L).
[42068,48880,65536,0,3,7,8]
4>

Plus it seems to work just fine with the usual lists.