Last active
August 6, 2020 11:25
-
-
Save bsergean/08387e2e19601f7df19f74321baebb52 to your computer and use it in GitHub Desktop.
ixwebsocket_issue_227_repro
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ConsoleApplication5.cpp : This file contains the 'main' function. Program execution begins and ends there. | |
// | |
#include <iostream> | |
#include "webSockServer.h" | |
int main() | |
{ | |
std::cout << "Server Starting up!\n"; | |
CWebSocketsServer server(nullptr); | |
server.initialize(); | |
while (true) | |
{ | |
sleep(100); | |
} | |
} | |
// Run program: Ctrl + F5 or Debug > Start Without Debugging menu | |
// Debug program: F5 or Debug > Start Debugging menu | |
// Tips for Getting Started: | |
// 1. Use the Solution Explorer window to add/manage files | |
// 2. Use the Team Explorer window to connect to source control | |
// 3. Use the Output window to see build output and other messages | |
// 4. Use the Error List window to view errors | |
// 5. Go to Project > Add New Item to create new code files, or Project > Add Existing Item to add existing code files to the project | |
// 6. In the future, to open this project again, go to File > Open > Project and select the .sln file |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
namespace eViewState | |
{ | |
enum eViewState | |
{ | |
eventView, | |
GridScriptConsole, | |
unspecified | |
}; | |
} | |
namespace eQRIntentType | |
{ | |
enum eQRIntentType | |
{ | |
QRSign, | |
QRShow, | |
QRStore, | |
QRImportSK, | |
QRImportEncSK, | |
QRImportContact, | |
QRUnknown | |
}; | |
} | |
namespace eIdentityTokenType | |
{ | |
enum eIdentityTokenType | |
{ | |
identityOnly, | |
PoW, | |
Stake, | |
Hybrid | |
}; | |
} | |
namespace eKeyCode | |
{ | |
enum eKeyCode | |
{ | |
arrowUp, | |
arrowDown, | |
arrowLeft, | |
arrowRight | |
}; | |
} | |
namespace eDTISessionStatus | |
{ | |
enum eDTISessionStatus | |
{ | |
initial, | |
alive, | |
ended | |
}; | |
} | |
namespace eDFSSessionStatus | |
{ | |
enum eDFSSessionStatus | |
{ | |
initial, | |
alive, | |
ended | |
}; | |
} | |
namespace eDTIEvent | |
{ | |
enum eDTIEvent | |
{ | |
interacted, | |
sessionStarted, | |
warningIssued | |
}; | |
} | |
namespace eFileMode | |
{ | |
enum eFileMode | |
{ | |
string, | |
binary | |
}; | |
} | |
namespace eTransactionsManagerMode | |
{ | |
enum eTransactionsManagerMode | |
{ | |
LIVE, | |
Flow, | |
Terminal | |
}; | |
} | |
namespace ePastEpochRewardCalculationMode | |
{ | |
enum ePastEpochRewardCalculationMode | |
{ | |
total, | |
ALeader, | |
BLeader | |
}; | |
} | |
namespace eDataPubResult | |
{ | |
enum eDataPubResult | |
{ | |
success, | |
failure | |
}; | |
} | |
namespace eCompileMode | |
{ | |
enum eCompileMode | |
{ | |
FAPIImplicit, | |
FAPIExplicit, | |
PreAuthentication, | |
Invalid | |
}; | |
} | |
namespace eManagerStatus | |
{ | |
enum eManagerStatus | |
{ | |
running, | |
paused, | |
stoppped, | |
initial | |
}; | |
} | |
namespace eBlockProcessingStatus | |
{ | |
enum eBlockProcessingStatus | |
{ | |
idle, | |
preProcessing, | |
processing, | |
validating, | |
commiting, | |
PostProcessing, | |
}; | |
} | |
namespace eBlockchainMode | |
{ | |
enum eBlockchainMode | |
{ | |
LIVE, | |
TestNet, | |
LIVESandBox,//without access to SolidStorage at all.//refreshed on demand. | |
TestNetSandBox,//without access to SolidStorage at all.//refreshed on demand | |
LocalData, | |
Unknown | |
}; | |
} | |
namespace eParamInsertionMethod | |
{ | |
enum eParamInsertionMethod | |
{ | |
number, | |
base58encoded, | |
RAWString, | |
remove | |
}; | |
} | |
namespace eCMDExecutorState | |
{ | |
enum eCMDExecutorState | |
{ | |
GridScriptDebugger = 1, | |
ViewControl = 0 | |
}; | |
} | |
namespace eBlockInfoRetrievalResult | |
{ | |
enum eBlockInfoRetrievalResult | |
{ | |
blockBodyUnavailable, | |
OK | |
}; | |
} | |
namespace eNodeType | |
{ | |
enum eNodeType | |
{ | |
extNode = 1, | |
branchNode = 2, | |
leafNode = 3 | |
}; | |
} | |
namespace eNodeSubType | |
{ | |
enum eNodeSubType | |
{ | |
RAW = 0, | |
stateDomain = 1, | |
transaction = 2, | |
receipt = 3, | |
verifiable = 4, | |
TrieDB = 5 | |
}; | |
} | |
namespace eBlockVerificationResult { | |
enum eBlockVerificationResult { | |
valid, | |
invalid, | |
unknownBlockOnPath, | |
unknownParent, | |
insufficientTotalPoW, | |
insufficientPoW, | |
parentPerspectiveUnavailavble, | |
inconsistentFinalPerspective, | |
flowInvalid, | |
unableToStartFlow, | |
receiptMissing, | |
transactionMissing, | |
verifiableMissing, | |
criticalFailure, | |
timeDiffExceeded, | |
headerMissing, | |
invalidSignature, | |
pubKeyMissing, | |
sigMissing, | |
noKeyBlockForDataBlock, | |
keyParentUnknown, | |
invalidBlockHeight, | |
rewardVerifiableMissing, | |
invalidKeyHeightForDataBlock, | |
leaderAttemptedADoubleSpendAttack, | |
invalidTotalFeesField | |
}; | |
} | |
namespace eChainProofUpdateResult | |
{ | |
enum eChainProofUpdateResult | |
{ | |
updated, | |
updatedLocalBestKnown, | |
totalDiffLower, | |
noCommonPointFound, | |
invalidData, | |
Error | |
}; | |
} | |
namespace eChainProofCommitResult | |
{ | |
enum eChainProofCommitResult | |
{ | |
blocksCommited, | |
chainWon, //when the total cumulative PoW of of the sub-chain of the heaviest chainproof is > mVerifiedChainProofTotalDifficulty THEN that subchain becomes the new mVerifiedChainProof | |
noCommits | |
}; | |
} | |
namespace eChainProof | |
{ | |
enum eChainProof | |
{ | |
verified, | |
heaviest | |
}; | |
} | |
namespace eBERObjectType | |
{ | |
enum eBERObjectType | |
{ | |
keyBlock, | |
keyBlockHeader, | |
regularBlock, | |
regularBlockHeader | |
}; | |
} | |
namespace eBlockInstantiationResult { | |
enum eBlockInstantiationResult { | |
OK, | |
Failure, | |
headerInstantationFailure, | |
parentMissing, | |
blockFetchedFromCache, | |
blockFetchedFromSS, | |
blockFetchedFromPointer, | |
blockDataUnavailableInCS, | |
blockInstantiatedTransactionTrieNodesMissing, | |
blockInstantiatedVerifiablesTrieNodesMissing, | |
blockInstantiatedReceiptsTrieNodesMissing, | |
}; | |
} | |
namespace eReceiptType | |
{ | |
enum eReceiptType { | |
transaction, | |
verifiable | |
}; | |
} | |
namespace eVerifiableType | |
{ | |
enum eVerifiableType | |
{ | |
minerReward, | |
GenesisRewards, | |
uncleBlock, | |
dataPropagation, | |
powerGeneration, | |
powerTransit, | |
proofOfFraud | |
}; | |
} | |
namespace eLinkType | |
{ | |
//we can traverse from Receipt's GUID, to Receipt's HASH and then | |
//used that HASH to find in WHICH BLOCK the receipt is stored. | |
//receipts, transactions and verifiables are retrieved from Blocks by their HASH. | |
enum eLinkType | |
{ | |
receiptsGUIDtoReceiptsHash, | |
transactionHashToBlockID, | |
verifiableHashToBlockID, | |
receiptHashToBlockID, | |
BHeightPKtoBlockHeader, //hash([blockHeight,LeaderPK]) to BlockHeader bytes *Used for proof-of-fraud*// the block does not need to be stored locally, but the body of link provides header | |
PoFIDtoReceiptID,//used by Proof-of-Fraud | |
friendlyIDtoAddr | |
}; | |
} | |
namespace eDeletedType | |
{ | |
enum eDeletedType | |
{ | |
TrieDB | |
}; | |
} | |
namespace eFraudCheckResult | |
{ | |
enum eFraudCheckResult | |
{ | |
keyBlockUnavailable, | |
newFraud, | |
OK, | |
error, | |
alreadyReported | |
}; | |
} | |
namespace eNetTaskProcessingResult | |
{ | |
enum eNetTaskProcessingResult | |
{ | |
succedded, | |
aborted, | |
inProgress, | |
error | |
}; | |
} | |
namespace eDFSTaskProcessingResult | |
{ | |
enum eDFSTaskProcessingResult | |
{ | |
succedded, | |
aborted, | |
inProgress, | |
error | |
}; | |
} | |
namespace eNetEntType | |
{ | |
enum eNetEntType | |
{ | |
unknown, | |
block, | |
transaction, | |
verifiable, | |
msg, | |
chainProof, | |
longestPath, | |
sec, | |
receiptBody, | |
receiptID, | |
ping, | |
hello,//contains client information, version etc. | |
bye, | |
QRIntentResponse, | |
DFS, | |
VMStatus, | |
ConnectionStatus, | |
VMMetaData//might encapsulate QRIntentRequest | |
}; | |
} | |
namespace eReqDataType { | |
enum eReqDataType | |
{ | |
text, | |
number, | |
binary | |
}; | |
} | |
namespace eNetReqType { | |
enum eNetReqType | |
{ | |
unknown, | |
notify, | |
request, | |
process | |
}; | |
} | |
namespace eVMStatus | |
{ | |
enum eVMStatus | |
{ | |
initializing, | |
ready, | |
aboutToShutDown, | |
disabled | |
}; | |
} | |
namespace eConnectionStatus | |
{ | |
enum eConnectionStatus | |
{ | |
initializing, | |
ready, | |
aboutToShutDown, | |
disabled | |
}; | |
} | |
namespace eVMMetaCodeExecutionMode | |
{ | |
enum eVMMetaCodeExecutionMode { | |
RAW, | |
GUI, | |
GUITerminal | |
}; | |
} | |
namespace eVMMetaSectionType | |
{ | |
enum eVMMetaSectionType | |
{ | |
unknown, | |
directoryListing, | |
fileContents, | |
notifications, | |
requests | |
}; | |
} | |
namespace eVMMetaEntryType | |
{ | |
enum eVMMetaEntryType | |
{ | |
unknown, | |
directoryEntry, | |
fileContent, | |
notification, | |
dataRequest, | |
dataResponse, | |
GridScriptCode, | |
GridScriptCodeResponse, | |
cryptoTransfer, | |
}; | |
} | |
namespace eDFSElementType | |
{ | |
enum eDFSElementType | |
{ | |
unknown, | |
stateDomainEntry, | |
fileEntry, | |
directoryEntry, | |
fileContent | |
}; | |
} | |
namespace eDataRequestType | |
{ | |
enum eDataRequestType | |
{ | |
unknown, | |
QRIntentAuth, | |
string, | |
integer, | |
binary, | |
boolean | |
}; | |
} | |
namespace eNotificationType | |
{ | |
enum eNotificationType | |
{ | |
unknown, | |
notification, | |
warning, | |
error | |
}; | |
} | |
namespace eDFSCmdType | |
{ | |
enum eDFSCmdType | |
{ | |
unknown, | |
init,//initiates decentralized file-sub system | |
ready,//ready-indicator | |
error,//error - more info in mData1 | |
exists,// check if path exists | |
stat, | |
execute,//executes dApp | |
readDir,//list directory content (LS) | |
readFile,//retrieve file ; path in mData1 (less) | |
writeFile,//write file; path in mData1, content in mData2 (cat) | |
rename,//rename file/dir. pathA in mData1, pathB in mData2 | |
copy,//copy file/dir. pathA in mData1, pathB in mData2 | |
unlink, | |
search,//find file/dir. Regex in mData1 | |
touch, | |
sessionStat, | |
requestCommit,//request QRIntent | |
QRIntentData,//serialized QRIntent in mData1 | |
commit,//provide serialized QRIntentResponse in mData1 | |
//content retrieval: | |
fileContent,// file path in mData1, content in mData2 | |
directoryContent,//sequence of vectors in mData1 | |
enterDir, | |
createDir, | |
sync | |
}; | |
} | |
namespace eWebSocketService | |
{ | |
enum eWebSocketService | |
{ | |
fileSystem = 0, | |
transactions = 1, | |
}; | |
} | |
namespace eWebSocketStatus | |
{ | |
enum eWebSocketStatus | |
{ | |
killed = 0, | |
alive = 1 | |
}; | |
} | |
namespace eWebSocketProcessingResult | |
{ | |
enum eWebSocketProcessingResult | |
{ | |
OK = 0, | |
invalidPacket = 1, | |
invalidService = 2, | |
invalidSession = 3 | |
}; | |
} | |
namespace eQRProcessingResult | |
{ | |
enum eQRProcessingResult | |
{ | |
error, | |
Ok | |
}; | |
} | |
namespace eFSCmdResult | |
{ | |
enum eFSCmdResult | |
{ | |
unknown, | |
error, | |
invalidCmd, | |
Ok | |
}; | |
} | |
namespace eFSCommitResult | |
{ | |
enum eFSCommitResult | |
{ | |
unknown, | |
error, | |
Ok | |
}; | |
} | |
namespace eFSEntityType | |
{ | |
enum eFSEntityType | |
{ | |
unknown, | |
file, | |
dir | |
}; | |
} | |
namespace eConversationProtocol | |
{ | |
enum eConversationProtocol { | |
UDT, | |
WebSockets | |
}; | |
} | |
namespace eNetTaskType | |
{ | |
enum eNetTaskType//types of global network tasks; these tasks are distributed amonng neighboors | |
{ | |
startConversation, | |
endConversation, | |
getBlock, | |
notifyBlock, | |
downloadUpdate, | |
checkForUpdate, | |
sync,//query all neighboors nodes for a newer chainProof | |
sendQRIntentResponse, | |
notifyReceiptID, | |
notifyReceiptBody, | |
awaitReceiptID, | |
sendRAWData, | |
DFSTask,// command-details encapsulated within CNetMsgs's data field (trough a serialized CDFSMsg), | |
sendVMMetaData, //i.e. may contain a QR-Intent processing request or other data-requests, user-interaction requests, | |
requestData | |
}; | |
} | |
namespace eNetTaskState | |
{ | |
enum eNetTaskState | |
{ | |
initial, | |
assigned, | |
working, | |
completed, | |
aborted | |
}; | |
} | |
namespace eDFSTaskState | |
{ | |
enum eDFSTaskState | |
{ | |
initial, | |
assigned, | |
working, | |
completed, | |
aborted | |
}; | |
} | |
namespace eObjectSubType | |
{ | |
enum eObjectSubType | |
{ | |
Transaction = 2, | |
Verifiable = 4 | |
}; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<header> | |
<script type="text/javascript"> | |
class CExploit { | |
constructor() { | |
this.mURI = 'ws://localhost:26039/'; | |
this.mWebSocket = new WebSocket(this.mURI); | |
setTimeout(this.attemptSomething.bind(this), 1000); | |
} | |
attemptSomething() { | |
if (this.mWebSocket.readyState == this.mWebSocket.OPEN) { | |
{ | |
this.mWebSocket.close(); | |
} | |
this.mWebSocket = new WebSocket(this.mURI); | |
} | |
setTimeout(this.attemptSomething.bind(this), 1000); | |
} | |
} | |
let exp = new CExploit(); | |
</script> | |
</header> | |
<body> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include "enums.h" | |
#include <mutex> | |
class IManager | |
{ | |
public: | |
void setIsReady(bool is = true); | |
bool getIsReady(); | |
virtual void stop() = 0; | |
virtual void pause() = 0; | |
virtual void resume() = 0; | |
virtual eManagerStatus::eManagerStatus getStatus() = 0; | |
private: | |
virtual void requestStatusChange(eManagerStatus::eManagerStatus status) = 0; | |
virtual eManagerStatus::eManagerStatus getRequestedStatusChange() = 0; | |
std::recursive_mutex mIsReadyGuardian; | |
bool mIsReady = false; | |
virtual void setStatus(eManagerStatus::eManagerStatus status) = 0; | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
all: | |
clang++ --std=c++14 --stdlib=libc++ -I/usr/local/include webSockServer.cpp ConsoleApplication5.cpp -L/usr/local/lib -lixwebsocket -framework foundation -framework Security -lz |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "webSockServer.h" | |
#include <ixwebsocket/IXWebSocketServer.h> | |
#include <ixwebsocket/IXWebSocket.h> | |
bool CWebSocketsServer::initialize() | |
{ | |
return initializeServer(); | |
} | |
void CWebSocketsServer::stop() | |
{ | |
std::lock_guard<std::recursive_mutex> lock(mGuardian); | |
//firs ensure no new session come-in | |
if (getStatus() == eManagerStatus::eManagerStatus::stoppped) | |
return; | |
mStatusChange = eManagerStatus::eManagerStatus::stoppped; | |
if (!mControllerThread.joinable() && getStatus() != eManagerStatus::eManagerStatus::stoppped)//controller is dead; we need first to thwart it for to enable for a state-transmission. | |
mControllerThread = std::thread(&CWebSocketsServer::mControllerThreadF, this); | |
while (getStatus() != eManagerStatus::eManagerStatus::stoppped && getStatus() != eManagerStatus::eManagerStatus::initial) | |
{ | |
std::this_thread::sleep_for(std::chrono::milliseconds(100)); | |
} | |
if (mControllerThread.joinable()) | |
mControllerThread.join(); | |
//then clean-up data structures / free memory | |
doCleaningUp(true);//kill all active ones | |
ix::uninitNetSystem(); | |
} | |
void CWebSocketsServer::pause() | |
{ | |
} | |
void CWebSocketsServer::resume() | |
{ | |
} | |
void CWebSocketsServer::mControllerThreadF() | |
{ | |
std::string tName = "WebSockets-Conversations Controller"; | |
setStatus(eManagerStatus::eManagerStatus::running); | |
bool wasPaused = false; | |
if (mStatus != eManagerStatus::eManagerStatus::running) | |
setStatus(eManagerStatus::eManagerStatus::running); | |
uint64_t justCommitedFromHeaviestChainProof = 0; | |
mWebSocketServerThread = std::thread(&CWebSocketsServer::WebSocketServerThreadF, this); | |
while (mStatus != eManagerStatus::eManagerStatus::stoppped) | |
{ | |
std::this_thread::sleep_for(std::chrono::milliseconds(100)); | |
wasPaused = false; | |
if (mStatusChange == eManagerStatus::eManagerStatus::paused) | |
{ | |
setStatus(eManagerStatus::eManagerStatus::paused); | |
mStatusChange = eManagerStatus::eManagerStatus::initial; | |
while (mStatusChange == eManagerStatus::eManagerStatus::initial) | |
{ | |
if (!wasPaused) | |
{ | |
// mTools->writeLine("My thread operations were freezed. Halting.."); | |
if (mWebSocketServerThread.native_handle() != 0) | |
{ | |
while (!mWebSocketServerThread.joinable()) | |
std::this_thread::sleep_for(std::chrono::milliseconds(100)); | |
mWebSocketServerThread.join(); | |
} | |
wasPaused = true; | |
} | |
std::this_thread::sleep_for(std::chrono::milliseconds(100)); | |
} | |
} | |
if (wasPaused) | |
{ | |
mWebSocketServerThread = std::thread(&CWebSocketsServer::WebSocketServerThreadF, this); | |
mStatus = eManagerStatus::eManagerStatus::running; | |
} | |
if (mStatusChange == eManagerStatus::eManagerStatus::stoppped) | |
{ | |
mStatusChange = eManagerStatus::eManagerStatus::initial; | |
mStatus = eManagerStatus::eManagerStatus::stoppped; | |
} | |
} | |
doCleaningUp(true);//kill all the connections; do not allow for Zombie-connections | |
setStatus(eManagerStatus::eManagerStatus::stoppped); | |
} | |
eManagerStatus::eManagerStatus CWebSocketsServer::getStatus() | |
{ | |
std::lock_guard<std::recursive_mutex> lock(mStatusGuardian); | |
return mStatus; | |
} | |
void CWebSocketsServer::setStatus(eManagerStatus::eManagerStatus status) | |
{ | |
std::lock_guard<std::recursive_mutex> lock(mStatusGuardian); | |
if (mStatus == status) | |
return; | |
mStatus = status; | |
switch (status) | |
{ | |
case eManagerStatus::eManagerStatus::running: | |
break; | |
case eManagerStatus::eManagerStatus::paused: | |
break; | |
case eManagerStatus::eManagerStatus::stoppped: | |
break; | |
default: | |
break; | |
} | |
} | |
void CWebSocketsServer::requestStatusChange(eManagerStatus::eManagerStatus status) | |
{ | |
std::lock_guard<std::mutex> lock(mStatusChangeGuardian); | |
mStatusChange = status; | |
} | |
eManagerStatus::eManagerStatus CWebSocketsServer::getRequestedStatusChange() | |
{ | |
std::lock_guard<std::mutex> lock(mStatusChangeGuardian); | |
return mStatusChange; | |
} | |
size_t CWebSocketsServer::getLastTimeCleanedUp() | |
{ | |
std::lock_guard<std::mutex> lock(mFieldsGuardian); | |
return mLastTimeCleaned; | |
} | |
size_t CWebSocketsServer::getActiveSessionsCount() | |
{ | |
std::lock_guard<std::recursive_mutex> lock(mConversationsGuardian); | |
return mConversations.size(); | |
} | |
size_t CWebSocketsServer::getMaxSessionsCount() | |
{ | |
return 100; | |
} | |
void CWebSocketsServer::setLastTimeCleanedUp(size_t timestamp) | |
{ | |
// std::lock_guard<std::mutex> lock(mFieldsGuardian); | |
mLastTimeCleaned = 0;//timestamp != 0 ? (timestamp) : (mTools->getTime()); | |
} | |
CWebSocketsServer::CWebSocketsServer(std::shared_ptr<CBlockchainManager> bm) | |
{ | |
mLastTimeCleaned = 0; | |
// mTools = bm->getTools(); | |
mBlockchainManager = bm; | |
//mBlockchainMode = bm->getMode(); | |
//mNetworkManager = bm->getNetworkManager(); | |
//mStatus = eManagerStatus::eManagerStatus::initial; | |
} | |
std::shared_ptr<ix::WebSocketServer> CWebSocketsServer::getWebSockServer() | |
{ | |
std::lock_guard<std::recursive_mutex> lock(mGuardian); | |
return mServer; | |
} | |
std::vector<std::shared_ptr<CConversation>> CWebSocketsServer::getConversationsByIP(std::string IP) | |
{ | |
std::vector<std::shared_ptr<CConversation>> toRet; | |
if (IP.size() == 0) | |
return toRet; | |
std::lock_guard<std::recursive_mutex> lock(mConversationsGuardian); | |
for (uint64_t i = 0; i < mConversations.size(); i++) | |
{ | |
// if (mTools->doStringsMatch(mConversations[i]->getEndpoint()->getIP(), IP)) | |
// toRet.push_back(mConversations[i]); | |
} | |
return toRet; | |
} | |
bool CWebSocketsServer::registerConversation(std::shared_ptr<CConversation> session) | |
{ | |
std::lock_guard<std::recursive_mutex> lock(mConversationsGuardian); | |
if (mConversations.size() < mMaxSessions) | |
{ | |
mConversations.push_back(session); | |
//mTools->writeLine("Allowed for a new WebSock connection from " + session->getEndpoint()->getIP());//+ std::string(clienthost) + ":" + std::string(clientservice)); | |
return true; | |
} | |
else | |
return false; | |
} | |
std::shared_ptr<CConversation> CWebSocketsServer::getConversationByID(std::vector<uint8_t> id) | |
{ | |
std::lock_guard<std::recursive_mutex> lock(mConversationsGuardian); | |
for (uint64_t i = 0; i < mConversations.size(); i++) | |
{ | |
// if (mTools->compareByteVectors(mConversations[i]->getID(), id)) | |
// return mConversations[i]; | |
} | |
return nullptr; | |
} | |
uint64_t CWebSocketsServer::cleanConversations() | |
{ | |
return 0; | |
} | |
uint64_t CWebSocketsServer::doCleaningUp(bool forceKillAllSessions) | |
{ | |
return 0; | |
} | |
void CWebSocketsServer::WebSocketServerThreadF() | |
{ | |
uint64_t cleanedCount = 0; | |
uint64_t alreadyConnected = 0; | |
std::string ip; | |
//mTools->SetThreadName("WebSock-Conversations Server"); | |
// Run the server in the background. Server can be stoped by calling server.stop() | |
if (mServer != nullptr) | |
mServer->start(); | |
//accept an incoming connection | |
while (getStatus() == eManagerStatus::eManagerStatus::running) | |
{ | |
cleanedCount = doCleaningUp(); | |
// if (cleanedCount > 0) | |
// mTools->writeLine("Freed " + std::to_string(cleanedCount) + " WebSock Conversations"); | |
//START to accept WebSocket connections | |
//+that was initiated during server initialization already | |
//+ client acceptance Lambda function also created during initialization | |
// std::shared_ptr<CEndPoint> ep = std::make_shared<CEndPoint>(clienthost, eEndpointType::IPv4, nullptr, CGlobalSecSettings::getDefaultPortNrDataExchange(mBlockchainMode)); | |
//std::shared_ptr< CConversation> conversation = std::make_shared<CConversation>(clientSocket, CBlockchainManager::getInstance(mBlockchainMode), mNetworkManager, ep); | |
alreadyConnected = 0; | |
//allow only one UDT conversation per IP address - END | |
sleep(500); | |
} | |
if (mServer != nullptr) | |
mServer->stop(); | |
} | |
bool CWebSocketsServer::initializeServer() | |
{ | |
if (!ix::initNetSystem()) | |
return false; | |
mServer = std::make_shared <ix::WebSocketServer>(26039); | |
// ix::WebSocketServer server; | |
std::string connectionId; | |
mServer->setOnConnectionCallback([this, &connectionId]( | |
std::weak_ptr<ix::WebSocket> webSocket, | |
std::shared_ptr< ix::ConnectionState> connectionState, | |
std::unique_ptr<ix::ConnectionInfo> connectionInfo) { | |
auto ws = webSocket.lock(); | |
if (ws) | |
{ | |
ws->disableAutomaticReconnection(); | |
if (getConversationsByIP(connectionInfo->remoteIp).size() >= 4) | |
{ | |
//sendNetMsgRAW(webSocket, eNetEntType::bye, eNetReqType::notify, mTools->stringToBytes("Connection limit reached wait or try another node.")); | |
//mTools->writeLine("Excessive incomming connection from IP: " + connectionInfo->remoteIp); | |
return; | |
} | |
} | |
//std::shared_ptr<CEndPoint> ep = std::make_shared<CEndPoint>(connectionInfo->remoteIp, eEndpointType::IPv4, nullptr, connectionInfo->remotePort); | |
//std::shared_ptr<CConversation> conversation = std::make_shared <CConversation>(webSocket, mBlockchainManager, mNetworkManager, ep, nullptr); | |
//if (!this->registerConversation(conversation)) | |
//{ | |
// sendNetMsgRAW(webSocket, eNetEntType::bye, eNetReqType::notify, mTools->stringToBytes("Connection limit reached wait or try another node.")); | |
// webSocket->send("Connection limit reached. Try another node."); | |
// return; | |
//} | |
// else | |
// { | |
// conversation->startWebSockConversation(webSocket); | |
//webSocket->sendText(std::to_string(conversation->getID()));//send session ID | |
//reply with sessionID | |
// } | |
}); | |
auto res = mServer->listen(); | |
if (!res.first) | |
{ | |
// Error handling | |
return false; | |
} | |
//start the controller thread which in turn would spawn the server thread. | |
mControllerThread = std::thread(&CWebSocketsServer::mControllerThreadF, this); | |
return true; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#pragma once | |
#include <cmath> | |
#include <sstream> | |
#include <iomanip> | |
#include <random> | |
#include <limits> | |
#include <stdlib.h> | |
#include <algorithm> | |
#include <iostream> | |
#include <cctype> | |
#include "IManager.h" | |
#include <ixwebsocket/IXNetSystem.h> | |
#include <ixwebsocket/IXWebSocket.h> | |
#include <ixwebsocket/IXWebSocketServer.h> | |
class CConversation; | |
class CBlockchainManager; | |
class CNetworkManager; | |
class CWebSocketResponse; | |
class CConversation; | |
/// <summary> | |
/// Implements a Web-Socket server. The server manages WebSockets. The incomming/outgoing commands have no state. | |
// Sessions CAN be maintained through underlying 'protocols' accessed through the WebSocket server. Decomposition and processing of such sessions SHOULD BE | |
// managed by the coresponding protocol's server. Still, the WebSockets server comes with an auto-firewall capabilties, tracking intensivity of queries per IP. | |
/// </summary> | |
class CWebSocketsServer : public std::enable_shared_from_this<CWebSocketsServer>, public IManager | |
{ | |
public: | |
CWebSocketsServer(std::shared_ptr<CBlockchainManager> bm); | |
bool initialize(); | |
// Inherited via IManager | |
virtual void stop() override; | |
virtual void pause() override; | |
virtual void resume() override; | |
void mControllerThreadF(); | |
virtual eManagerStatus::eManagerStatus getStatus() override; | |
virtual void setStatus(eManagerStatus::eManagerStatus status) override; | |
// Inherited via IManager | |
virtual void requestStatusChange(eManagerStatus::eManagerStatus status) override; | |
virtual eManagerStatus::eManagerStatus getRequestedStatusChange() override; | |
size_t getLastTimeCleanedUp(); | |
size_t getActiveSessionsCount(); | |
size_t getMaxSessionsCount(); | |
void setLastTimeCleanedUp(size_t timestamp = 0); | |
//commands | |
//std::shared_ptr<CWebSocketResponse> processInput(std::vector<uint8_t> input); | |
std::shared_ptr<ix::WebSocketServer> getWebSockServer(); | |
std::vector<std::shared_ptr<CConversation>> getConversationsByIP(std::string IP); | |
bool registerConversation(std::shared_ptr<CConversation> conversation); | |
std::shared_ptr<CConversation> getConversationByID(std::vector<uint8_t> id); | |
private: | |
uint64_t cleanConversations(); | |
uint64_t doCleaningUp(bool forceKill = false); | |
//CMD-processing | |
std::shared_ptr<ix::WebSocketServer> mServer; | |
std::recursive_mutex mConversationsGuardian; | |
std::vector<std::shared_ptr<CConversation>> mConversations; | |
size_t mMaxWarningsCount; | |
size_t mMaxSessions; | |
std::shared_ptr<CBlockchainManager> mBlockchainManager; | |
eBlockchainMode::eBlockchainMode mBlockchainMode; | |
eManagerStatus::eManagerStatus mStatus; | |
std::thread mControllerThread; | |
eManagerStatus::eManagerStatus mStatusChange; | |
std::recursive_mutex mStatusGuardian, mGuardian; | |
std::mutex mFieldsGuardian; | |
bool mShutdown; | |
std::thread mWebSocketServerThread; | |
void WebSocketServerThreadF(); | |
//bool sendNetMsgRAW(std::shared_ptr<ix::WebSocket> socket, eNetEntType::eNetEntType eNetType, eNetReqType::eNetReqType eNetReqType, std::vector<uint8_t> RAWbytes); | |
//bool sendNetMsg(std::shared_ptr<ix::WebSocket> socket, eNetEntType::eNetEntType eNetType, eNetReqType::eNetReqType eNetReqType, eDFSCmdType::eDFSCmdType dfsCMDType, std::vector<uint8_t> dfsData1, std::vector<uint8_t> NetMSGRAWbytes); | |
bool initializeServer(); | |
size_t mLastTimeCleaned; | |
std::mutex mStatusChangeGuardian; | |
std::shared_ptr<CNetworkManager> mNetworkManager; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment