diff --git a/Filelist.txt b/Filelist.txt index 6b0ffe3d..678291f8 100644 --- a/Filelist.txt +++ b/Filelist.txt @@ -202,8 +202,6 @@ naclite.h nbtheory.cpp nbtheory.h neon-simd.cpp -network.cpp -network.h nr.h oaep.cpp oaep.h @@ -311,8 +309,6 @@ sm4.cpp sm4-simd.cpp sm4.h smartptr.h -socketft.cpp -socketft.h sosemanuk.cpp sosemanuk.h speck.cpp @@ -336,8 +332,6 @@ threefish.h tiger.cpp tiger.h tigertab.cpp -trdlocal.cpp -trdlocal.h trunhash.h ttmac.cpp ttmac.h @@ -360,14 +354,10 @@ validate.h vmac.cpp vmac.h vs2005.zip -wait.cpp -wait.h wake.cpp wake.h whrlpool.cpp whrlpool.h -winpipes.cpp -winpipes.h words.h x64dll.asm x64masm.asm diff --git a/config.h b/config.h index 57f1515d..c7d1ca3b 100644 --- a/config.h +++ b/config.h @@ -142,15 +142,6 @@ // see http://github.com/weidai11/cryptopp/issues/389. // #define CRYPTOPP_NO_ASSIGN_TO_INTEGER -// choose which style of sockets to wrap (mostly useful for MinGW which has both) -#if !defined(NO_BERKELEY_STYLE_SOCKETS) && !defined(PREFER_BERKELEY_STYLE_SOCKETS) -# define PREFER_BERKELEY_STYLE_SOCKETS -#endif - -// #if !defined(NO_WINDOWS_STYLE_SOCKETS) && !defined(PREFER_WINDOWS_STYLE_SOCKETS) -// # define PREFER_WINDOWS_STYLE_SOCKETS -// #endif - // set the name of Rijndael cipher, was "Rijndael" before version 5.3 #define CRYPTOPP_RIJNDAEL_NAME "AES" @@ -219,10 +210,6 @@ namespace CryptoPP { } # endif #endif -#if defined(__CYGWIN__) && defined(PREFER_WINDOWS_STYLE_SOCKETS) -# define __USE_W32_SOCKETS -#endif - // Originally in global namespace to avoid ambiguity with other byte typedefs. // Moved to Crypto++ namespace due to C++17, std::byte and potential compile problems. Also see // http://www.cryptopp.com/wiki/std::byte and http://github.com/weidai11/cryptopp/issues/442 @@ -912,46 +899,10 @@ NAMESPACE_END # endif #endif -#ifdef CRYPTOPP_UNIX_AVAILABLE -# define HAS_BERKELEY_STYLE_SOCKETS -# define SOCKETS_AVAILABLE -#endif - -// Sockets are only available under Windows Runtime desktop partition apps (despite the MSDN literature) -#ifdef CRYPTOPP_WIN32_AVAILABLE -# define HAS_WINDOWS_STYLE_SOCKETS -# if !defined(WINAPI_FAMILY) -# define SOCKETS_AVAILABLE -# elif defined(WINAPI_FAMILY) -# if (WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)) -# define SOCKETS_AVAILABLE -# endif -# endif -#endif - -#if defined(HAS_WINDOWS_STYLE_SOCKETS) && (!defined(HAS_BERKELEY_STYLE_SOCKETS) || defined(PREFER_WINDOWS_STYLE_SOCKETS)) -# define USE_WINDOWS_STYLE_SOCKETS -#else -# define USE_BERKELEY_STYLE_SOCKETS -#endif - -#if defined(CRYPTOPP_WIN32_AVAILABLE) && defined(SOCKETS_AVAILABLE) && !defined(USE_BERKELEY_STYLE_SOCKETS) -# define WINDOWS_PIPES_AVAILABLE -#endif - - #if defined(CRYPTOPP_UNIX_AVAILABLE) || defined(CRYPTOPP_DOXYGEN_PROCESSING) # define NONBLOCKING_RNG_AVAILABLE # define BLOCKING_RNG_AVAILABLE # define OS_RNG_AVAILABLE -# define HAS_PTHREADS -# define THREADS_AVAILABLE -#endif - -// Early IBM XL C on AIX fails to link due to missing pthread gear -#if defined(_AIX) && defined(__xlC__) -# undef HAS_PTHREADS -# undef THREADS_AVAILABLE #endif // Cygwin/Newlib requires _XOPEN_SOURCE=600 @@ -961,14 +912,10 @@ NAMESPACE_END #ifdef CRYPTOPP_WIN32_AVAILABLE # if !defined(WINAPI_FAMILY) -# define HAS_WINTHREADS -# define THREADS_AVAILABLE # define NONBLOCKING_RNG_AVAILABLE # define OS_RNG_AVAILABLE # elif defined(WINAPI_FAMILY) # if (WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)) -# define HAS_WINTHREADS -# define THREADS_AVAILABLE # define NONBLOCKING_RNG_AVAILABLE # define OS_RNG_AVAILABLE # elif !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)) diff --git a/cryptdll.vcxproj b/cryptdll.vcxproj index df5a4787..971cbb79 100644 --- a/cryptdll.vcxproj +++ b/cryptdll.vcxproj @@ -240,7 +240,6 @@ - @@ -309,7 +308,6 @@ - diff --git a/cryptest.nmake b/cryptest.nmake index a0db6a29..e6a16fc4 100644 --- a/cryptest.nmake +++ b/cryptest.nmake @@ -45,11 +45,9 @@ ########################################################################################### -# If you use 'make sources' from Linux makefile, then add 'winpipes.cpp' to the list below. +LIB_SRCS = cryptlib.cpp cpu.cpp integer.cpp 3way.cpp adler32.cpp algebra.cpp algparam.cpp arc4.cpp aria-simd.cpp aria.cpp ariatab.cpp asn.cpp authenc.cpp base32.cpp base64.cpp basecode.cpp bfinit.cpp blake2-simd.cpp blake2.cpp blowfish.cpp blumshub.cpp camellia.cpp cast.cpp casts.cpp cbcmac.cpp ccm.cpp chacha.cpp cham.cpp cham-simd.cpp channels.cpp cmac.cpp crc-simd.cpp crc.cpp default.cpp des.cpp dessp.cpp dh.cpp dh2.cpp dll.cpp dsa.cpp eax.cpp ec2n.cpp eccrypto.cpp ecp.cpp elgamal.cpp emsa2.cpp eprecomp.cpp esign.cpp files.cpp filters.cpp fips140.cpp fipstest.cpp gcm-simd.cpp gcm.cpp gf256.cpp gf2_32.cpp gf2n.cpp gfpcrypt.cpp gost.cpp gzip.cpp hc128.cpp hc256.cpp hex.cpp hight.cpp hmac.cpp hrtimer.cpp ida.cpp idea.cpp iterhash.cpp kalyna.cpp kalynatab.cpp keccak.cpp lea.cpp lea-simd.cpp luc.cpp mars.cpp marss.cpp md2.cpp md4.cpp md5.cpp misc.cpp modes.cpp mqueue.cpp mqv.cpp nbtheory.cpp neon-simd.cpp oaep.cpp osrng.cpp padlkrng.cpp panama.cpp pkcspad.cpp poly1305.cpp polynomi.cpp pssr.cpp pubkey.cpp queue.cpp rabin.cpp randpool.cpp rabbit.cpp rc2.cpp rc5.cpp rc6.cpp rdrand.cpp rdtables.cpp rijndael-simd.cpp rijndael.cpp ripemd.cpp rng.cpp rsa.cpp rw.cpp safer.cpp salsa.cpp scrypt.cpp seal.cpp seed.cpp serpent.cpp sha-simd.cpp sha.cpp sha3.cpp shacal2-simd.cpp shacal2.cpp shark.cpp sharkbox.cpp simeck-simd.cpp simeck.cpp simon.cpp simon64-simd.cpp simon128-simd.cpp skipjack.cpp sm3.cpp sm4.cpp sm4-simd.cpp sosemanuk.cpp speck.cpp speck64-simd.cpp speck128-simd.cpp square.cpp squaretb.cpp sse-simd.cpp strciphr.cpp tea.cpp tftables.cpp threefish.cpp tiger.cpp tigertab.cpp ttmac.cpp tweetnacl.cpp twofish.cpp vmac.cpp wake.cpp whrlpool.cp xtr.cpp xtrcrypt.cpp zdeflate.cpp zinflate.cpp zlib.cpp -LIB_SRCS = cryptlib.cpp cpu.cpp integer.cpp 3way.cpp adler32.cpp algebra.cpp algparam.cpp arc4.cpp aria-simd.cpp aria.cpp ariatab.cpp asn.cpp authenc.cpp base32.cpp base64.cpp basecode.cpp bfinit.cpp blake2-simd.cpp blake2.cpp blowfish.cpp blumshub.cpp camellia.cpp cast.cpp casts.cpp cbcmac.cpp ccm.cpp chacha.cpp cham.cpp cham-simd.cpp channels.cpp cmac.cpp crc-simd.cpp crc.cpp default.cpp des.cpp dessp.cpp dh.cpp dh2.cpp dll.cpp dsa.cpp eax.cpp ec2n.cpp eccrypto.cpp ecp.cpp elgamal.cpp emsa2.cpp eprecomp.cpp esign.cpp files.cpp filters.cpp fips140.cpp fipstest.cpp gcm-simd.cpp gcm.cpp gf256.cpp gf2_32.cpp gf2n.cpp gfpcrypt.cpp gost.cpp gzip.cpp hc128.cpp hc256.cpp hex.cpp hight.cpp hmac.cpp hrtimer.cpp ida.cpp idea.cpp iterhash.cpp kalyna.cpp kalynatab.cpp keccak.cpp lea.cpp lea-simd.cpp luc.cpp mars.cpp marss.cpp md2.cpp md4.cpp md5.cpp misc.cpp modes.cpp mqueue.cpp mqv.cpp nbtheory.cpp neon-simd.cpp network.cpp oaep.cpp osrng.cpp padlkrng.cpp panama.cpp pkcspad.cpp poly1305.cpp polynomi.cpp pssr.cpp pubkey.cpp queue.cpp rabin.cpp randpool.cpp rabbit.cpp rc2.cpp rc5.cpp rc6.cpp rdrand.cpp rdtables.cpp rijndael-simd.cpp rijndael.cpp ripemd.cpp rng.cpp rsa.cpp rw.cpp safer.cpp salsa.cpp scrypt.cpp seal.cpp seed.cpp serpent.cpp sha-simd.cpp sha.cpp sha3.cpp shacal2-simd.cpp shacal2.cpp shark.cpp sharkbox.cpp simeck-simd.cpp simeck.cpp simon.cpp simon64-simd.cpp simon128-simd.cpp skipjack.cpp sm3.cpp sm4.cpp sm4-simd.cpp socketft.cpp sosemanuk.cpp speck.cpp speck64-simd.cpp speck128-simd.cpp square.cpp squaretb.cpp sse-simd.cpp strciphr.cpp tea.cpp tftables.cpp threefish.cpp tiger.cpp tigertab.cpp trdlocal.cpp ttmac.cpp tweetnacl.cpp twofish.cpp vmac.cpp wait.cpp wake.cpp whrlpool.cpp winpipes.cpp xtr.cpp xtrcrypt.cpp zdeflate.cpp zinflate.cpp zlib.cpp - -LIB_OBJS = cryptlib.obj cpu.obj integer.obj 3way.obj adler32.obj algebra.obj algparam.obj arc4.obj aria-simd.obj aria.obj ariatab.obj asn.obj authenc.obj base32.obj base64.obj basecode.obj bfinit.obj blake2-simd.obj blake2.obj blowfish.obj blumshub.obj camellia.obj cast.obj casts.obj cbcmac.obj ccm.obj chacha.obj cham.obj cham-simd.obj channels.obj cmac.obj crc-simd.obj crc.obj default.obj des.obj dessp.obj dh.obj dh2.obj dll.obj dsa.obj eax.obj ec2n.obj eccrypto.obj ecp.obj elgamal.obj emsa2.obj eprecomp.obj esign.obj files.obj filters.obj fips140.obj fipstest.obj gcm-simd.obj gcm.obj gf256.obj gf2_32.obj gf2n.obj gfpcrypt.obj gost.obj gzip.obj hc128.obj hc256.obj hex.obj hight.obj hmac.obj hrtimer.obj ida.obj idea.obj iterhash.obj kalyna.obj kalynatab.obj keccak.obj lea.obj lea-simd.obj luc.obj mars.obj marss.obj md2.obj md4.obj md5.obj misc.obj modes.obj mqueue.obj mqv.obj nbtheory.obj neon-simd.obj network.obj oaep.obj osrng.obj padlkrng.obj panama.obj pkcspad.obj poly1305.obj polynomi.obj pssr.obj pubkey.obj queue.obj rabin.obj randpool.obj rabbit.obj rc2.obj rc5.obj rc6.obj rdrand.obj rdtables.obj rijndael-simd.obj rijndael.obj ripemd.obj rng.obj rsa.obj rw.obj safer.obj salsa.obj scrypt.obj seal.obj seed.obj serpent.obj sha-simd.obj sha.obj sha3.obj shacal2-simd.obj shacal2.obj shark.obj sharkbox.obj simeck-simd.obj simeck.obj simon.obj simon64-simd.obj simon128-simd.obj skipjack.obj sm3.obj sm4.obj sm4-simd.obj socketft.obj sosemanuk.obj speck.obj speck64-simd.obj speck128-simd.obj square.obj squaretb.obj sse-simd.obj strciphr.obj tea.obj tftables.obj threefish.obj tiger.obj tigertab.obj trdlocal.obj ttmac.obj tweetnacl.obj twofish.obj vmac.obj wait.obj wake.obj whrlpool.obj winpipes.obj xtr.obj xtrcrypt.obj zdeflate.obj zinflate.obj zlib.obj +LIB_OBJS = cryptlib.obj cpu.obj integer.obj 3way.obj adler32.obj algebra.obj algparam.obj arc4.obj aria-simd.obj aria.obj ariatab.obj asn.obj authenc.obj base32.obj base64.obj basecode.obj bfinit.obj blake2-simd.obj blake2.obj blowfish.obj blumshub.obj camellia.obj cast.obj casts.obj cbcmac.obj ccm.obj chacha.obj cham.obj cham-simd.obj channels.obj cmac.obj crc-simd.obj crc.obj default.obj des.obj dessp.obj dh.obj dh2.obj dll.obj dsa.obj eax.obj ec2n.obj eccrypto.obj ecp.obj elgamal.obj emsa2.obj eprecomp.obj esign.obj files.obj filters.obj fips140.obj fipstest.obj gcm-simd.obj gcm.obj gf256.obj gf2_32.obj gf2n.obj gfpcrypt.obj gost.obj gzip.obj hc128.obj hc256.obj hex.obj hight.obj hmac.obj hrtimer.obj ida.obj idea.obj iterhash.obj kalyna.obj kalynatab.obj keccak.obj lea.obj lea-simd.obj luc.obj mars.obj marss.obj md2.obj md4.obj md5.obj misc.obj modes.obj mqueue.obj mqv.obj nbtheory.obj neon-simd.obj oaep.obj osrng.obj padlkrng.obj panama.obj pkcspad.obj poly1305.obj polynomi.obj pssr.obj pubkey.obj queue.obj rabin.obj randpool.obj rabbit.obj rc2.obj rc5.obj rc6.obj rdrand.obj rdtables.obj rijndael-simd.obj rijndael.obj ripemd.obj rng.obj rsa.obj rw.obj safer.obj salsa.obj scrypt.obj seal.obj seed.obj serpent.obj sha-simd.obj sha.obj sha3.obj shacal2-simd.obj shacal2.obj shark.obj sharkbox.obj simeck-simd.obj simeck.obj simon.obj simon64-simd.obj simon128-simd.obj skipjack.obj sm3.obj sm4.obj sm4-simd.obj sosemanuk.obj speck.obj speck64-simd.obj speck128-simd.obj square.obj squaretb.obj sse-simd.obj strciphr.obj tea.obj tftables.obj threefish.obj tiger.obj tigertab.obj ttmac.obj tweetnacl.obj twofish.obj vmac.obj wake.obj whrlpool.obj xtr.obj xtrcrypt.obj zdeflate.obj zinflate.obj zlib.obj TEST_SRCS = bench1.cpp bench2.cpp bench3.cpp test.cpp validat0.cpp validat1.cpp validat2.cpp validat3.cpp validat4.cpp validat5.cpp validat6.cpp validat7.cpp validat8.cpp validat9.cpp validat10.cpp datatest.cpp regtest1.cpp regtest2.cpp regtest3.cpp regtest4.cpp fipsalgt.cpp dlltest.cpp fipstest.cpp @@ -108,7 +106,7 @@ ASFLAGS = /nologo /D_M_X86 /W3 /Cx /Zi /safeseh LIB_SRCS = $(LIB_SRCS) rdrand.cpp rdrand.asm LIB_OBJS = $(LIB_OBJS) rdrand.obj rdrand-x86.obj LDFLAGS = $(LDFLAGS) /MACHINE:X86 -LDLIBS = $(LDLIBS) ws2_32.lib kernel32.lib +LDLIBS = $(LDLIBS) kernel32.lib !ENDIF # May need $(VCINSTALLDIR)\bin\amd64\ml64.exe @@ -121,7 +119,7 @@ ASFLAGS = /nologo /D_M_X64 /W3 /Cx /Zi LIB_SRCS = $(LIB_SRCS) rdrand.cpp rdrand.asm LIB_OBJS = $(LIB_OBJS) rdrand.obj rdrand-x64.obj x64masm.obj x64dll.obj LDFLAGS = $(LDFLAGS) /MACHINE:X64 -LDLIBS = $(LDLIBS) ws2_32.lib kernel32.lib +LDLIBS = $(LDLIBS) kernel32.lib !ENDIF # We still don't know what we need for ARM64 on Windows. ARM64 and arm64 may be incorrect @@ -131,7 +129,7 @@ CXXFLAGS = $(CXXFLAGS) /DWINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP LIB_SRCS = $(LIB_SRCS) neon-simd.cpp LIB_OBJS = $(LIB_OBJS) neon-simd.obj # CXXFLAGS = $(CXXFLAGS) /DWINAPI_FAMILY=WINAPI_FAMILY_APP -# LDLIBS = $(LDLIBS) ws2_32.lib +# LDLIBS = $(LDLIBS) !ENDIF all: cryptest.exe diff --git a/cryptlib.cpp b/cryptlib.cpp index 8c1de4e2..81ff4b16 100644 --- a/cryptlib.cpp +++ b/cryptlib.cpp @@ -22,17 +22,11 @@ #include "fips140.h" #include "argnames.h" #include "fltrimpl.h" -#include "trdlocal.h" #include "osrng.h" #include "secblock.h" #include "smartptr.h" #include "stdcpp.h" -// http://www.cygwin.com/faq.html#faq.api.winsock -#if (defined(__CYGWIN__) || defined(__CYGWIN32__)) && defined(PREFER_WINDOWS_STYLE_SOCKETS) -# error Cygwin does not support Windows style sockets. See http://www.cygwin.com/faq.html#faq.api.winsock -#endif - NAMESPACE_BEGIN(CryptoPP) CRYPTOPP_COMPILE_ASSERT(sizeof(byte) == 1); diff --git a/cryptlib.h b/cryptlib.h index 722b8181..1b0c1791 100644 --- a/cryptlib.h +++ b/cryptlib.h @@ -48,9 +48,9 @@
Compression
Deflator, Inflator, Gzip, Gunzip, ZlibCompressor, ZlibDecompressor
Input Source Classes
- StringSource, ArraySource, FileSource, SocketSource, WindowsPipeSource, RandomNumberSource + StringSource, ArraySource, FileSource, RandomNumberSource
Output Sink Classes
- StringSinkTemplate, StringSink, ArraySink, FileSink, SocketSink, WindowsPipeSink, RandomNumberSink + StringSinkTemplate, StringSink, ArraySink, FileSink, RandomNumberSink
Filter Wrappers
StreamTransformationFilter, AuthenticatedEncryptionFilter, AuthenticatedDecryptionFilter, HashFilter, HashVerificationFilter, SignerFilter, SignatureVerificationFilter @@ -58,7 +58,7 @@ HexEncoder, HexDecoder, Base64Encoder, Base64Decoder, Base64URLEncoder, Base64URLDecoder, Base32Encoder, Base32Decoder
Wrappers for OS features
- Timer, Socket, WindowsHandle, ThreadLocalStorage, ThreadUserTimer + Timer, ThreadUserTimer diff --git a/cryptlib.vcxproj b/cryptlib.vcxproj index 042fab7f..6115e9f0 100644 --- a/cryptlib.vcxproj +++ b/cryptlib.vcxproj @@ -257,7 +257,6 @@ - @@ -308,7 +307,6 @@ - @@ -322,15 +320,12 @@ - - - @@ -460,7 +455,6 @@ - @@ -507,7 +501,6 @@ - @@ -517,16 +510,13 @@ - - - diff --git a/cryptlib.vcxproj.filters b/cryptlib.vcxproj.filters index 6d37edbd..5c178559 100644 --- a/cryptlib.vcxproj.filters +++ b/cryptlib.vcxproj.filters @@ -269,9 +269,6 @@ Source Files - - Source Files - Source Files @@ -425,9 +422,6 @@ Source Files - - Source Files - Source Files @@ -458,9 +452,6 @@ Source Files - - Source Files - Source Files @@ -473,18 +464,12 @@ Source Files - - Source Files - Source Files Source Files - - Source Files - Source Files @@ -774,9 +759,6 @@ Header Files - - Header Files - Header Files @@ -918,9 +900,6 @@ Header Files - - Header Files - Header Files @@ -945,9 +924,6 @@ Header Files - - Header Files - Header Files @@ -963,18 +939,12 @@ Header Files - - Header Files - Header Files Header Files - - Header Files - Header Files diff --git a/dll.h b/dll.h index bbb2257a..f923026c 100644 --- a/dll.h +++ b/dll.h @@ -40,7 +40,6 @@ #include "rw.h" #include "sha.h" #include "skipjack.h" -#include "trdlocal.h" #ifdef CRYPTOPP_IMPORTS diff --git a/fips140.cpp b/fips140.cpp index f95f4005..1f911fc5 100644 --- a/fips140.cpp +++ b/fips140.cpp @@ -6,7 +6,6 @@ #include "fips140.h" #include "misc.h" -#include "trdlocal.h" // needs to be included last for cygwin NAMESPACE_BEGIN(CryptoPP) @@ -16,10 +15,6 @@ NAMESPACE_BEGIN(CryptoPP) #define CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 0 #endif -#if (CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 && !defined(THREADS_AVAILABLE)) -#error FIPS 140-2 compliance requires the availability of thread local storage. -#endif - #if (CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 && !defined(OS_RNG_AVAILABLE)) #error FIPS 140-2 compliance requires the availability of OS provided RNG. #endif @@ -41,29 +36,24 @@ PowerUpSelfTestStatus CRYPTOPP_API GetPowerUpSelfTestStatus() return g_powerUpSelfTestStatus; } -#if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 -ThreadLocalStorage & AccessPowerUpSelfTestInProgress() -{ - static ThreadLocalStorage selfTestInProgress; - return selfTestInProgress; -} -#endif +// One variable for all threads for compatibility. Previously this +// was a ThreadLocalStorage variable, which is per-thread. Also see +// https://github.com/weidai11/cryptopp/issues/208 +static bool s_inProgress = false; bool PowerUpSelfTestInProgressOnThisThread() { #if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 - return AccessPowerUpSelfTestInProgress().GetValue() != NULLPTR; -#else - CRYPTOPP_ASSERT(false); // should not be called - return false; + return s_inProgress; #endif + return false; } void SetPowerUpSelfTestInProgressOnThisThread(bool inProgress) { CRYPTOPP_UNUSED(inProgress); #if CRYPTOPP_ENABLE_COMPLIANCE_WITH_FIPS_140_2 - AccessPowerUpSelfTestInProgress().SetValue((void *)inProgress); + s_inProgress = inProgress; #endif } diff --git a/network.cpp b/network.cpp deleted file mode 100644 index c7873d0e..00000000 --- a/network.cpp +++ /dev/null @@ -1,554 +0,0 @@ -// network.cpp - originally written and placed in the public domain by Wei Dai - -#include "pch.h" - -#include "network.h" - -#if !defined(NO_OS_DEPENDENCE) && defined(SOCKETS_AVAILABLE) - -#include "wait.h" - -#define CRYPTOPP_TRACE_NETWORK 0 - -NAMESPACE_BEGIN(CryptoPP) - -lword LimitedBandwidth::ComputeCurrentTransceiveLimit() -{ - if (!m_maxBytesPerSecond) - return ULONG_MAX; - - const double curTime = GetCurTimeAndCleanUp(); - CRYPTOPP_UNUSED(curTime); - - lword total = 0; - for (OpQueue::size_type i=0; i!=m_ops.size(); ++i) - total += m_ops[i].second; - return SaturatingSubtract(m_maxBytesPerSecond, total); -} - -double LimitedBandwidth::TimeToNextTransceive() -{ - if (!m_maxBytesPerSecond) - return 0; - - if (!m_nextTransceiveTime) - ComputeNextTransceiveTime(); - - return SaturatingSubtract(m_nextTransceiveTime, m_timer.ElapsedTimeAsDouble()); -} - -void LimitedBandwidth::NoteTransceive(lword size) -{ - if (m_maxBytesPerSecond) - { - double curTime = GetCurTimeAndCleanUp(); - m_ops.push_back(std::make_pair(curTime, size)); - m_nextTransceiveTime = 0; - } -} - -void LimitedBandwidth::ComputeNextTransceiveTime() -{ - double curTime = GetCurTimeAndCleanUp(); - lword total = 0; - for (unsigned int i=0; i!=m_ops.size(); ++i) - total += m_ops[i].second; - m_nextTransceiveTime = - (total < m_maxBytesPerSecond) ? curTime : m_ops.front().first + 1000; -} - -double LimitedBandwidth::GetCurTimeAndCleanUp() -{ - if (!m_maxBytesPerSecond) - return 0; - - double curTime = m_timer.ElapsedTimeAsDouble(); - while (m_ops.size() && (m_ops.front().first + 1000 < curTime)) - m_ops.pop_front(); - return curTime; -} - -void LimitedBandwidth::GetWaitObjects(WaitObjectContainer &container, const CallStack &callStack) -{ - double nextTransceiveTime = TimeToNextTransceive(); - if (nextTransceiveTime) - container.ScheduleEvent(nextTransceiveTime, CallStack("LimitedBandwidth::GetWaitObjects()", &callStack)); -} - -// ************************************************************* - -size_t NonblockingSource::GeneralPump2( - lword& byteCount, bool blockingOutput, - unsigned long maxTime, bool checkDelimiter, byte delimiter) -{ - m_blockedBySpeedLimit = false; - - if (!GetMaxBytesPerSecond()) - { - size_t ret = DoPump(byteCount, blockingOutput, maxTime, checkDelimiter, delimiter); - m_doPumpBlocked = (ret != 0); - return ret; - } - - bool forever = (maxTime == INFINITE_TIME); - unsigned long timeToGo = maxTime; - Timer timer(Timer::MILLISECONDS, forever); - lword maxSize = byteCount; - byteCount = 0; - - timer.StartTimer(); - - while (true) - { - lword curMaxSize = UnsignedMin(ComputeCurrentTransceiveLimit(), maxSize - byteCount); - - if (curMaxSize || m_doPumpBlocked) - { - if (!forever) timeToGo = SaturatingSubtract(maxTime, timer.ElapsedTime()); - size_t ret = DoPump(curMaxSize, blockingOutput, timeToGo, checkDelimiter, delimiter); - m_doPumpBlocked = (ret != 0); - if (curMaxSize) - { - NoteTransceive(curMaxSize); - byteCount += curMaxSize; - } - if (ret) - return ret; - } - - if (maxSize != ULONG_MAX && byteCount >= maxSize) - break; - - if (!forever) - { - timeToGo = SaturatingSubtract(maxTime, timer.ElapsedTime()); - if (!timeToGo) - break; - } - - double waitTime = TimeToNextTransceive(); - if (!forever && waitTime > timeToGo) - { - m_blockedBySpeedLimit = true; - break; - } - - WaitObjectContainer container; - LimitedBandwidth::GetWaitObjects(container, CallStack("NonblockingSource::GeneralPump2() - speed limit", NULLPTR)); - container.Wait((unsigned long)waitTime); - } - - return 0; -} - -size_t NonblockingSource::PumpMessages2(unsigned int &messageCount, bool blocking) -{ - if (messageCount == 0) - return 0; - - messageCount = 0; - - lword byteCount; - do { - byteCount = LWORD_MAX; - RETURN_IF_NONZERO(Pump2(byteCount, blocking)); - } while(byteCount == LWORD_MAX); - - if (!m_messageEndSent && SourceExhausted()) - { - RETURN_IF_NONZERO(AttachedTransformation()->Put2(NULLPTR, 0, GetAutoSignalPropagation(), true)); - m_messageEndSent = true; - messageCount = 1; - } - return 0; -} - -lword NonblockingSink::TimedFlush(unsigned long maxTime, size_t targetSize) -{ - m_blockedBySpeedLimit = false; - - size_t curBufSize = GetCurrentBufferSize(); - if (curBufSize <= targetSize && (targetSize || !EofPending())) - return 0; - - if (!GetMaxBytesPerSecond()) - return DoFlush(maxTime, targetSize); - - bool forever = (maxTime == INFINITE_TIME); - unsigned long timeToGo = maxTime; - Timer timer(Timer::MILLISECONDS, forever); - lword totalFlushed = 0; - - timer.StartTimer(); - - while (true) - { - size_t flushSize = UnsignedMin(curBufSize - targetSize, ComputeCurrentTransceiveLimit()); - if (flushSize || EofPending()) - { - if (!forever) timeToGo = SaturatingSubtract(maxTime, timer.ElapsedTime()); - size_t ret = (size_t)DoFlush(timeToGo, curBufSize - flushSize); - if (ret) - { - NoteTransceive(ret); - curBufSize -= ret; - totalFlushed += ret; - } - } - - if (curBufSize <= targetSize && (targetSize || !EofPending())) - break; - - if (!forever) - { - timeToGo = SaturatingSubtract(maxTime, timer.ElapsedTime()); - if (!timeToGo) - break; - } - - double waitTime = TimeToNextTransceive(); - if (!forever && waitTime > timeToGo) - { - m_blockedBySpeedLimit = true; - break; - } - - WaitObjectContainer container; - LimitedBandwidth::GetWaitObjects(container, CallStack("NonblockingSink::TimedFlush() - speed limit", NULLPTR)); - container.Wait((unsigned long)waitTime); - } - - return totalFlushed; -} - -bool NonblockingSink::IsolatedFlush(bool hardFlush, bool blocking) -{ - TimedFlush(blocking ? INFINITE_TIME : 0); - return hardFlush && (!!GetCurrentBufferSize() || EofPending()); -} - -// ************************************************************* - -NetworkSource::NetworkSource(BufferedTransformation *attachment) - : NonblockingSource(attachment), m_buf(1024*16) - , m_putSize(0), m_dataBegin(0), m_dataEnd(0) - , m_waitingForResult(false), m_outputBlocked(false) -{ -} - -unsigned int NetworkSource::GetMaxWaitObjectCount() const -{ - return LimitedBandwidth::GetMaxWaitObjectCount() - + GetReceiver().GetMaxWaitObjectCount() - + AttachedTransformation()->GetMaxWaitObjectCount(); -} - -void NetworkSource::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) -{ - if (BlockedBySpeedLimit()) - LimitedBandwidth::GetWaitObjects(container, CallStack("NetworkSource::GetWaitObjects() - speed limit", &callStack)); - else if (!m_outputBlocked) - { - if (m_dataBegin == m_dataEnd) - AccessReceiver().GetWaitObjects(container, CallStack("NetworkSource::GetWaitObjects() - no data", &callStack)); - else - container.SetNoWait(CallStack("NetworkSource::GetWaitObjects() - have data", &callStack)); - } - - AttachedTransformation()->GetWaitObjects(container, CallStack("NetworkSource::GetWaitObjects() - attachment", &callStack)); -} - -size_t NetworkSource::DoPump(lword &byteCount, bool blockingOutput, unsigned long maxTime, bool checkDelimiter, byte delimiter) -{ - NetworkReceiver &receiver = AccessReceiver(); - - lword maxSize = byteCount; - byteCount = 0; - bool forever = maxTime == INFINITE_TIME; - Timer timer(Timer::MILLISECONDS, forever); - BufferedTransformation *t = AttachedTransformation(); - - if (m_outputBlocked) - goto DoOutput; - - while (true) - { - if (m_dataBegin == m_dataEnd) - { - if (receiver.EofReceived()) - break; - - if (m_waitingForResult) - { - if (receiver.MustWaitForResult() && - !receiver.Wait(SaturatingSubtract(maxTime, timer.ElapsedTime()), - CallStack("NetworkSource::DoPump() - wait receive result", NULLPTR))) - break; - - unsigned int recvResult = receiver.GetReceiveResult(); -#if CRYPTOPP_TRACE_NETWORK - OutputDebugStringA((IntToString((unsigned int)this) + ": Received " + IntToString(recvResult) + " bytes\n").c_str()); -#endif - m_dataEnd += recvResult; - m_waitingForResult = false; - - if (!receiver.MustWaitToReceive() && !receiver.EofReceived() && m_dataEnd != m_buf.size()) - goto ReceiveNoWait; - } - else - { - m_dataEnd = m_dataBegin = 0; - - if (receiver.MustWaitToReceive()) - { - if (!receiver.Wait(SaturatingSubtract(maxTime, timer.ElapsedTime()), - CallStack("NetworkSource::DoPump() - wait receive", NULLPTR))) - break; - - receiver.Receive(m_buf+m_dataEnd, m_buf.size()-m_dataEnd); - m_waitingForResult = true; - } - else - { -ReceiveNoWait: - m_waitingForResult = true; - // call Receive repeatedly as long as data is immediately available, - // because some receivers tend to return data in small pieces -#if CRYPTOPP_TRACE_NETWORK - OutputDebugStringA((IntToString((unsigned int)this) + ": Receiving " + IntToString(m_buf.size()-m_dataEnd) + " bytes\n").c_str()); -#endif - while (receiver.Receive(m_buf+m_dataEnd, m_buf.size()-m_dataEnd)) - { - unsigned int recvResult = receiver.GetReceiveResult(); -#if CRYPTOPP_TRACE_NETWORK - OutputDebugStringA((IntToString((unsigned int)this) + ": Received " + IntToString(recvResult) + " bytes\n").c_str()); -#endif - m_dataEnd += recvResult; - if (receiver.EofReceived() || m_dataEnd > m_buf.size() /2) - { - m_waitingForResult = false; - break; - } - } - } - } - } - else - { - m_putSize = UnsignedMin(m_dataEnd - m_dataBegin, maxSize - byteCount); - - if (checkDelimiter) - m_putSize = std::find(m_buf+m_dataBegin, m_buf+m_dataBegin+m_putSize, delimiter) - (m_buf+m_dataBegin); - -DoOutput: - size_t result = t->PutModifiable2(m_buf+m_dataBegin, m_putSize, 0, forever || blockingOutput); - if (result) - { - if (t->Wait(SaturatingSubtract(maxTime, timer.ElapsedTime()), - CallStack("NetworkSource::DoPump() - wait attachment", NULLPTR))) - goto DoOutput; - else - { - m_outputBlocked = true; - return result; - } - } - m_outputBlocked = false; - - byteCount += m_putSize; - m_dataBegin += m_putSize; - if (checkDelimiter && m_dataBegin < m_dataEnd && m_buf[m_dataBegin] == delimiter) - break; - if (maxSize != ULONG_MAX && byteCount == maxSize) - break; - // once time limit is reached, return even if there is more data waiting - // but make 0 a special case so caller can request a large amount of data to be - // pumped as long as it is immediately available - if (maxTime > 0 && timer.ElapsedTime() > maxTime) - break; - } - } - - return 0; -} - -// ************************************************************* - -NetworkSink::NetworkSink(unsigned int maxBufferSize, unsigned int autoFlushBound) - : m_maxBufferSize(maxBufferSize), m_autoFlushBound(autoFlushBound) - , m_needSendResult(false), m_wasBlocked(false), m_eofState(EOF_NONE) - , m_buffer(STDMIN(16U*1024U+256, maxBufferSize)), m_skipBytes(0) - , m_speedTimer(Timer::MILLISECONDS), m_byteCountSinceLastTimerReset(0) - , m_currentSpeed(0), m_maxObservedSpeed(0) -{ -} - -float NetworkSink::ComputeCurrentSpeed() -{ - if (m_speedTimer.ElapsedTime() > 1000) - { - m_currentSpeed = m_byteCountSinceLastTimerReset * 1000 / m_speedTimer.ElapsedTime(); - m_maxObservedSpeed = STDMAX(m_currentSpeed, m_maxObservedSpeed * 0.98f); - m_byteCountSinceLastTimerReset = 0; - m_speedTimer.StartTimer(); -// OutputDebugStringA(("max speed: " + IntToString((int)m_maxObservedSpeed) + " current speed: " + IntToString((int)m_currentSpeed) + "\n").c_str()); - } - return m_currentSpeed; -} - -float NetworkSink::GetMaxObservedSpeed() const -{ - lword m = GetMaxBytesPerSecond(); - return m ? STDMIN(m_maxObservedSpeed, static_cast(m)) : m_maxObservedSpeed; -} - -unsigned int NetworkSink::GetMaxWaitObjectCount() const -{ - return LimitedBandwidth::GetMaxWaitObjectCount() + GetSender().GetMaxWaitObjectCount(); -} - -void NetworkSink::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) -{ - if (BlockedBySpeedLimit()) - LimitedBandwidth::GetWaitObjects(container, CallStack("NetworkSink::GetWaitObjects() - speed limit", &callStack)); - else if (m_wasBlocked) - AccessSender().GetWaitObjects(container, CallStack("NetworkSink::GetWaitObjects() - was blocked", &callStack)); - else if (!m_buffer.IsEmpty()) - AccessSender().GetWaitObjects(container, CallStack("NetworkSink::GetWaitObjects() - buffer not empty", &callStack)); - else if (EofPending()) - AccessSender().GetWaitObjects(container, CallStack("NetworkSink::GetWaitObjects() - EOF pending", &callStack)); -} - -size_t NetworkSink::Put2(const byte *inString, size_t length, int messageEnd, bool blocking) -{ - if (m_eofState == EOF_DONE) - { - if (length || messageEnd) - throw Exception(Exception::OTHER_ERROR, "NetworkSink::Put2() being called after EOF had been sent"); - - return 0; - } - - if (m_eofState > EOF_NONE) - goto EofSite; - - { - if (m_skipBytes) - { - CRYPTOPP_ASSERT(length >= m_skipBytes); - inString += m_skipBytes; - length -= m_skipBytes; - } - - m_buffer.Put(inString, length); - - if (!blocking || m_buffer.CurrentSize() > m_autoFlushBound) - TimedFlush(0, 0); - - size_t targetSize = messageEnd ? 0 : m_maxBufferSize; - if (blocking) - TimedFlush(INFINITE_TIME, targetSize); - - if (m_buffer.CurrentSize() > targetSize) - { - CRYPTOPP_ASSERT(!blocking); - m_wasBlocked = true; - m_skipBytes += length; - size_t blockedBytes = UnsignedMin(length, m_buffer.CurrentSize() - targetSize); - return STDMAX(blockedBytes, 1); - } - - m_wasBlocked = false; - m_skipBytes = 0; - } - - if (messageEnd) - { - m_eofState = EOF_PENDING_SEND; - - EofSite: - TimedFlush(blocking ? INFINITE_TIME : 0, 0); - if (m_eofState != EOF_DONE) - return 1; - } - - return 0; -} - -lword NetworkSink::DoFlush(unsigned long maxTime, size_t targetSize) -{ - NetworkSender &sender = AccessSender(); - - bool forever = maxTime == INFINITE_TIME; - Timer timer(Timer::MILLISECONDS, forever); - unsigned int totalFlushSize = 0; - - while (true) - { - if (m_buffer.CurrentSize() <= targetSize) - break; - - if (m_needSendResult) - { - if (sender.MustWaitForResult() && - !sender.Wait(SaturatingSubtract(maxTime, timer.ElapsedTime()), - CallStack("NetworkSink::DoFlush() - wait send result", NULLPTR))) - break; - - unsigned int sendResult = sender.GetSendResult(); -#if CRYPTOPP_TRACE_NETWORK - OutputDebugStringA((IntToString((unsigned int)this) + ": Sent " + IntToString(sendResult) + " bytes\n").c_str()); -#endif - m_buffer.Skip(sendResult); - totalFlushSize += sendResult; - m_needSendResult = false; - - if (!m_buffer.AnyRetrievable()) - break; - } - - unsigned long timeOut = maxTime ? SaturatingSubtract(maxTime, timer.ElapsedTime()) : 0; - if (sender.MustWaitToSend() && !sender.Wait(timeOut, CallStack("NetworkSink::DoFlush() - wait send", NULLPTR))) - break; - - size_t contiguousSize = 0; - const byte *block = m_buffer.Spy(contiguousSize); - -#if CRYPTOPP_TRACE_NETWORK - OutputDebugStringA((IntToString((unsigned int)this) + ": Sending " + IntToString(contiguousSize) + " bytes\n").c_str()); -#endif - sender.Send(block, contiguousSize); - m_needSendResult = true; - - if (maxTime > 0 && timeOut == 0) - break; // once time limit is reached, return even if there is more data waiting - } - - m_byteCountSinceLastTimerReset += totalFlushSize; - ComputeCurrentSpeed(); - - if (m_buffer.IsEmpty() && !m_needSendResult) - { - if (m_eofState == EOF_PENDING_SEND) - { - sender.SendEof(); - m_eofState = sender.MustWaitForEof() ? EOF_PENDING_DELIVERY : EOF_DONE; - } - - while (m_eofState == EOF_PENDING_DELIVERY) - { - unsigned long timeOut = maxTime ? SaturatingSubtract(maxTime, timer.ElapsedTime()) : 0; - if (!sender.Wait(timeOut, CallStack("NetworkSink::DoFlush() - wait EOF", NULLPTR))) - break; - - if (sender.EofSent()) - m_eofState = EOF_DONE; - } - } - - return totalFlushSize; -} - -NAMESPACE_END - -#endif // #ifdef SOCKETS_AVAILABLE diff --git a/network.h b/network.h deleted file mode 100644 index 3ea90dee..00000000 --- a/network.h +++ /dev/null @@ -1,234 +0,0 @@ -#ifndef CRYPTOPP_NETWORK_H -#define CRYPTOPP_NETWORK_H - -#include "config.h" - -#if !defined(NO_OS_DEPENDENCE) && defined(SOCKETS_AVAILABLE) - -#include "filters.h" -#include "hrtimer.h" -#include "stdcpp.h" - -NAMESPACE_BEGIN(CryptoPP) - -class LimitedBandwidth -{ -public: - LimitedBandwidth(lword maxBytesPerSecond = 0) - : m_maxBytesPerSecond(maxBytesPerSecond), m_timer(Timer::MILLISECONDS) - , m_nextTransceiveTime(0) - { m_timer.StartTimer(); } - - lword GetMaxBytesPerSecond() const - { return m_maxBytesPerSecond; } - - void SetMaxBytesPerSecond(lword v) - { m_maxBytesPerSecond = v; } - - lword ComputeCurrentTransceiveLimit(); - - double TimeToNextTransceive(); - - void NoteTransceive(lword size); - -public: - /*! GetWaitObjects() must be called despite the 0 return from GetMaxWaitObjectCount(); - the 0 is because the ScheduleEvent() method is used instead of adding a wait object */ - unsigned int GetMaxWaitObjectCount() const { return 0; } - void GetWaitObjects(WaitObjectContainer &container, const CallStack &callStack); - -private: - lword m_maxBytesPerSecond; - - typedef std::deque > OpQueue; - OpQueue m_ops; - - Timer m_timer; - double m_nextTransceiveTime; - - void ComputeNextTransceiveTime(); - double GetCurTimeAndCleanUp(); -}; - -/// a Source class that can pump from a device for a specified amount of time. -class CRYPTOPP_NO_VTABLE NonblockingSource : public AutoSignaling, public LimitedBandwidth -{ -public: - NonblockingSource(BufferedTransformation *attachment) - : m_messageEndSent(false) , m_doPumpBlocked(false), m_blockedBySpeedLimit(false) {Detach(attachment);} - - /// \name NONBLOCKING SOURCE - //@{ - - /// pump up to maxSize bytes using at most maxTime milliseconds - /*! If checkDelimiter is true, pump up to delimiter, which itself is not extracted or pumped. */ - size_t GeneralPump2(lword &byteCount, bool blockingOutput=true, unsigned long maxTime=INFINITE_TIME, bool checkDelimiter=false, byte delimiter='\n'); - - lword GeneralPump(lword maxSize=LWORD_MAX, unsigned long maxTime=INFINITE_TIME, bool checkDelimiter=false, byte delimiter='\n') - { - GeneralPump2(maxSize, true, maxTime, checkDelimiter, delimiter); - return maxSize; - } - lword TimedPump(unsigned long maxTime) - {return GeneralPump(LWORD_MAX, maxTime);} - lword PumpLine(byte delimiter='\n', lword maxSize=1024) - {return GeneralPump(maxSize, INFINITE_TIME, true, delimiter);} - - size_t Pump2(lword &byteCount, bool blocking=true) - {return GeneralPump2(byteCount, blocking, blocking ? INFINITE_TIME : 0);} - size_t PumpMessages2(unsigned int &messageCount, bool blocking=true); - //@} - -protected: - virtual size_t DoPump(lword &byteCount, bool blockingOutput, - unsigned long maxTime, bool checkDelimiter, byte delimiter) =0; - - bool BlockedBySpeedLimit() const { return m_blockedBySpeedLimit; } - -private: - bool m_messageEndSent, m_doPumpBlocked, m_blockedBySpeedLimit; -}; - -/// Network Receiver -class CRYPTOPP_NO_VTABLE NetworkReceiver : public Waitable -{ -public: - virtual bool MustWaitToReceive() {return false;} - virtual bool MustWaitForResult() {return false;} - /// receive data from network source, returns whether result is immediately available - virtual bool Receive(byte* buf, size_t bufLen) =0; - virtual unsigned int GetReceiveResult() =0; - virtual bool EofReceived() const =0; -}; - -class CRYPTOPP_NO_VTABLE NonblockingSinkInfo -{ -public: - virtual ~NonblockingSinkInfo() {} - virtual size_t GetMaxBufferSize() const =0; - virtual size_t GetCurrentBufferSize() const =0; - virtual bool EofPending() const =0; - /// compute the current speed of this sink in bytes per second - virtual float ComputeCurrentSpeed() =0; - /// get the maximum observed speed of this sink in bytes per second - virtual float GetMaxObservedSpeed() const =0; -}; - -/// a Sink class that queues input and can flush to a device for a specified amount of time. -class CRYPTOPP_NO_VTABLE NonblockingSink : public Sink, public NonblockingSinkInfo, public LimitedBandwidth -{ -public: - NonblockingSink() : m_blockedBySpeedLimit(false) {} - - bool IsolatedFlush(bool hardFlush, bool blocking); - - /// flush to device for no more than maxTime milliseconds - /*! This function will repeatedly attempt to flush data to some device, until - the queue is empty, or a total of maxTime milliseconds have elapsed. - If maxTime == 0, at least one attempt will be made to flush some data, but - it is likely that not all queued data will be flushed, even if the device - is ready to receive more data without waiting. If you want to flush as much data - as possible without waiting for the device, call this function in a loop. - For example: while (sink.TimedFlush(0) > 0) {} - \return number of bytes flushed - */ - lword TimedFlush(unsigned long maxTime, size_t targetSize = 0); - - virtual void SetMaxBufferSize(size_t maxBufferSize) =0; - /// set a bound which will cause sink to flush if exceeded by GetCurrentBufferSize() - virtual void SetAutoFlushBound(size_t bound) =0; - -protected: - virtual lword DoFlush(unsigned long maxTime, size_t targetSize) = 0; - - bool BlockedBySpeedLimit() const { return m_blockedBySpeedLimit; } - -private: - bool m_blockedBySpeedLimit; -}; - -/// Network Sender -class CRYPTOPP_NO_VTABLE NetworkSender : public Waitable -{ -public: - virtual bool MustWaitToSend() {return false;} - virtual bool MustWaitForResult() {return false;} - virtual void Send(const byte* buf, size_t bufLen) =0; - virtual unsigned int GetSendResult() =0; - virtual bool MustWaitForEof() {return false;} - virtual void SendEof() =0; - virtual bool EofSent() {return false;} // implement if MustWaitForEof() == true -}; - -/// Network Source -class CRYPTOPP_NO_VTABLE NetworkSource : public NonblockingSource -{ -public: - NetworkSource(BufferedTransformation *attachment); - - unsigned int GetMaxWaitObjectCount() const; - void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); - - bool SourceExhausted() const {return m_dataBegin == m_dataEnd && GetReceiver().EofReceived();} - -protected: - size_t DoPump(lword &byteCount, bool blockingOutput, unsigned long maxTime, bool checkDelimiter, byte delimiter); - - virtual NetworkReceiver & AccessReceiver() =0; - const NetworkReceiver & GetReceiver() const {return const_cast(this)->AccessReceiver();} - -private: - SecByteBlock m_buf; - size_t m_putSize, m_dataBegin, m_dataEnd; - bool m_waitingForResult, m_outputBlocked; -}; - -/// Network Sink -class CRYPTOPP_NO_VTABLE NetworkSink : public NonblockingSink -{ -public: - NetworkSink(unsigned int maxBufferSize, unsigned int autoFlushBound); - - unsigned int GetMaxWaitObjectCount() const; - void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); - - size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking); - - void SetMaxBufferSize(size_t maxBufferSize) {m_maxBufferSize = maxBufferSize; m_buffer.SetNodeSize(UnsignedMin(maxBufferSize, 16U*1024U+256U));} - void SetAutoFlushBound(size_t bound) {m_autoFlushBound = bound;} - - size_t GetMaxBufferSize() const {return m_maxBufferSize;} - size_t GetCurrentBufferSize() const {return (size_t)m_buffer.CurrentSize();} - - void ClearBuffer() { m_buffer.Clear(); } - - bool EofPending() const { return m_eofState > EOF_NONE && m_eofState < EOF_DONE; } - - /// compute the current speed of this sink in bytes per second - float ComputeCurrentSpeed(); - /// get the maximum observed speed of this sink in bytes per second - float GetMaxObservedSpeed() const; - -protected: - lword DoFlush(unsigned long maxTime, size_t targetSize); - - virtual NetworkSender & AccessSender() =0; - const NetworkSender & GetSender() const {return const_cast(this)->AccessSender();} - -private: - enum EofState { EOF_NONE, EOF_PENDING_SEND, EOF_PENDING_DELIVERY, EOF_DONE }; - - size_t m_maxBufferSize, m_autoFlushBound; - bool m_needSendResult, m_wasBlocked; - EofState m_eofState; - ByteQueue m_buffer; - size_t m_skipBytes; - Timer m_speedTimer; - float m_byteCountSinceLastTimerReset, m_currentSpeed, m_maxObservedSpeed; -}; - -NAMESPACE_END - -#endif // SOCKETS_AVAILABLE - -#endif // CRYPTOPP_NETWORK_H diff --git a/socketft.cpp b/socketft.cpp deleted file mode 100644 index 00c6b603..00000000 --- a/socketft.cpp +++ /dev/null @@ -1,673 +0,0 @@ -// socketft.cpp - originally written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "config.h" - -#if !defined(NO_OS_DEPENDENCE) && defined(SOCKETS_AVAILABLE) - -#include "socketft.h" -#include "wait.h" - -// Windows 8, Windows Server 2012, and Windows Phone 8.1 need and -#if defined(CRYPTOPP_WIN32_AVAILABLE) -# if ((WINVER >= 0x0602 /*_WIN32_WINNT_WIN8*/) || (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)) -# include -# include -# define USE_WINDOWS8_API -# endif -#endif - -#ifdef USE_BERKELEY_STYLE_SOCKETS -#include -#include -#include -#include -#include -#include -#endif - -#if defined(CRYPTOPP_MSAN) -# include -#endif - -// From http://groups.google.com/d/msg/cryptopp-users/MzvocLrbIpE/TMCa6LFhCgAJ, -// is a compatibility header and it needs _WIN32_WINNT >= 0x501. -// The work-around should be OK since it won't cross-pollinate into header files. -#if defined(__MINGW32__) && (_WIN32_WINNT < 0x501) -# undef _WIN32_WINNT -# define _WIN32_WINNT 0x501 -#endif - -#ifdef USE_WINDOWS_STYLE_SOCKETS -# pragma comment(lib, "ws2_32.lib") -# if defined(_WIN32_WINNT) && (_WIN32_WINNT < 0x501) -# include -# endif -#endif - -NAMESPACE_BEGIN(CryptoPP) - -#ifdef USE_WINDOWS_STYLE_SOCKETS -const int SOCKET_EINVAL = WSAEINVAL; -const int SOCKET_EWOULDBLOCK = WSAEWOULDBLOCK; -typedef int socklen_t; -#else -const int SOCKET_EINVAL = EINVAL; -const int SOCKET_EWOULDBLOCK = EWOULDBLOCK; -#endif - -// Solaris doesn't have INADDR_NONE -#ifndef INADDR_NONE -# define INADDR_NONE 0xffffffff -#endif /* INADDR_NONE */ - -// Some Windows SDKs do not have INET6_ADDRSTRLEN -#ifndef INET_ADDRSTRLEN -# define INET_ADDRSTRLEN (22) -#endif -#ifndef INET6_ADDRSTRLEN -# define INET6_ADDRSTRLEN (65) -#endif - -#define MAX_ADDRSTRLEN (INET6_ADDRSTRLEN > INET_ADDRSTRLEN ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN) - -// Also see http://stackoverflow.com/a/20816961 and http://github.com/weidai11/cryptopp/issues/322 -#if defined(USE_WINDOWS_STYLE_SOCKETS) -int inet_pton(int af, const char *src, void *dst) -{ -#if CRYPTOPP_MSC_VERSION -# pragma warning(push) -# pragma warning(disable: 4996) -#endif - - // Posix states only src is validated. Avoid a bad dst dereference. - if(!src || !dst) return 0; - - struct sockaddr_storage ss; - ZeroMemory(&ss, sizeof(ss)); - -#if CRYPTOPP_MSC_VERSION >= 1400 - char temp[MAX_ADDRSTRLEN]; - strcpy_s(temp, sizeof(temp), src); -#else - char temp[MAX_ADDRSTRLEN]; - strncpy(temp, src, sizeof(temp)); - temp[MAX_ADDRSTRLEN-1] = '\0'; -#endif - - - int size = sizeof(ss); - if (WSAStringToAddressA(temp, af, NULLPTR, (struct sockaddr *)&ss, &size) == 0) { - switch (af) { - case AF_INET: - *(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr; - return 1; - case AF_INET6: - *(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr; - return 1; - } - } - - ((sockaddr_in *)dst)->sin_addr.s_addr = INADDR_NONE; - return 0; - -#if CRYPTOPP_MSC_VERSION -# pragma warning(pop) -#endif -} -#endif - -Socket::Err::Err(socket_t s, const std::string& operation, int error) - : OS_Error(IO_ERROR, "Socket: " + operation + " operation failed with error " + IntToString(error), operation, error) - , m_s(s) -{ -} - -Socket::~Socket() -{ - if (m_own) - { - try - { - CloseSocket(); - } - catch (const Exception&) - { - CRYPTOPP_ASSERT(0); - } - } -} - -void Socket::AttachSocket(socket_t s, bool own) -{ - if (m_own) - CloseSocket(); - - m_s = s; - m_own = own; - SocketChanged(); -} - -socket_t Socket::DetachSocket() -{ - socket_t s = m_s; - m_s = INVALID_SOCKET; - SocketChanged(); - return s; -} - -void Socket::Create(int nType) -{ - CRYPTOPP_ASSERT(m_s == INVALID_SOCKET); - m_s = socket(AF_INET, nType, 0); - CheckAndHandleError("socket", m_s); - m_own = true; - SocketChanged(); -} - -void Socket::CloseSocket() -{ - if (m_s != INVALID_SOCKET) - { -#ifdef USE_WINDOWS_STYLE_SOCKETS -# if defined(USE_WINDOWS8_API) - BOOL result = CancelIoEx((HANDLE) m_s, NULLPTR); - CRYPTOPP_ASSERT(result || (!result && GetLastError() == ERROR_NOT_FOUND)); - CheckAndHandleError_int("closesocket", closesocket(m_s)); - CRYPTOPP_UNUSED(result); // Used by CRYPTOPP_ASSERT in debug builds -# else - BOOL result = CancelIo((HANDLE) m_s); - CRYPTOPP_ASSERT(result || (!result && GetLastError() == ERROR_NOT_FOUND)); - CheckAndHandleError_int("closesocket", closesocket(m_s)); - CRYPTOPP_UNUSED(result); -# endif -#else - CheckAndHandleError_int("close", close(m_s)); -#endif - m_s = INVALID_SOCKET; - SocketChanged(); - } -} - -void Socket::Bind(unsigned int port, const char *addr) -{ - sockaddr_in sa; - memset(&sa, 0, sizeof(sa)); - sa.sin_family = AF_INET; - - if (addr == NULLPTR) - sa.sin_addr.s_addr = htonl(INADDR_ANY); - else - { - // unsigned long result = inet_addr(addr); - unsigned long result; - if (inet_pton(AF_INET, addr, &result) < 1 || result == INADDR_NONE) - { - SetLastError(SOCKET_EINVAL); - CheckAndHandleError_int("inet_addr", SOCKET_ERROR); - } - sa.sin_addr.s_addr = result; - } - - sa.sin_port = htons((unsigned short)port); - - Bind((sockaddr *)&sa, sizeof(sa)); -} - -void Socket::Bind(const sockaddr *psa, socklen_t saLen) -{ - CRYPTOPP_ASSERT(m_s != INVALID_SOCKET); - // cygwin workaround: needs const_cast - CheckAndHandleError_int("bind", bind(m_s, const_cast(psa), saLen)); -} - -void Socket::Listen(int backlog) -{ - CRYPTOPP_ASSERT(m_s != INVALID_SOCKET); - CheckAndHandleError_int("listen", listen(m_s, backlog)); -} - -bool Socket::Connect(const char *addr, unsigned int port) -{ - CRYPTOPP_ASSERT(addr != NULLPTR); - - sockaddr_in sa; - memset(&sa, 0, sizeof(sa)); - sa.sin_family = AF_INET; - - // Make inet_pton failures non-fatal. - if (!addr || inet_pton(AF_INET, addr, &sa.sin_addr.s_addr) < 1) - sa.sin_addr.s_addr = INADDR_NONE; - - if (sa.sin_addr.s_addr == INADDR_NONE) - { - addrinfo hints, *result = NULLPTR; - memset(&hints, 0, sizeof(hints)); - - hints.ai_socktype = SOCK_STREAM; - hints.ai_family = AF_INET; - - if (getaddrinfo(addr, NULLPTR, &hints, &result) != 0 || result == NULLPTR) - { - freeaddrinfo(result); - SetLastError(SOCKET_EINVAL); - CheckAndHandleError_int("getaddrinfo", SOCKET_ERROR); - } - else - { - // Avoid assignment on due to alignment issues in Apple headers - // sa.sin_addr.s_addr = ((struct sockaddr_in *)(result->ai_addr))->sin_addr.s_addr; - struct sockaddr_in* sap = (struct sockaddr_in *)result->ai_addr; - memcpy(&sa.sin_addr.s_addr, &sap->sin_addr.s_addr, sizeof(sa.sin_addr.s_addr)); - freeaddrinfo(result); - } - } - - sa.sin_port = htons((unsigned short)port); - - return Connect((const sockaddr *)&sa, sizeof(sa)); -} - -bool Socket::Connect(const sockaddr* psa, socklen_t saLen) -{ - CRYPTOPP_ASSERT(m_s != INVALID_SOCKET); - int result = connect(m_s, const_cast(psa), saLen); - if (result == SOCKET_ERROR && GetLastError() == SOCKET_EWOULDBLOCK) - return false; - CheckAndHandleError_int("connect", result); - return true; -} - -bool Socket::Accept(Socket& target, sockaddr *psa, socklen_t *psaLen) -{ - CRYPTOPP_ASSERT(m_s != INVALID_SOCKET); - socket_t s = accept(m_s, psa, psaLen); - if (s == INVALID_SOCKET && GetLastError() == SOCKET_EWOULDBLOCK) - return false; - CheckAndHandleError("accept", s); - target.AttachSocket(s, true); - return true; -} - -void Socket::GetSockName(sockaddr *psa, socklen_t *psaLen) -{ - CRYPTOPP_ASSERT(m_s != INVALID_SOCKET); - CheckAndHandleError_int("getsockname", getsockname(m_s, psa, psaLen)); -} - -void Socket::GetPeerName(sockaddr *psa, socklen_t *psaLen) -{ - CRYPTOPP_ASSERT(m_s != INVALID_SOCKET); - CheckAndHandleError_int("getpeername", getpeername(m_s, psa, psaLen)); -} - -unsigned int Socket::Send(const byte* buf, size_t bufLen, int flags) -{ - CRYPTOPP_ASSERT(m_s != INVALID_SOCKET); - int result = send(m_s, (const char *)buf, UnsignedMin(INT_MAX, bufLen), flags); - CheckAndHandleError_int("send", result); - return result; -} - -unsigned int Socket::Receive(byte* buf, size_t bufLen, int flags) -{ - CRYPTOPP_ASSERT(m_s != INVALID_SOCKET); - int result = recv(m_s, (char *)buf, UnsignedMin(INT_MAX, bufLen), flags); - CheckAndHandleError_int("recv", result); - return result; -} - -void Socket::ShutDown(int how) -{ - CRYPTOPP_ASSERT(m_s != INVALID_SOCKET); - int result = shutdown(m_s, how); - CheckAndHandleError_int("shutdown", result); -} - -void Socket::IOCtl(long cmd, unsigned long *argp) -{ - CRYPTOPP_ASSERT(m_s != INVALID_SOCKET); -#ifdef USE_WINDOWS_STYLE_SOCKETS - CheckAndHandleError_int("ioctlsocket", ioctlsocket(m_s, cmd, argp)); -#else - CheckAndHandleError_int("ioctl", ioctl(m_s, cmd, argp)); -#endif -} - -bool Socket::SendReady(const timeval *timeout) -{ - fd_set fds; - FD_ZERO(&fds); - FD_SET(m_s, &fds); -#ifdef CRYPTOPP_MSAN - __msan_unpoison(&fds, sizeof(fds)); -#endif - - int ready; - if (timeout == NULLPTR) - ready = select((int)m_s+1, NULLPTR, &fds, NULLPTR, NULLPTR); - else - { - timeval timeoutCopy = *timeout; // select() modified timeout on Linux - ready = select((int)m_s+1, NULLPTR, &fds, NULLPTR, &timeoutCopy); - } - CheckAndHandleError_int("select", ready); - return ready > 0; -} - -bool Socket::ReceiveReady(const timeval *timeout) -{ - fd_set fds; - FD_ZERO(&fds); - FD_SET(m_s, &fds); -#ifdef CRYPTOPP_MSAN - __msan_unpoison(&fds, sizeof(fds)); -#endif - - int ready; - if (timeout == NULLPTR) - ready = select((int)m_s+1, &fds, NULLPTR, NULLPTR, NULLPTR); - else - { - timeval timeoutCopy = *timeout; // select() modified timeout on Linux - ready = select((int)m_s+1, &fds, NULLPTR, NULLPTR, &timeoutCopy); - } - CheckAndHandleError_int("select", ready); - return ready > 0; -} - -unsigned int Socket::PortNameToNumber(const char *name, const char *protocol) -{ - int port = atoi(name); - if (IntToString(port) == name) - return port; - - servent *se = getservbyname(name, protocol); - if (!se) - throw Err(INVALID_SOCKET, "getservbyname", SOCKET_EINVAL); - return ntohs(se->s_port); -} - -void Socket::StartSockets() -{ -#ifdef USE_WINDOWS_STYLE_SOCKETS - WSADATA wsd; - int result = WSAStartup(0x0202, &wsd); - if (result != 0) - throw Err(INVALID_SOCKET, "WSAStartup", result); -#endif -} - -void Socket::ShutdownSockets() -{ -#ifdef USE_WINDOWS_STYLE_SOCKETS - int result = WSACleanup(); - if (result != 0) - throw Err(INVALID_SOCKET, "WSACleanup", result); -#endif -} - -int Socket::GetLastError() -{ -#ifdef USE_WINDOWS_STYLE_SOCKETS - return WSAGetLastError(); -#else - return errno; -#endif -} - -void Socket::SetLastError(int errorCode) -{ -#ifdef USE_WINDOWS_STYLE_SOCKETS - WSASetLastError(errorCode); -#else - errno = errorCode; -#endif -} - -void Socket::HandleError(const char *operation) const -{ - int err = GetLastError(); - throw Err(m_s, operation, err); -} - -#ifdef USE_WINDOWS_STYLE_SOCKETS - -SocketReceiver::SocketReceiver(Socket &s) - : m_s(s), m_lastResult(0), m_resultPending(false), m_eofReceived(false) -{ - m_event.AttachHandle(CreateEvent(NULLPTR, true, false, NULLPTR), true); - m_s.CheckAndHandleError("CreateEvent", m_event.HandleValid()); - memset(&m_overlapped, 0, sizeof(m_overlapped)); - m_overlapped.hEvent = m_event; -} - -SocketReceiver::~SocketReceiver() -{ -#ifdef USE_WINDOWS_STYLE_SOCKETS -# if defined(USE_WINDOWS8_API) - BOOL result = CancelIoEx((HANDLE) m_s.GetSocket(), NULLPTR); - CRYPTOPP_ASSERT(result || (!result && GetLastError() == ERROR_NOT_FOUND)); - CRYPTOPP_UNUSED(result); // Used by CRYPTOPP_ASSERT in debug builds -# else - BOOL result = CancelIo((HANDLE) m_s.GetSocket()); - CRYPTOPP_ASSERT(result || (!result && GetLastError() == ERROR_NOT_FOUND)); - CRYPTOPP_UNUSED(result); -# endif -#endif -} - -bool SocketReceiver::Receive(byte* buf, size_t bufLen) -{ - CRYPTOPP_ASSERT(!m_resultPending && !m_eofReceived); - - DWORD flags = 0; - // don't queue too much at once, or we might use up non-paged memory - WSABUF wsabuf = {UnsignedMin((u_long)128*1024, bufLen), (char *)buf}; - if (WSARecv(m_s, &wsabuf, 1, &m_lastResult, &flags, &m_overlapped, NULLPTR) == 0) - { - if (m_lastResult == 0) - m_eofReceived = true; - } - else - { - switch (WSAGetLastError()) - { - default: - m_s.CheckAndHandleError_int("WSARecv", SOCKET_ERROR); - // Fall through for non-fatal - case WSAEDISCON: - m_lastResult = 0; - m_eofReceived = true; - break; - case WSA_IO_PENDING: - m_resultPending = true; - } - } - return !m_resultPending; -} - -void SocketReceiver::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) -{ - if (m_resultPending) - container.AddHandle(m_event, CallStack("SocketReceiver::GetWaitObjects() - result pending", &callStack)); - else if (!m_eofReceived) - container.SetNoWait(CallStack("SocketReceiver::GetWaitObjects() - result ready", &callStack)); -} - -unsigned int SocketReceiver::GetReceiveResult() -{ - if (m_resultPending) - { - DWORD flags = 0; - if (WSAGetOverlappedResult(m_s, &m_overlapped, &m_lastResult, false, &flags)) - { - if (m_lastResult == 0) - m_eofReceived = true; - } - else - { - switch (WSAGetLastError()) - { - default: - m_s.CheckAndHandleError("WSAGetOverlappedResult", FALSE); - // Fall through for non-fatal - case WSAEDISCON: - m_lastResult = 0; - m_eofReceived = true; - } - } - m_resultPending = false; - } - return m_lastResult; -} - -// ************************************************************* - -SocketSender::SocketSender(Socket &s) - : m_s(s), m_lastResult(0), m_resultPending(false) -{ - m_event.AttachHandle(CreateEvent(NULLPTR, true, false, NULLPTR), true); - m_s.CheckAndHandleError("CreateEvent", m_event.HandleValid()); - memset(&m_overlapped, 0, sizeof(m_overlapped)); - m_overlapped.hEvent = m_event; -} - - -SocketSender::~SocketSender() -{ -#ifdef USE_WINDOWS_STYLE_SOCKETS -# if defined(USE_WINDOWS8_API) - BOOL result = CancelIoEx((HANDLE) m_s.GetSocket(), NULLPTR); - CRYPTOPP_ASSERT(result || (!result && GetLastError() == ERROR_NOT_FOUND)); - CRYPTOPP_UNUSED(result); // Used by CRYPTOPP_ASSERT in debug builds -# else - BOOL result = CancelIo((HANDLE) m_s.GetSocket()); - CRYPTOPP_ASSERT(result || (!result && GetLastError() == ERROR_NOT_FOUND)); - CRYPTOPP_UNUSED(result); -# endif -#endif -} - -void SocketSender::Send(const byte* buf, size_t bufLen) -{ - CRYPTOPP_ASSERT(!m_resultPending); - DWORD written = 0; - // don't queue too much at once, or we might use up non-paged memory - WSABUF wsabuf = {UnsignedMin((u_long)128*1024, bufLen), (char *)buf}; - if (WSASend(m_s, &wsabuf, 1, &written, 0, &m_overlapped, NULLPTR) == 0) - { - m_resultPending = false; - m_lastResult = written; - } - else - { - if (WSAGetLastError() != WSA_IO_PENDING) - m_s.CheckAndHandleError_int("WSASend", SOCKET_ERROR); - - m_resultPending = true; - } -} - -void SocketSender::SendEof() -{ - CRYPTOPP_ASSERT(!m_resultPending); - m_s.ShutDown(SD_SEND); - m_s.CheckAndHandleError("ResetEvent", ResetEvent(m_event)); - m_s.CheckAndHandleError_int("WSAEventSelect", WSAEventSelect(m_s, m_event, FD_CLOSE)); - m_resultPending = true; -} - -bool SocketSender::EofSent() -{ - if (m_resultPending) - { - WSANETWORKEVENTS events; - m_s.CheckAndHandleError_int("WSAEnumNetworkEvents", WSAEnumNetworkEvents(m_s, m_event, &events)); - if ((events.lNetworkEvents & FD_CLOSE) != FD_CLOSE) - throw Socket::Err(m_s, "WSAEnumNetworkEvents (FD_CLOSE not present)", E_FAIL); - if (events.iErrorCode[FD_CLOSE_BIT] != 0) - throw Socket::Err(m_s, "FD_CLOSE (via WSAEnumNetworkEvents)", events.iErrorCode[FD_CLOSE_BIT]); - m_resultPending = false; - } - return m_lastResult != 0; -} - -void SocketSender::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) -{ - if (m_resultPending) - container.AddHandle(m_event, CallStack("SocketSender::GetWaitObjects() - result pending", &callStack)); - else - container.SetNoWait(CallStack("SocketSender::GetWaitObjects() - result ready", &callStack)); -} - -unsigned int SocketSender::GetSendResult() -{ - if (m_resultPending) - { - DWORD flags = 0; - BOOL result = WSAGetOverlappedResult(m_s, &m_overlapped, &m_lastResult, false, &flags); - m_s.CheckAndHandleError("WSAGetOverlappedResult", result); - m_resultPending = false; - } - return m_lastResult; -} - -#endif - -#ifdef USE_BERKELEY_STYLE_SOCKETS - -SocketReceiver::SocketReceiver(Socket &s) - : m_s(s), m_lastResult(0), m_eofReceived(false) -{ -} - -void SocketReceiver::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) -{ - if (!m_eofReceived) - container.AddReadFd(m_s, CallStack("SocketReceiver::GetWaitObjects()", &callStack)); -} - -bool SocketReceiver::Receive(byte* buf, size_t bufLen) -{ - m_lastResult = m_s.Receive(buf, bufLen); - if (bufLen > 0 && m_lastResult == 0) - m_eofReceived = true; - return true; -} - -unsigned int SocketReceiver::GetReceiveResult() -{ - return m_lastResult; -} - -SocketSender::SocketSender(Socket &s) - : m_s(s), m_lastResult(0) -{ -} - -void SocketSender::Send(const byte* buf, size_t bufLen) -{ - m_lastResult = m_s.Send(buf, bufLen); -} - -void SocketSender::SendEof() -{ - m_s.ShutDown(SD_SEND); -} - -unsigned int SocketSender::GetSendResult() -{ - return m_lastResult; -} - -void SocketSender::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) -{ - container.AddWriteFd(m_s, CallStack("SocketSender::GetWaitObjects()", &callStack)); -} - -#endif // USE_BERKELEY_STYLE_SOCKETS - -NAMESPACE_END - -#endif // SOCKETS_AVAILABLE diff --git a/socketft.h b/socketft.h deleted file mode 100644 index 00c4fc27..00000000 --- a/socketft.h +++ /dev/null @@ -1,227 +0,0 @@ -#ifndef CRYPTOPP_SOCKETFT_H -#define CRYPTOPP_SOCKETFT_H - -#include "config.h" - -#if !defined(NO_OS_DEPENDENCE) && defined(SOCKETS_AVAILABLE) - -#include "cryptlib.h" -#include "network.h" -#include "queue.h" - -#ifdef USE_WINDOWS_STYLE_SOCKETS -# if defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_) -# error Winsock 1 is not supported by this library. Please include this file or winsock2.h before windows.h. -# endif -#include -#include -#include "winpipes.h" -#else -#include -#include -#include -#include -#endif - -NAMESPACE_BEGIN(CryptoPP) - -#ifdef USE_WINDOWS_STYLE_SOCKETS -typedef ::SOCKET socket_t; -#else -typedef int socket_t; -const socket_t INVALID_SOCKET = -1; -// cygwin 1.1.4 doesn't have SHUT_RD -const int SD_RECEIVE = 0; -const int SD_SEND = 1; -const int SD_BOTH = 2; -const int SOCKET_ERROR = -1; -#endif - -#ifndef socklen_t -typedef TYPE_OF_SOCKLEN_T socklen_t; // see config.h -#endif - -/// wrapper for Windows or Berkeley Sockets -class Socket -{ -public: - /// exception thrown by Socket class - class Err : public OS_Error - { - public: - Err(socket_t s, const std::string& operation, int error); - socket_t GetSocket() const {return m_s;} - - private: - socket_t m_s; - }; - - Socket(socket_t s = INVALID_SOCKET, bool own=false) : m_s(s), m_own(own) {} - Socket(const Socket &s) : m_s(s.m_s), m_own(false) {} - virtual ~Socket(); - - bool GetOwnership() const {return m_own;} - void SetOwnership(bool own) {m_own = own;} - - operator socket_t() {return m_s;} - socket_t GetSocket() const {return m_s;} - void AttachSocket(socket_t s, bool own=false); - socket_t DetachSocket(); - void CloseSocket(); - - void Create(int nType = SOCK_STREAM); - void Bind(unsigned int port, const char *addr=NULLPTR); - void Bind(const sockaddr* psa, socklen_t saLen); - void Listen(int backlog = SOMAXCONN); - // the next three functions return false if the socket is in nonblocking mode - // and the operation cannot be completed immediately - bool Connect(const char *addr, unsigned int port); - bool Connect(const sockaddr* psa, socklen_t saLen); - bool Accept(Socket& s, sockaddr *psa=NULLPTR, socklen_t *psaLen=NULLPTR); - void GetSockName(sockaddr *psa, socklen_t *psaLen); - void GetPeerName(sockaddr *psa, socklen_t *psaLen); - unsigned int Send(const byte* buf, size_t bufLen, int flags=0); - unsigned int Receive(byte* buf, size_t bufLen, int flags=0); - void ShutDown(int how = SD_SEND); - - void IOCtl(long cmd, unsigned long *argp); - bool SendReady(const timeval *timeout); - bool ReceiveReady(const timeval *timeout); - - virtual void HandleError(const char *operation) const; - void CheckAndHandleError_int(const char *operation, int result) const - {if (result == SOCKET_ERROR) HandleError(operation);} - void CheckAndHandleError(const char *operation, socket_t result) const - {if (result == static_cast(SOCKET_ERROR)) HandleError(operation);} -#ifdef USE_WINDOWS_STYLE_SOCKETS - void CheckAndHandleError(const char *operation, BOOL result) const - {if (!result) HandleError(operation);} - void CheckAndHandleError(const char *operation, bool result) const - {if (!result) HandleError(operation);} -#endif - - /// look up the port number given its name, returns 0 if not found - static unsigned int PortNameToNumber(const char *name, const char *protocol="tcp"); - /// start Windows Sockets 2 - static void StartSockets(); - /// calls WSACleanup for Windows Sockets - static void ShutdownSockets(); - /// returns errno or WSAGetLastError - static int GetLastError(); - /// sets errno or calls WSASetLastError - static void SetLastError(int errorCode); - -protected: - virtual void SocketChanged() {} - - socket_t m_s; - bool m_own; -}; - -class SocketsInitializer -{ -public: - SocketsInitializer() {Socket::StartSockets();} - ~SocketsInitializer() {try {Socket::ShutdownSockets();} catch (const Exception&) {CRYPTOPP_ASSERT(0);}} -}; - -class SocketReceiver : public NetworkReceiver -{ -public: - SocketReceiver(Socket &s); - -#ifdef USE_BERKELEY_STYLE_SOCKETS - bool MustWaitToReceive() {return true;} -#else - ~SocketReceiver(); - bool MustWaitForResult() {return true;} -#endif - bool Receive(byte* buf, size_t bufLen); - unsigned int GetReceiveResult(); - bool EofReceived() const {return m_eofReceived;} - - unsigned int GetMaxWaitObjectCount() const {return 1;} - void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); - -private: - Socket &m_s; - -#ifdef USE_WINDOWS_STYLE_SOCKETS - WindowsHandle m_event; - OVERLAPPED m_overlapped; - DWORD m_lastResult; - bool m_resultPending; -#else - unsigned int m_lastResult; -#endif - - bool m_eofReceived; -}; - -class SocketSender : public NetworkSender -{ -public: - SocketSender(Socket &s); - -#ifdef USE_BERKELEY_STYLE_SOCKETS - bool MustWaitToSend() {return true;} -#else - ~SocketSender(); - bool MustWaitForResult() {return true;} - bool MustWaitForEof() { return true; } - bool EofSent(); -#endif - void Send(const byte* buf, size_t bufLen); - unsigned int GetSendResult(); - void SendEof(); - - unsigned int GetMaxWaitObjectCount() const {return 1;} - void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); - -private: - Socket &m_s; -#ifdef USE_WINDOWS_STYLE_SOCKETS - WindowsHandle m_event; - OVERLAPPED m_overlapped; - DWORD m_lastResult; - bool m_resultPending; -#else - unsigned int m_lastResult; -#endif -}; - -/// socket-based implementation of NetworkSource -class SocketSource : public NetworkSource, public Socket -{ -public: - SocketSource(socket_t s = INVALID_SOCKET, bool pumpAll = false, BufferedTransformation *attachment = NULLPTR) - : NetworkSource(attachment), Socket(s), m_receiver(*this) - { - if (pumpAll) - PumpAll(); - } - -private: - NetworkReceiver & AccessReceiver() {return m_receiver;} - SocketReceiver m_receiver; -}; - -/// socket-based implementation of NetworkSink -class SocketSink : public NetworkSink, public Socket -{ -public: - SocketSink(socket_t s=INVALID_SOCKET, unsigned int maxBufferSize=0, unsigned int autoFlushBound=16*1024) - : NetworkSink(maxBufferSize, autoFlushBound), Socket(s), m_sender(*this) {} - - void SendEof() {ShutDown(SD_SEND);} - -private: - NetworkSender & AccessSender() {return m_sender;} - SocketSender m_sender; -}; - -NAMESPACE_END - -#endif // SOCKETS_AVAILABLE - -#endif // CRYPTOPP_SOCKETFT_H diff --git a/test.cpp b/test.cpp index 5d8e702c..f7a2f6e6 100644 --- a/test.cpp +++ b/test.cpp @@ -18,8 +18,6 @@ #include "randpool.h" #include "ida.h" #include "base64.h" -#include "socketft.h" -#include "wait.h" #include "factory.h" #include "whrlpool.h" #include "tiger.h" @@ -43,11 +41,6 @@ #include #endif -#if defined(USE_BERKELEY_STYLE_SOCKETS) && !defined(macintosh) -#include -#include -#endif - #if (_MSC_VER >= 1000) #include // for the debug heap #endif @@ -62,7 +55,6 @@ #ifdef __BORLANDC__ #pragma comment(lib, "cryptlib_bds.lib") -#pragma comment(lib, "ws2_32.lib") #endif // Aggressive stack checking with VS2005 SP1 and above. @@ -115,8 +107,6 @@ void Base64Decode(const char *infile, const char *outfile); void HexEncode(const char *infile, const char *outfile); void HexDecode(const char *infile, const char *outfile); -void ForwardTcpPort(const char *sourcePort, const char *destinationHost, const char *destinationPort); - void FIPS140_GenerateRandomFiles(); bool Validate(int, bool, const char *); @@ -386,8 +376,6 @@ int scoped_main(int argc, char *argv[]) FIPS140_SampleApplication(); else if (command == "fips-rand") FIPS140_GenerateRandomFiles(); - else if (command == "ft") - ForwardTcpPort(argv[2], argv[3], argv[4]); else if (command == "a") { if (AdhocTest) @@ -793,77 +781,6 @@ void HexDecode(const char *in, const char *out) FileSource(in, true, new HexDecoder(new FileSink(out))); } -void ForwardTcpPort(const char *sourcePortName, const char *destinationHost, const char *destinationPortName) -{ - // Quiet warnings for Windows Phone and Windows Store builds - CRYPTOPP_UNUSED(sourcePortName), CRYPTOPP_UNUSED(destinationHost), CRYPTOPP_UNUSED(destinationPortName); - -#ifdef SOCKETS_AVAILABLE - SocketsInitializer sockInit; - - Socket sockListen, sockSource, sockDestination; - - int sourcePort = Socket::PortNameToNumber(sourcePortName); - int destinationPort = Socket::PortNameToNumber(destinationPortName); - - sockListen.Create(); - sockListen.Bind(sourcePort); - - const int flag = 1; - int err = setsockopt(sockListen, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int)); - CRYPTOPP_ASSERT(err == 0); - if(err != 0) - throw Socket::Err(sockListen, "setsockopt", sockListen.GetLastError()); - - std::cout << "Listing on port " << sourcePort << ".\n"; - sockListen.Listen(); - - sockListen.Accept(sockSource); - std::cout << "Connection accepted on port " << sourcePort << ".\n"; - sockListen.CloseSocket(); - - std::cout << "Making connection to " << destinationHost << ", port " << destinationPort << ".\n"; - sockDestination.Create(); - sockDestination.Connect(destinationHost, destinationPort); - - std::cout << "Connection made to " << destinationHost << ", starting to forward.\n"; - - SocketSource out(sockSource, false, new SocketSink(sockDestination)); - SocketSource in(sockDestination, false, new SocketSink(sockSource)); - - WaitObjectContainer waitObjects; - - while (!(in.SourceExhausted() && out.SourceExhausted())) - { - waitObjects.Clear(); - - out.GetWaitObjects(waitObjects, CallStack("ForwardTcpPort - out", NULLPTR)); - in.GetWaitObjects(waitObjects, CallStack("ForwardTcpPort - in", NULLPTR)); - - waitObjects.Wait(INFINITE_TIME); - - if (!out.SourceExhausted()) - { - std::cout << "o" << std::flush; - out.PumpAll2(false); - if (out.SourceExhausted()) - std::cout << "EOF received on source socket.\n"; - } - - if (!in.SourceExhausted()) - { - std::cout << "i" << std::flush; - in.PumpAll2(false); - if (in.SourceExhausted()) - std::cout << "EOF received on destination socket.\n"; - } - } -#else - std::cout << "Socket support was not enabled at compile time.\n"; - exit(-1); -#endif -} - bool Validate(int alg, bool thorough, const char *seedInput) { bool result; diff --git a/trdlocal.cpp b/trdlocal.cpp deleted file mode 100644 index f13b1845..00000000 --- a/trdlocal.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// trdlocal.cpp - originally written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "config.h" - -#ifndef CRYPTOPP_IMPORTS - -#if !defined(NO_OS_DEPENDENCE) && defined(THREADS_AVAILABLE) - -#include "trdlocal.h" -#include "stdcpp.h" - -#ifdef HAS_WINTHREADS -#define WIN32_LEAN_AND_MEAN -#include -#endif - -#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE -# pragma GCC diagnostic ignored "-Wc++11-compat" -#endif - -NAMESPACE_BEGIN(CryptoPP) - -ThreadLocalStorage::Err::Err(const std::string& operation, int error) - : OS_Error(OTHER_ERROR, "ThreadLocalStorage: " + operation + " operation failed with error 0x" + IntToString(error, 16), operation, error) -{ -} - -// Windows: "a process may have up to TLS_MINIMUM_AVAILABLE indexes (guaranteed to be greater than -// or equal to 64)", https://support.microsoft.com/en-us/help/94804/info-thread-local-storage-overview -ThreadLocalStorage::ThreadLocalStorage() -{ -#ifdef HAS_WINTHREADS - m_index = TlsAlloc(); - CRYPTOPP_ASSERT(m_index != TLS_OUT_OF_INDEXES); - if (m_index == TLS_OUT_OF_INDEXES) - throw Err("TlsAlloc", GetLastError()); -#else - m_index = 0; - int error = pthread_key_create(&m_index, NULLPTR); - CRYPTOPP_ASSERT(!error); - if (error) - throw Err("pthread_key_create", error); -#endif -} - -ThreadLocalStorage::~ThreadLocalStorage() CRYPTOPP_THROW -{ -#if defined(CRYPTOPP_CXX17_EXCEPTIONS) - if (std::uncaught_exceptions() == 0) -#elif defined(CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE) - if (std::uncaught_exception() == false) -#else - try -#endif -#ifdef HAS_WINTHREADS - { - int rc = TlsFree(m_index); - CRYPTOPP_ASSERT(rc); - if (!rc) - throw Err("TlsFree", GetLastError()); - } -#else - { - int error = pthread_key_delete(m_index); - CRYPTOPP_ASSERT(!error); - if (error) - throw Err("pthread_key_delete", error); - } -#endif -#if !defined(CRYPTOPP_CXX17_EXCEPTIONS) && !defined(CRYPTOPP_UNCAUGHT_EXCEPTION_AVAILABLE) - catch(const Exception&) - { - } -#endif -} - -void ThreadLocalStorage::SetValue(void *value) -{ -#ifdef HAS_WINTHREADS - if (!TlsSetValue(m_index, value)) - throw Err("TlsSetValue", GetLastError()); -#else - int error = pthread_setspecific(m_index, value); - if (error) - throw Err("pthread_key_getspecific", error); -#endif -} - -void *ThreadLocalStorage::GetValue() const -{ -#ifdef HAS_WINTHREADS - void *result = TlsGetValue(m_index); - const DWORD dwRet = GetLastError(); - - CRYPTOPP_ASSERT(result || (!result && (dwRet == NO_ERROR))); - if (!result && dwRet != NO_ERROR) - throw Err("TlsGetValue", dwRet); -#else - // Null is a valid return value. Posix does not provide a way to - // check for a "good" Null vs a "bad" Null (errno is not set). - void *result = pthread_getspecific(m_index); -#endif - return result; -} - -NAMESPACE_END - -#endif // THREADS_AVAILABLE -#endif // CRYPTOPP_IMPORTS diff --git a/trdlocal.h b/trdlocal.h deleted file mode 100644 index a30ca692..00000000 --- a/trdlocal.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef CRYPTOPP_TRDLOCAL_H -#define CRYPTOPP_TRDLOCAL_H - -#include "config.h" - -#if !defined(NO_OS_DEPENDENCE) && defined(THREADS_AVAILABLE) - -#include "misc.h" - -#ifdef HAS_WINTHREADS -typedef unsigned long ThreadLocalIndexType; -#else -#include -typedef pthread_key_t ThreadLocalIndexType; -#endif - -NAMESPACE_BEGIN(CryptoPP) - -/// thread local storage -class CRYPTOPP_DLL ThreadLocalStorage : public NotCopyable -{ -public: - /// exception thrown by ThreadLocalStorage class - class Err : public OS_Error - { - public: - Err(const std::string& operation, int error); - }; - - ThreadLocalStorage(); - ~ThreadLocalStorage() CRYPTOPP_THROW; - - void SetValue(void *value); - void *GetValue() const; - -private: - ThreadLocalIndexType m_index; -}; - -NAMESPACE_END - -#endif // THREADS_AVAILABLE - -#endif // CRYPTOPP_TRDLOCAL_H diff --git a/wait.cpp b/wait.cpp deleted file mode 100644 index 17f42ffe..00000000 --- a/wait.cpp +++ /dev/null @@ -1,486 +0,0 @@ -// wait.cpp - originally written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "config.h" - -// http://connect.microsoft.com/VisualStudio/feedback/details/1581706 -// and http://github.com/weidai11/cryptopp/issues/214 -#if CRYPTOPP_MSC_VERSION -# pragma warning(disable: 4189) -# pragma warning(disable: 4589) -#endif - -#if !defined(NO_OS_DEPENDENCE) && (defined(SOCKETS_AVAILABLE) || defined(WINDOWS_PIPES_AVAILABLE)) - -#include "wait.h" -#include "misc.h" -#include "smartptr.h" - -// Windows 8, Windows Server 2012, and Windows Phone 8.1 need and -#if defined(CRYPTOPP_WIN32_AVAILABLE) -# if ((WINVER >= 0x0602 /*_WIN32_WINNT_WIN8*/) || (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)) -# include -# include -# define USE_WINDOWS8_API -# endif -#endif - -#ifdef USE_BERKELEY_STYLE_SOCKETS -#include -#include -#include -#include -#endif - -#if defined(CRYPTOPP_MSAN) -# include -#endif - -NAMESPACE_BEGIN(CryptoPP) - -unsigned int WaitObjectContainer::MaxWaitObjects() -{ -#ifdef USE_WINDOWS_STYLE_SOCKETS - return MAXIMUM_WAIT_OBJECTS * (MAXIMUM_WAIT_OBJECTS-1); -#else - return FD_SETSIZE; -#endif -} - -WaitObjectContainer::WaitObjectContainer(WaitObjectsTracer* tracer) - : m_tracer(tracer), -#ifdef USE_WINDOWS_STYLE_SOCKETS - m_startWaiting(0), m_stopWaiting(0), -#endif - m_firstEventTime(0.0f), m_eventTimer(Timer::MILLISECONDS), m_lastResult(0), - m_sameResultCount(0), m_noWaitTimer(Timer::MILLISECONDS) -{ - Clear(); - m_eventTimer.StartTimer(); -} - -void WaitObjectContainer::Clear() -{ -#ifdef USE_WINDOWS_STYLE_SOCKETS - m_handles.clear(); -#else - m_maxFd = 0; - FD_ZERO(&m_readfds); - FD_ZERO(&m_writefds); -# ifdef CRYPTOPP_MSAN - __msan_unpoison(&m_readfds, sizeof(m_readfds)); - __msan_unpoison(&m_writefds, sizeof(m_writefds)); -# endif -#endif - m_noWait = false; - m_firstEventTime = 0; -} - -inline void WaitObjectContainer::SetLastResult(LastResultType result) -{ - if (result == m_lastResult) - m_sameResultCount++; - else - { - m_lastResult = result; - m_sameResultCount = 0; - } -} - -void WaitObjectContainer::DetectNoWait(LastResultType result, CallStack const& callStack) -{ - if (result == m_lastResult && m_noWaitTimer.ElapsedTime() > 1000) - { - if (m_sameResultCount > m_noWaitTimer.ElapsedTime()) - { - if (m_tracer) - { - std::string desc = "No wait loop detected - m_lastResult: "; - desc.append(IntToString(m_lastResult)).append(", call stack:"); - for (CallStack const* cs = &callStack; cs; cs = cs->Prev()) - desc.append("\n- ").append(cs->Format()); - m_tracer->TraceNoWaitLoop(desc); - } - try { throw 0; } catch (...) {} // help debugger break - } - - m_noWaitTimer.StartTimer(); - m_sameResultCount = 0; - } -} - -void WaitObjectContainer::SetNoWait(CallStack const& callStack) -{ - DetectNoWait(LastResultType(LASTRESULT_NOWAIT), CallStack("WaitObjectContainer::SetNoWait()", &callStack)); - m_noWait = true; -} - -void WaitObjectContainer::ScheduleEvent(double milliseconds, CallStack const& callStack) -{ - if (milliseconds <= 3) - DetectNoWait(LastResultType(LASTRESULT_SCHEDULED), CallStack("WaitObjectContainer::ScheduleEvent()", &callStack)); - double thisEventTime = m_eventTimer.ElapsedTimeAsDouble() + milliseconds; - if (!m_firstEventTime || thisEventTime < m_firstEventTime) - m_firstEventTime = thisEventTime; -} - -#ifdef USE_WINDOWS_STYLE_SOCKETS - -struct WaitingThreadData -{ - bool waitingToWait, terminate; - HANDLE startWaiting, stopWaiting; - const HANDLE *waitHandles; - unsigned int count; - HANDLE threadHandle; - DWORD threadId; - DWORD* error; -}; - -WaitObjectContainer::~WaitObjectContainer() -{ - try // don't let exceptions escape destructor - { - if (!m_threads.empty()) - { - HANDLE threadHandles[MAXIMUM_WAIT_OBJECTS] = {0}; - - unsigned int i; - for (i=0; i pThread((WaitingThreadData *)lParam); - WaitingThreadData &thread = *pThread; - std::vector handles; - - while (true) - { - thread.waitingToWait = true; -#if defined(USE_WINDOWS8_API) - DWORD result = ::WaitForSingleObjectEx(thread.startWaiting, INFINITE, FALSE); - CRYPTOPP_ASSERT(result != WAIT_FAILED); -#else - DWORD result = ::WaitForSingleObject(thread.startWaiting, INFINITE); - CRYPTOPP_ASSERT(result != WAIT_FAILED); -#endif - - thread.waitingToWait = false; - if (thread.terminate) - break; - if (!thread.count) - continue; - - handles.resize(thread.count + 1); - handles[0] = thread.stopWaiting; - std::copy(thread.waitHandles, thread.waitHandles+thread.count, handles.begin()+1); - -#if defined(USE_WINDOWS8_API) - result = ::WaitForMultipleObjectsEx((DWORD)handles.size(), &handles[0], FALSE, INFINITE, FALSE); - CRYPTOPP_ASSERT(result != WAIT_FAILED); -#else - result = ::WaitForMultipleObjects((DWORD)handles.size(), &handles[0], FALSE, INFINITE); - CRYPTOPP_ASSERT(result != WAIT_FAILED); -#endif - - if (result == WAIT_OBJECT_0) - continue; // another thread finished waiting first, so do nothing - SetEvent(thread.stopWaiting); - if (!(result > WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + handles.size())) - { - CRYPTOPP_ASSERT(!"error in WaitingThread"); // break here so we can see which thread has an error - *thread.error = ::GetLastError(); - } - } - - return S_OK; // return a value here to avoid compiler warning -} - -void WaitObjectContainer::CreateThreads(unsigned int count) -{ - size_t currentCount = m_threads.size(); - if (currentCount == 0) - { - m_startWaiting = ::CreateEvent(NULLPTR, TRUE, FALSE, NULLPTR); - m_stopWaiting = ::CreateEvent(NULLPTR, TRUE, FALSE, NULLPTR); - } - - if (currentCount < count) - { - m_threads.resize(count); - for (size_t i=currentCount; i MAXIMUM_WAIT_OBJECTS) - { - // too many wait objects for a single WaitForMultipleObjects call, so use multiple threads - static const unsigned int WAIT_OBJECTS_PER_THREAD = MAXIMUM_WAIT_OBJECTS-1; - unsigned int nThreads = (unsigned int)((m_handles.size() + WAIT_OBJECTS_PER_THREAD - 1) / WAIT_OBJECTS_PER_THREAD); - if (nThreads > MAXIMUM_WAIT_OBJECTS) // still too many wait objects, maybe implement recursive threading later? - throw Err("WaitObjectContainer: number of wait objects exceeds limit"); - CreateThreads(nThreads); - DWORD error = S_OK; - - for (unsigned int i=0; i 0) - { - unsigned long timeAfterWait = t.ElapsedTime(); - OutputDebugStringA(("Handles " + IntToString(m_handles.size()) + ", Woke up by " + IntToString(result-WAIT_OBJECT_0) + ", Busied for " + IntToString(timeBeforeWait-lastTime) + " us, Waited for " + IntToString(timeAfterWait-timeBeforeWait) + " us, max " + IntToString(milliseconds) + "ms\n").c_str()); - lastTime = timeAfterWait; - } -#endif - if (result < WAIT_OBJECT_0 + m_handles.size()) - { - if (result == m_lastResult) - m_sameResultCount++; - else - { - m_lastResult = result; - m_sameResultCount = 0; - } - return true; - } - else if (result == WAIT_TIMEOUT) - { - SetLastResult(timeoutIsScheduledEvent ? LASTRESULT_SCHEDULED : LASTRESULT_TIMEOUT); - return timeoutIsScheduledEvent; - } - else - throw Err("WaitObjectContainer: WaitForMultipleObjects failed with error " + IntToString(::GetLastError())); - } -} - -#else // #ifdef USE_WINDOWS_STYLE_SOCKETS - -void WaitObjectContainer::AddReadFd(int fd, CallStack const& callStack) // TODO: do something with callStack -{ - CRYPTOPP_UNUSED(callStack); - FD_SET(fd, &m_readfds); - m_maxFd = STDMAX(m_maxFd, fd); -} - -void WaitObjectContainer::AddWriteFd(int fd, CallStack const& callStack) // TODO: do something with callStack -{ - CRYPTOPP_UNUSED(callStack); - FD_SET(fd, &m_writefds); - m_maxFd = STDMAX(m_maxFd, fd); -} - -bool WaitObjectContainer::Wait(unsigned long milliseconds) -{ - if (m_noWait || (!m_maxFd && !m_firstEventTime)) - return true; - - bool timeoutIsScheduledEvent = false; - - if (m_firstEventTime) - { - double timeToFirstEvent = SaturatingSubtract(m_firstEventTime, m_eventTimer.ElapsedTimeAsDouble()); - if (timeToFirstEvent <= milliseconds) - { - milliseconds = (unsigned long)timeToFirstEvent; - timeoutIsScheduledEvent = true; - } - } - - timeval tv, *timeout; - - if (milliseconds == INFINITE_TIME) - timeout = NULLPTR; - else - { - tv.tv_sec = milliseconds / 1000; - tv.tv_usec = (milliseconds % 1000) * 1000; - timeout = &tv; - } - - int result = select(m_maxFd+1, &m_readfds, &m_writefds, NULLPTR, timeout); - - if (result > 0) - return true; - else if (result == 0) - return timeoutIsScheduledEvent; - else - throw Err("WaitObjectContainer: select failed with error " + IntToString(errno)); -} - -#endif - -// ******************************************************** - -std::string CallStack::Format() const -{ - return m_info; -} - -std::string CallStackWithNr::Format() const -{ - return std::string(m_info) + " / nr: " + IntToString(m_nr); -} - -std::string CallStackWithStr::Format() const -{ - return std::string(m_info) + " / " + std::string(m_z); -} - -bool Waitable::Wait(unsigned long milliseconds, CallStack const& callStack) -{ - WaitObjectContainer container; - GetWaitObjects(container, callStack); // reduce clutter by not adding this func to stack - return container.Wait(milliseconds); -} - -NAMESPACE_END - -#endif diff --git a/wait.h b/wait.h deleted file mode 100644 index 924ed42b..00000000 --- a/wait.h +++ /dev/null @@ -1,235 +0,0 @@ -// wait.h - originally written and placed in the public domain by Wei Dai - -#ifndef CRYPTOPP_WAIT_H -#define CRYPTOPP_WAIT_H - -#include "config.h" - -#if !defined(NO_OS_DEPENDENCE) && (defined(SOCKETS_AVAILABLE) || defined(WINDOWS_PIPES_AVAILABLE)) - -#include "cryptlib.h" -#include "misc.h" -#include "stdcpp.h" - -#ifdef USE_WINDOWS_STYLE_SOCKETS -#include -#else -#include -#include -#endif - -// For definitions of VOID, PVOID, HANDLE, PHANDLE, etc. -#if defined(CRYPTOPP_WIN32_AVAILABLE) -#define WIN32_LEAN_AND_MEAN -#include -#endif - -#include "hrtimer.h" - -#if defined(__has_feature) -# if __has_feature(memory_sanitizer) -# define CRYPTOPP_MSAN 1 -# endif -#endif - -// http://connect.microsoft.com/VisualStudio/feedback/details/1581706 -// and http://github.com/weidai11/cryptopp/issues/214 -#if (CRYPTOPP_MSC_VERSION >= 1900) -# pragma warning(push) -# pragma warning(disable: 4589) -#endif - -NAMESPACE_BEGIN(CryptoPP) - -class Tracer -{ -public: - Tracer(unsigned int level) : m_level(level) {} - virtual ~Tracer() {} - -protected: - /// Override this in your most-derived tracer to do the actual tracing. - virtual void Trace(unsigned int n, std::string const& s) = 0; - - /*! By default, tracers will decide which trace messages to trace according to a trace level - mechanism. If your most-derived tracer uses a different mechanism, override this to - return false. If this method returns false, the default TraceXxxx(void) methods will all - return 0 and must be overridden explicitly by your tracer for trace messages you want. */ - virtual bool UsingDefaults() const { return true; } - -protected: - unsigned int m_level; - - void TraceIf(unsigned int n, std::string const&s) - { if (n) Trace(n, s); } - - /*! Returns nr if, according to the default log settings mechanism (using log levels), - the message should be traced. Returns 0 if the default trace level mechanism is not - in use, or if it is in use but the event should not be traced. Provided as a utility - method for easier and shorter coding of default TraceXxxx(void) implementations. */ - unsigned int Tracing(unsigned int nr, unsigned int minLevel) const - { return (UsingDefaults() && m_level >= minLevel) ? nr : 0; } -}; - -// Your Tracer-derived class should inherit as virtual public from Tracer or another -// Tracer-derived class, and should pass the log level in its constructor. You can use the -// following methods to begin and end your Tracer definition. - -// This constructor macro initializes Tracer directly even if not derived directly from it; -// this is intended, virtual base classes are always initialized by the most derived class. -#define CRYPTOPP_TRACER_CONSTRUCTOR(DERIVED) \ - public: DERIVED(unsigned int level = 0) : Tracer(level) {} - -#define CRYPTOPP_BEGIN_TRACER_CLASS_1(DERIVED, BASE1) \ - class DERIVED : virtual public BASE1, public NotCopyable { CRYPTOPP_TRACER_CONSTRUCTOR(DERIVED) - -#define CRYPTOPP_BEGIN_TRACER_CLASS_2(DERIVED, BASE1, BASE2) \ - class DERIVED : virtual public BASE1, virtual public BASE2, public NotCopyable { CRYPTOPP_TRACER_CONSTRUCTOR(DERIVED) - -#define CRYPTOPP_END_TRACER_CLASS }; - -// In your Tracer-derived class, you should define a globally unique event number for each -// new event defined. This can be done using the following macros. - -#define CRYPTOPP_BEGIN_TRACER_EVENTS(UNIQUENR) enum { EVENTBASE = UNIQUENR, -#define CRYPTOPP_TRACER_EVENT(EVENTNAME) EventNr_##EVENTNAME, -#define CRYPTOPP_END_TRACER_EVENTS }; - -// In your own Tracer-derived class, you must define two methods per new trace event type: -// - unsigned int TraceXxxx() const -// Your default implementation of this method should return the event number if according -// to the default trace level system the event should be traced, or 0 if it should not. -// - void TraceXxxx(string const& s) -// This method should call TraceIf(TraceXxxx(), s); to do the tracing. -// For your convenience, a macro to define these two types of methods are defined below. -// If you use this macro, you should also use the TRACER_EVENTS macros above to associate -// event names with numbers. - -#define CRYPTOPP_TRACER_EVENT_METHODS(EVENTNAME, LOGLEVEL) \ - virtual unsigned int Trace##EVENTNAME() const { return Tracing(EventNr_##EVENTNAME, LOGLEVEL); } \ - virtual void Trace##EVENTNAME(std::string const& s) { TraceIf(Trace##EVENTNAME(), s); } - - -/*! A simple unidirectional linked list with m_prev == 0 to indicate the final entry. - The aim of this implementation is to provide a very lightweight and practical - tracing mechanism with a low performance impact. Functions and methods supporting - this call-stack mechanism would take a parameter of the form "CallStack const& callStack", - and would pass this parameter to subsequent functions they call using the construct: - - SubFunc(arg1, arg2, CallStack("my func at place such and such", &callStack)); - - The advantage of this approach is that it is easy to use and should be very efficient, - involving no allocation from the heap, just a linked list of stack objects containing - pointers to static ASCIIZ strings (or possibly additional but simple data if derived). */ -class CallStack -{ -public: - CallStack(char const* i, CallStack const* p) : m_info(i), m_prev(p) {} - CallStack const* Prev() const { return m_prev; } - virtual std::string Format() const; - -protected: - char const* m_info; - CallStack const* m_prev; -}; - -/*! An extended CallStack entry type with an additional numeric parameter. */ -class CallStackWithNr : public CallStack -{ -public: - CallStackWithNr(char const* i, word32 n, CallStack const* p) : CallStack(i, p), m_nr(n) {} - std::string Format() const; - -protected: - word32 m_nr; -}; - -/*! An extended CallStack entry type with an additional string parameter. */ -class CallStackWithStr : public CallStack -{ -public: - CallStackWithStr(char const* i, char const* z, CallStack const* p) : CallStack(i, p), m_z(z) {} - std::string Format() const; - -protected: - char const* m_z; -}; - -// Thanks to Maximilian Zamorsky for help with http://connect.microsoft.com/VisualStudio/feedback/details/1570496/ -CRYPTOPP_BEGIN_TRACER_CLASS_1(WaitObjectsTracer, Tracer) - CRYPTOPP_BEGIN_TRACER_EVENTS(0x48752841) - CRYPTOPP_TRACER_EVENT(NoWaitLoop) - CRYPTOPP_END_TRACER_EVENTS - CRYPTOPP_TRACER_EVENT_METHODS(NoWaitLoop, 1) -CRYPTOPP_END_TRACER_CLASS - -struct WaitingThreadData; - -/// container of wait objects -class WaitObjectContainer : public NotCopyable -{ -public: - /// exception thrown by WaitObjectContainer - class Err : public Exception - { - public: - Err(const std::string& s) : Exception(IO_ERROR, s) {} - }; - - static unsigned int MaxWaitObjects(); - - WaitObjectContainer(WaitObjectsTracer* tracer = NULLPTR); - - void Clear(); - void SetNoWait(CallStack const& callStack); - void ScheduleEvent(double milliseconds, CallStack const& callStack); - // returns false if timed out - bool Wait(unsigned long milliseconds); - -#ifdef USE_WINDOWS_STYLE_SOCKETS - virtual ~WaitObjectContainer(); - void AddHandle(HANDLE handle, CallStack const& callStack); -#else - void AddReadFd(int fd, CallStack const& callStack); - void AddWriteFd(int fd, CallStack const& callStack); -#endif - -private: - WaitObjectsTracer* m_tracer; - -#ifdef USE_WINDOWS_STYLE_SOCKETS - void CreateThreads(unsigned int count); - std::vector m_handles; - std::vector m_threads; - HANDLE m_startWaiting; - HANDLE m_stopWaiting; -#else - fd_set m_readfds, m_writefds; - int m_maxFd; -#endif - double m_firstEventTime; - Timer m_eventTimer; - bool m_noWait; - -#ifdef USE_WINDOWS_STYLE_SOCKETS - typedef size_t LastResultType; -#else - typedef int LastResultType; -#endif - enum { LASTRESULT_NOWAIT = -1, LASTRESULT_SCHEDULED = -2, LASTRESULT_TIMEOUT = -3 }; - LastResultType m_lastResult; - unsigned int m_sameResultCount; - Timer m_noWaitTimer; - void SetLastResult(LastResultType result); - void DetectNoWait(LastResultType result, CallStack const& callStack); -}; - -NAMESPACE_END - -#if (CRYPTOPP_MSC_VERSION >= 1900) -# pragma warning(pop) -#endif - -#endif // NO_OS_DEPENDENCE - -#endif // CRYPTOPP_WAIT_H diff --git a/winpipes.cpp b/winpipes.cpp deleted file mode 100644 index 2585dd55..00000000 --- a/winpipes.cpp +++ /dev/null @@ -1,227 +0,0 @@ -// winpipes.cpp - originally written and placed in the public domain by Wei Dai - -#include "pch.h" -#include "config.h" - -#if !defined(NO_OS_DEPENDENCE) && defined(WINDOWS_PIPES_AVAILABLE) - -#include "winpipes.h" -#include "wait.h" - -// Windows 8, Windows Server 2012, and Windows Phone 8.1 need and -#if defined(CRYPTOPP_WIN32_AVAILABLE) -# if ((WINVER >= 0x0602 /*_WIN32_WINNT_WIN8*/) || (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)) -# include -# include -# define USE_WINDOWS8_API -# endif -#endif - -NAMESPACE_BEGIN(CryptoPP) - -WindowsHandle::WindowsHandle(HANDLE h, bool own) - : m_h(h), m_own(own) -{ -} - -WindowsHandle::~WindowsHandle() -{ - if (m_own) - { - try - { - CloseHandle(); - } - catch (const Exception&) - { - CRYPTOPP_ASSERT(0); - } - } -} - -bool WindowsHandle::HandleValid() const -{ - return m_h && m_h != INVALID_HANDLE_VALUE; -} - -void WindowsHandle::AttachHandle(HANDLE h, bool own) -{ - if (m_own) - CloseHandle(); - - m_h = h; - m_own = own; - HandleChanged(); -} - -HANDLE WindowsHandle::DetachHandle() -{ - HANDLE h = m_h; - m_h = INVALID_HANDLE_VALUE; - HandleChanged(); - return h; -} - -void WindowsHandle::CloseHandle() -{ - if (m_h != INVALID_HANDLE_VALUE) - { - ::CloseHandle(m_h); - m_h = INVALID_HANDLE_VALUE; - HandleChanged(); - } -} - -// ******************************************************** - -void WindowsPipe::HandleError(const char *operation) const -{ - DWORD err = GetLastError(); - throw Err(GetHandle(), operation, err); -} - -WindowsPipe::Err::Err(HANDLE s, const std::string& operation, int error) - : OS_Error(IO_ERROR, "WindowsPipe: " + operation + " operation failed with error 0x" + IntToString(error, 16), operation, error) - , m_h(s) -{ -} - -// ************************************************************* - -WindowsPipeReceiver::WindowsPipeReceiver() - : m_lastResult(0), m_resultPending(false), m_eofReceived(false) -{ - m_event.AttachHandle(CreateEvent(NULLPTR, true, false, NULLPTR), true); - CheckAndHandleError("CreateEvent", m_event.HandleValid()); - memset(&m_overlapped, 0, sizeof(m_overlapped)); - m_overlapped.hEvent = m_event; -} - -bool WindowsPipeReceiver::Receive(byte* buf, size_t bufLen) -{ - CRYPTOPP_ASSERT(!m_resultPending && !m_eofReceived); - - const HANDLE h = GetHandle(); - // don't queue too much at once, or we might use up non-paged memory - if (ReadFile(h, buf, UnsignedMin((DWORD)128*1024, bufLen), &m_lastResult, &m_overlapped)) - { - if (m_lastResult == 0) - m_eofReceived = true; - } - else - { - switch (GetLastError()) - { - default: - CheckAndHandleError("ReadFile", false); - // Fall through for non-fatal - case ERROR_BROKEN_PIPE: - case ERROR_HANDLE_EOF: - m_lastResult = 0; - m_eofReceived = true; - break; - case ERROR_IO_PENDING: - m_resultPending = true; - } - } - return !m_resultPending; -} - -void WindowsPipeReceiver::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) -{ - if (m_resultPending) - container.AddHandle(m_event, CallStack("WindowsPipeReceiver::GetWaitObjects() - result pending", &callStack)); - else if (!m_eofReceived) - container.SetNoWait(CallStack("WindowsPipeReceiver::GetWaitObjects() - result ready", &callStack)); -} - -unsigned int WindowsPipeReceiver::GetReceiveResult() -{ - if (m_resultPending) - { -#if defined(USE_WINDOWS8_API) - BOOL result = GetOverlappedResultEx(GetHandle(), &m_overlapped, &m_lastResult, INFINITE, FALSE); -#else - BOOL result = GetOverlappedResult(GetHandle(), &m_overlapped, &m_lastResult, FALSE); -#endif - if (result) - { - if (m_lastResult == 0) - m_eofReceived = true; - } - else - { - switch (GetLastError()) - { - default: - CheckAndHandleError("GetOverlappedResult", false); - // Fall through for non-fatal - case ERROR_BROKEN_PIPE: - case ERROR_HANDLE_EOF: - m_lastResult = 0; - m_eofReceived = true; - } - } - m_resultPending = false; - } - return m_lastResult; -} - -// ************************************************************* - -WindowsPipeSender::WindowsPipeSender() - : m_lastResult(0), m_resultPending(false) -{ - m_event.AttachHandle(CreateEvent(NULLPTR, true, false, NULLPTR), true); - CheckAndHandleError("CreateEvent", m_event.HandleValid()); - memset(&m_overlapped, 0, sizeof(m_overlapped)); - m_overlapped.hEvent = m_event; -} - -void WindowsPipeSender::Send(const byte* buf, size_t bufLen) -{ - DWORD written = 0; - const HANDLE h = GetHandle(); - // don't queue too much at once, or we might use up non-paged memory - if (WriteFile(h, buf, UnsignedMin((DWORD)128*1024, bufLen), &written, &m_overlapped)) - { - m_resultPending = false; - m_lastResult = written; - } - else - { - if (GetLastError() != ERROR_IO_PENDING) - CheckAndHandleError("WriteFile", false); - - m_resultPending = true; - } -} - -void WindowsPipeSender::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack) -{ - if (m_resultPending) - container.AddHandle(m_event, CallStack("WindowsPipeSender::GetWaitObjects() - result pending", &callStack)); - else - container.SetNoWait(CallStack("WindowsPipeSender::GetWaitObjects() - result ready", &callStack)); -} - -unsigned int WindowsPipeSender::GetSendResult() -{ - if (m_resultPending) - { - const HANDLE h = GetHandle(); -#if defined(USE_WINDOWS8_API) - BOOL result = GetOverlappedResultEx(h, &m_overlapped, &m_lastResult, INFINITE, FALSE); - CheckAndHandleError("GetOverlappedResultEx", result); -#else - BOOL result = GetOverlappedResult(h, &m_overlapped, &m_lastResult, FALSE); - CheckAndHandleError("GetOverlappedResult", result); -#endif - m_resultPending = false; - } - return m_lastResult; -} - -NAMESPACE_END - -#endif diff --git a/winpipes.h b/winpipes.h deleted file mode 100644 index 347e800c..00000000 --- a/winpipes.h +++ /dev/null @@ -1,146 +0,0 @@ -#ifndef CRYPTOPP_WINPIPES_H -#define CRYPTOPP_WINPIPES_H - -#include "config.h" - -#if !defined(NO_OS_DEPENDENCE) && defined(WINDOWS_PIPES_AVAILABLE) - -#include "cryptlib.h" -#include "network.h" -#include "queue.h" -#include - -NAMESPACE_BEGIN(CryptoPP) - -/// \brief Windows Handle -class WindowsHandle -{ -public: - virtual ~WindowsHandle(); - - WindowsHandle(HANDLE h = INVALID_HANDLE_VALUE, bool own=false); - WindowsHandle(const WindowsHandle &h) : m_h(h.m_h), m_own(false) {} - - bool GetOwnership() const {return m_own;} - void SetOwnership(bool own) {m_own = own;} - - operator HANDLE() const {return m_h;} - HANDLE GetHandle() const {return m_h;} - bool HandleValid() const; - void AttachHandle(HANDLE h, bool own=false); - HANDLE DetachHandle(); - void CloseHandle(); - -protected: - virtual void HandleChanged() {} - - HANDLE m_h; - bool m_own; -}; - -/// \brief Windows Pipe -class WindowsPipe -{ -public: - class Err : public OS_Error - { - public: - Err(HANDLE h, const std::string& operation, int error); - HANDLE GetHandle() const {return m_h;} - - private: - HANDLE m_h; - }; - -protected: - virtual HANDLE GetHandle() const =0; - virtual void HandleError(const char *operation) const; - void CheckAndHandleError(const char *operation, BOOL result) const - {if (!result) HandleError(operation);} -}; - -/// \brief Pipe-based implementation of NetworkReceiver -class WindowsPipeReceiver : public WindowsPipe, public NetworkReceiver -{ -public: - WindowsPipeReceiver(); - - bool MustWaitForResult() {return true;} - bool Receive(byte* buf, size_t bufLen); - unsigned int GetReceiveResult(); - bool EofReceived() const {return m_eofReceived;} - - HANDLE GetHandle() const {return m_event;} - unsigned int GetMaxWaitObjectCount() const {return 1;} - void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); - -private: - WindowsHandle m_event; - OVERLAPPED m_overlapped; - DWORD m_lastResult; - bool m_resultPending; - bool m_eofReceived; -}; - -/// \brief Pipe-based implementation of NetworkSender -class WindowsPipeSender : public WindowsPipe, public NetworkSender -{ -public: - WindowsPipeSender(); - - bool MustWaitForResult() {return true;} - void Send(const byte* buf, size_t bufLen); - unsigned int GetSendResult(); - bool MustWaitForEof() { return false; } - void SendEof() {} - - HANDLE GetHandle() const {return m_event;} - unsigned int GetMaxWaitObjectCount() const {return 1;} - void GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack); - -private: - WindowsHandle m_event; - OVERLAPPED m_overlapped; - DWORD m_lastResult; - bool m_resultPending; -}; - -/// \brief Windows Pipe Source -class WindowsPipeSource : public WindowsHandle, public NetworkSource, public WindowsPipeReceiver -{ -public: - WindowsPipeSource(HANDLE h=INVALID_HANDLE_VALUE, bool pumpAll=false, BufferedTransformation *attachment=NULLPTR) - : WindowsHandle(h), NetworkSource(attachment) - { - if (pumpAll) - PumpAll(); - } - - using NetworkSource::GetMaxWaitObjectCount; - using NetworkSource::GetWaitObjects; - -private: - HANDLE GetHandle() const {return WindowsHandle::GetHandle();} - NetworkReceiver & AccessReceiver() {return *this;} -}; - -/// \brief Windows Pipe Sink -class WindowsPipeSink : public WindowsHandle, public NetworkSink, public WindowsPipeSender -{ -public: - WindowsPipeSink(HANDLE h=INVALID_HANDLE_VALUE, unsigned int maxBufferSize=0, unsigned int autoFlushBound=16*1024) - : WindowsHandle(h), NetworkSink(maxBufferSize, autoFlushBound) {} - - using NetworkSink::GetMaxWaitObjectCount; - using NetworkSink::GetWaitObjects; - -private: - HANDLE GetHandle() const {return WindowsHandle::GetHandle();} - NetworkSender & AccessSender() {return *this;} -}; - -NAMESPACE_END - -#endif // WINDOWS_PIPES_AVAILABLE - -#endif