@@ -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