Skip to content

Commit 265d0e4

Browse files
ethourisMikolaj Malecki
andauthored
[core] Fixed invalid cookie contest calculation (#3212)
Co-authored-by: Mikolaj Malecki <mmalecki@haivision.com>
1 parent 725e2d4 commit 265d0e4

File tree

1 file changed

+32
-9
lines changed

1 file changed

+32
-9
lines changed

srtcore/core.cpp

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4107,13 +4107,13 @@ void srt::CUDT::cookieContest()
41074107
if (m_SrtHsSide != HSD_DRAW)
41084108
return;
41094109

4110-
LOGC(cnlog.Debug,
4111-
log << CONID() << "cookieContest: agent=" << m_ConnReq.m_iCookie << " peer=" << m_ConnRes.m_iCookie);
4112-
41134110
// Here m_ConnReq.m_iCookie is a local cookie value sent in connection request to the peer.
41144111
// m_ConnRes.m_iCookie is a cookie value sent by the peer in its connection request.
41154112
if (m_ConnReq.m_iCookie == 0 || m_ConnRes.m_iCookie == 0)
41164113
{
4114+
LOGC(cnlog.Debug, log << CONID() << "cookieContest: agent=" << m_ConnReq.m_iCookie << " peer=" << m_ConnRes.m_iCookie
4115+
<< " - ERROR: zero not allowed!");
4116+
41174117
// Note that it's virtually impossible that Agent's cookie is not ready, this
41184118
// shall be considered IPE.
41194119
// Not all cookies are ready, don't start the contest.
@@ -4134,11 +4134,34 @@ void srt::CUDT::cookieContest()
41344134
// int32_t iBetterCookie = 2002790373 (7760 27E5);
41354135
//
41364136
// Now 64-bit arithmetic is used to calculate the actual result of subtraction.
4137-
// The 31-st bit is then checked to check if the resulting is negative in 32-bit aritmetics.
4138-
// This way the old contest behavior is preserved, and potential compiler optimisations are avoided.
4139-
const int64_t contest = int64_t(m_ConnReq.m_iCookie) - int64_t(m_ConnRes.m_iCookie);
4140-
4141-
if ((contest & 0xFFFFFFFF) == 0)
4137+
//
4138+
// In SRT v1.5.4 there was a version, that checked:
4139+
// - if LOWER 32-bits are 0, this is a draw
4140+
// - if bit 31 is set (AND with 0x80000000), the result is considered negative.
4141+
// This was erroneous because for 1 and 0x80000001 cookie values the
4142+
// result was always the same, regardless of the order:
4143+
//
4144+
// 0x0000000000000001 - 0xFFFFFFFF80000001 = 0x0000000080000000
4145+
// 0xFFFFFFFF80000001 - 0x0000000080000000 = 0xFFFFFFFF80000000
4146+
//
4147+
// >> if (contest & 0x80000000) -> results in true in both comparisons.
4148+
//
4149+
// This version takes the bare result of the 64-bit arithmetics.
4150+
const int64_t xreq = int64_t(m_ConnReq.m_iCookie);
4151+
const int64_t xres = int64_t(m_ConnRes.m_iCookie);
4152+
const int64_t contest = xreq - xres;
4153+
4154+
// NOTE: for 1.6.0 use:
4155+
// fmtc hex64 = fmtc().uhex().fillzero().width(16); then
4156+
// << fmt(xreq, hex64)
4157+
LOGC(cnlog.Debug, log << CONID() << "cookieContest: agent=" << m_ConnReq.m_iCookie
4158+
<< " peer=" << m_ConnRes.m_iCookie
4159+
<< hex << uppercase << setfill('0') // PERSISTENT flags
4160+
<< " X64: "<< setw(16) << xreq
4161+
<< " vs. " << setw(16) << xres
4162+
<< " DIFF: " << setw(16) << contest);
4163+
4164+
if (contest == 0)
41424165
{
41434166
// DRAW! The only way to continue would be to force the
41444167
// cookies to be regenerated and to start over. But it's
@@ -4154,7 +4177,7 @@ void srt::CUDT::cookieContest()
41544177
return;
41554178
}
41564179

4157-
if (contest & 0x80000000)
4180+
if (contest < 0)
41584181
{
41594182
m_SrtHsSide = HSD_RESPONDER;
41604183
return;

0 commit comments

Comments
 (0)