Commit a864e40c authored by John Selbie's avatar John Selbie

Remove atomichelpers.cpp

parent 19d5cf47
include ../common.inc include ../common.inc
PROJECT_TARGET := libcommon.a PROJECT_TARGET := libcommon.a
PROJECT_SRCS := atomichelpers.cpp cmdlineparser.cpp common.cpp condmutex.cpp crc32.cpp fasthash.cpp getconsolewidth.cpp getmillisecondcounter.cpp logger.cpp prettyprint.cpp stringhelper.cpp PROJECT_SRCS := cmdlineparser.cpp common.cpp condmutex.cpp crc32.cpp fasthash.cpp getconsolewidth.cpp getmillisecondcounter.cpp logger.cpp prettyprint.cpp stringhelper.cpp
PROJECT_OBJS := $(subst .cpp,.o,$(PROJECT_SRCS)) PROJECT_OBJS := $(subst .cpp,.o,$(PROJECT_SRCS))
INCLUDES := $(BOOST_INCLUDE) INCLUDES := $(BOOST_INCLUDE)
PRECOMP_H_GCH := commonincludes.hpp.gch PRECOMP_H_GCH := commonincludes.hpp.gch
......
/*
Copyright 2011 John Selbie
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "commonincludes.hpp"
#include "atomichelpers.h"
#if defined(i386) || defined(__i386) || defined(__i386__)
#define ATOMICS_USE_XADD
#endif
#ifdef ATOMICS_USE_XADD
unsigned int xadd_4(volatile void* pVal, unsigned int inc)
{
unsigned int result;
unsigned int* pValInt = (unsigned int*)pVal;
asm volatile(
"lock; xaddl %%eax, %2;"
:"=a" (result)
: "a" (inc), "m" (*pValInt)
:"memory" );
return (result);
}
int AtomicIncrement(int* pInt)
{
COMPILE_TIME_ASSERT(sizeof(int)==4);
// InterlockedIncrement
unsigned int result = xadd_4(pInt, 1) + 1;
return (int)result;
}
int AtomicDecrement(int* pInt)
{
// InterlockedDecrement
unsigned int result = xadd_4(pInt, -1) - 1;
return (int)result;
}
#else
int AtomicIncrement(int* pInt)
{
COMPILE_TIME_ASSERT(sizeof(int)==4);
// InterlockedIncrement
return __sync_add_and_fetch(pInt, 1);
}
int AtomicDecrement(int* pInt)
{
// InterlockedDecrement
return __sync_sub_and_fetch(pInt, 1);
}
#endif
/*
Copyright 2013 John Selbie
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef ATOMICHELPERS_H
#define ATOMICHELPERS_H
int AtomicIncrement(int* pInt);
int AtomicDecrement(int* pInt);
#endif /* ATOMICHELPERS_H */
...@@ -67,7 +67,7 @@ static const uint32_t crc_table[256] = { ...@@ -67,7 +67,7 @@ static const uint32_t crc_table[256] = {
#define DO8(buf) DO4(buf); DO4(buf); #define DO8(buf) DO4(buf); DO4(buf);
/* ========================================================================= */ /* ========================================================================= */
uint32_t crc32(uint32_t crc, uint8_t* buf, size_t len) uint32_t crc32(uint32_t crc, const uint8_t* buf, size_t len)
{ {
if (buf == nullptr) return 0L; if (buf == nullptr) return 0L;
crc = crc ^ 0xffffffffL; crc = crc ^ 0xffffffffL;
......
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
/*
* File: crc32.h
* Author: jselbie
*
* Created on September 3, 2018, 11:22 PM
*/
#ifndef CRC32_H #ifndef CRC32_H
#define CRC32_H #define CRC32_H
uint32_t crc32(uint32_t crc, uint8_t* buf, size_t len); uint32_t crc32(uint32_t crc, const uint8_t* buf, size_t len);
#endif /* CRC32_H */ #endif /* CRC32_H */
......
...@@ -17,9 +17,13 @@ ...@@ -17,9 +17,13 @@
#include "commonincludes.hpp" #include "commonincludes.hpp"
#include <sstream>
#include <atomic>
#include "stringhelper.h" #include "stringhelper.h"
#include "atomichelpers.h"
#include "oshelper.h"
#include "stunbuilder.h" #include "stunbuilder.h"
...@@ -32,12 +36,10 @@ ...@@ -32,12 +36,10 @@
#endif #endif
#include "crc32.h" #include "crc32.h"
#include "stunauth.h" #include "stunauth.h"
static int g_sequence_number = 0xaaaaaaaa; std::atomic<int> g_sequence_number;
CStunMessageBuilder::CStunMessageBuilder() : CStunMessageBuilder::CStunMessageBuilder() :
...@@ -91,6 +93,25 @@ HRESULT CStunMessageBuilder::AddTransactionId(const StunTransactionId& transid) ...@@ -91,6 +93,25 @@ HRESULT CStunMessageBuilder::AddTransactionId(const StunTransactionId& transid)
return _stream.Write(transid.id, sizeof(transid.id)); return _stream.Write(transid.id, sizeof(transid.id));
} }
uint32_t CStunMessageBuilder::GetEntropy()
{
uint32_t entropy = 0;
std::ostringstream ss;
ss << g_sequence_number.fetch_add(1);
ss << '.';
ss << getpid();
ss << '.';
ss << reinterpret_cast<uintptr_t>(this);
ss << '.';
ss << time(nullptr);
ss << '.';
ss << GetMillisecondCounter();
std::string str;
str = ss.str();
entropy = crc32(0, (const uint8_t*)(str.c_str()), str.size());
return entropy;
}
HRESULT CStunMessageBuilder::AddRandomTransactionId(StunTransactionId* pTransId) HRESULT CStunMessageBuilder::AddRandomTransactionId(StunTransactionId* pTransId)
{ {
StunTransactionId transid; StunTransactionId transid;
...@@ -98,11 +119,9 @@ HRESULT CStunMessageBuilder::AddRandomTransactionId(StunTransactionId* pTransId) ...@@ -98,11 +119,9 @@ HRESULT CStunMessageBuilder::AddRandomTransactionId(StunTransactionId* pTransId)
uint32_t entropy=0; uint32_t entropy=0;
// on x86, the rdtsc instruction is about as good as it gets for a random sequence number // on x86, the rdtsc instruction is about as good as it gets for a random sequence number
// on linux, there's /dev/urandom // on linux, there's /dev/urandom
#ifdef _WIN32 #ifdef _WIN32
// on windows, there's lots of simple stuff we can get at to give us a random number // on windows, there's lots of simple stuff we can get at to give us a random number
// the rdtsc instruction is about as good as it gets // the rdtsc instruction is about as good as it gets
...@@ -121,21 +140,15 @@ HRESULT CStunMessageBuilder::AddRandomTransactionId(StunTransactionId* pTransId) ...@@ -121,21 +140,15 @@ HRESULT CStunMessageBuilder::AddRandomTransactionId(StunTransactionId* pTransId)
} }
} }
if (entropy == 0) if (entropy == 0)
{ {
entropy ^= getpid(); entropy = GetEntropy();
entropy ^= reinterpret_cast<uintptr_t>(this);
entropy ^= time(nullptr);
entropy ^= AtomicIncrement(&g_sequence_number);
} }
#endif #endif
srand(entropy); srand(entropy);
// the first four bytes of the transaction id is always the magic cookie // the first four bytes of the transaction id is always the magic cookie
// followed by 12 bytes of the real transaction id // followed by 12 bytes of the real transaction id
memcpy(transid.id, &stun_cookie_nbo, sizeof(stun_cookie_nbo)); memcpy(transid.id, &stun_cookie_nbo, sizeof(stun_cookie_nbo));
......
...@@ -38,7 +38,8 @@ private: ...@@ -38,7 +38,8 @@ private:
HRESULT AddMappedAddressImpl(uint16_t attribute, const CSocketAddress& addr); HRESULT AddMappedAddressImpl(uint16_t attribute, const CSocketAddress& addr);
HRESULT AddMessageIntegrityImpl(uint8_t* key, size_t keysize); HRESULT AddMessageIntegrityImpl(uint8_t* key, size_t keysize);
uint32_t GetEntropy();
public: public:
CStunMessageBuilder(); CStunMessageBuilder();
...@@ -83,6 +84,8 @@ public: ...@@ -83,6 +84,8 @@ public:
HRESULT GetResult(CRefCountedBuffer* pspBuffer); HRESULT GetResult(CRefCountedBuffer* pspBuffer);
CDataStream& GetStream(); CDataStream& GetStream();
friend class CTestBuilder;
}; };
#endif #endif
...@@ -55,7 +55,7 @@ void CStunMessageReader::Reset() ...@@ -55,7 +55,7 @@ void CStunMessageReader::Reset()
_indexMessageIntegrity = -1; _indexMessageIntegrity = -1;
_countAttributes = 0; _countAttributes = 0;
memset(&_transactionid, '\0', sizeof(_transactionid)); _transactionid = {};
_msgTypeNormalized = 0xffff; _msgTypeNormalized = 0xffff;
_msgClass = StunMsgClassInvalidMessageClass; _msgClass = StunMsgClassInvalidMessageClass;
_msgLength = 0; _msgLength = 0;
......
include ../common.inc include ../common.inc
PROJECT_TARGET := stuntestcode PROJECT_TARGET := stuntestcode
PROJECT_OBJS := benchmark.o testatomichelpers.o testbuilder.o testclientlogic.o testcmdline.o testcrc32.o testcode.o testdatastream.o testfasthash.o testintegrity.o testmessagehandler.o testpolling.o testratelimiter.o testreader.o testrecvfromex.o PROJECT_OBJS := benchmark.o testbuilder.o testclientlogic.o testcmdline.o testcrc32.o testcode.o testdatastream.o testfasthash.o testintegrity.o testmessagehandler.o testpolling.o testratelimiter.o testreader.o testrecvfromex.o
INCLUDES := $(BOOST_INCLUDE) $(OPENSSL_INCLUDE) -I../common -I../stuncore -I../networkutils INCLUDES := $(BOOST_INCLUDE) $(OPENSSL_INCLUDE) -I../common -I../stuncore -I../networkutils
LIB_PATH := -L../networkutils -L../stuncore -L../common LIB_PATH := -L../networkutils -L../stuncore -L../common
......
/*
Copyright 2013 John Selbie
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#include "commonincludes.hpp"
#include "testatomichelpers.h"
#include "atomichelpers.h"
HRESULT CTestAtomicHelpers::Run()
{
HRESULT hr = S_OK;
int value = -2000;
int nextexpected = -2000;
int result = 0;
while (value < 2000)
{
nextexpected++;
result = AtomicIncrement(&value);
ChkIf(result != nextexpected, E_UNEXPECTED);
ChkIf(result != value, E_UNEXPECTED);
}
value = 2000;
nextexpected = 2000;
while (value > -2000)
{
nextexpected--;
result = AtomicDecrement(&value);
ChkIf(result != nextexpected, E_UNEXPECTED);
ChkIf(result != value, E_UNEXPECTED);
}
Cleanup:
return hr;
}
\ No newline at end of file
/*
Copyright 2013 John Selbie
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef TESTATOMICHELPERS_H
#define TESTATOMICHELPERS_H
#include "unittest.h"
class CTestAtomicHelpers : public IUnitTest
{
public:
virtual HRESULT Run();
UT_DECLARE_TEST_NAME("CTestAtomicHelpers");
};
#endif /* TESTATOMICHELPERS_H */
...@@ -27,6 +27,7 @@ HRESULT CTestBuilder::Run() ...@@ -27,6 +27,7 @@ HRESULT CTestBuilder::Run()
HRESULT hr = S_OK; HRESULT hr = S_OK;
Chk(Test1()) Chk(Test1())
Chk(Test2()); Chk(Test2());
Chk(TestEntropy());
Cleanup: Cleanup:
return hr; return hr;
} }
...@@ -138,4 +139,23 @@ Cleanup: ...@@ -138,4 +139,23 @@ Cleanup:
return hr; return hr;
} }
HRESULT CTestBuilder::TestEntropy()
{
CStunMessageBuilder builder;
HRESULT hr = S_OK;
uint32_t prev = 0;
for (int x = 0; x < 15; x++)
{
uint32_t e = builder.GetEntropy();
ChkIfA(e == 0, E_FAIL);
ChkIfA(e == prev, E_FAIL);
prev = e;
}
Cleanup:
return hr;
}
...@@ -26,6 +26,7 @@ class CTestBuilder : public IUnitTest ...@@ -26,6 +26,7 @@ class CTestBuilder : public IUnitTest
public: public:
HRESULT Test1(); HRESULT Test1();
HRESULT Test2(); HRESULT Test2();
HRESULT TestEntropy();
virtual HRESULT Run(); virtual HRESULT Run();
......
...@@ -33,7 +33,6 @@ ...@@ -33,7 +33,6 @@
#include "prettyprint.h" #include "prettyprint.h"
#include "polling.h" #include "polling.h"
#include "testpolling.h" #include "testpolling.h"
#include "testatomichelpers.h"
#include "testratelimiter.h" #include "testratelimiter.h"
void ReaderFuzzTest() void ReaderFuzzTest()
...@@ -85,7 +84,6 @@ void RunUnitTests() ...@@ -85,7 +84,6 @@ void RunUnitTests()
std::shared_ptr<CTestRecvFromExIPV6> spTestRecvFromEx6(new CTestRecvFromExIPV6); std::shared_ptr<CTestRecvFromExIPV6> spTestRecvFromEx6(new CTestRecvFromExIPV6);
std::shared_ptr<CTestFastHash> spTestFastHash(new CTestFastHash); std::shared_ptr<CTestFastHash> spTestFastHash(new CTestFastHash);
std::shared_ptr<CTestPolling> spTestPolling(new CTestPolling); std::shared_ptr<CTestPolling> spTestPolling(new CTestPolling);
std::shared_ptr<CTestAtomicHelpers> spTestAtomicHelpers(new CTestAtomicHelpers);
std::shared_ptr<CTestRateLimiter> spTestRateLimiter(new CTestRateLimiter); std::shared_ptr<CTestRateLimiter> spTestRateLimiter(new CTestRateLimiter);
std::shared_ptr<CTestCRC32> spTestCRC32(new CTestCRC32); std::shared_ptr<CTestCRC32> spTestCRC32(new CTestCRC32);
...@@ -100,7 +98,6 @@ void RunUnitTests() ...@@ -100,7 +98,6 @@ void RunUnitTests()
vecTests.push_back(spTestRecvFromEx6); vecTests.push_back(spTestRecvFromEx6);
vecTests.push_back(spTestFastHash); vecTests.push_back(spTestFastHash);
vecTests.push_back(spTestPolling); vecTests.push_back(spTestPolling);
vecTests.push_back(spTestAtomicHelpers);
vecTests.push_back(spTestRateLimiter); vecTests.push_back(spTestRateLimiter);
vecTests.push_back(spTestCRC32); vecTests.push_back(spTestCRC32);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment