/* ###### Create new session ############################################# */ struct Session* addSession(struct RSerPoolSocket* rserpoolSocket, const sctp_assoc_t assocID, const bool isIncoming, const unsigned char* poolHandle, const size_t poolHandleSize, struct TagItem* tags) { struct Session* session = (struct Session*)malloc(sizeof(struct Session)); if(session != NULL) { CHECK(rserpoolSocket->ConnectedSession == NULL); session->Tags = tagListDuplicate(tags); if(session->Tags == NULL) { free(session); return(NULL); } simpleRedBlackTreeNodeNew(&session->AssocIDNode); simpleRedBlackTreeNodeNew(&session->SessionIDNode); session->AssocID = assocID; session->IsIncoming = isIncoming; session->IsFailed = isIncoming ? false : true; if(poolHandleSize > 0) { CHECK(poolHandleSize <= MAX_POOLHANDLESIZE); poolHandleNew(&session->Handle, poolHandle, poolHandleSize); } else { session->Handle.Size = 0; } session->Cookie = NULL; session->CookieSize = 0; session->CookieEcho = NULL; session->CookieEchoSize = 0; session->StatusText[0] = 0x00; session->ConnectionTimeStamp = (isIncoming == true) ? getMicroTime() : 0; session->ConnectedPE = 0; session->ConnectTimeout = (unsigned long long)tagListGetData(tags, TAG_RspSession_ConnectTimeout, 5000000); session->HandleResolutionRetryDelay = (unsigned long long)tagListGetData(tags, TAG_RspSession_HandleResolutionRetryDelay, 250000); threadSafetyLock(&rserpoolSocket->Mutex); session->SessionID = identifierBitmapAllocateID(rserpoolSocket->SessionAllocationBitmap); if(session->SessionID >= 0) { threadSafetyLock(&rserpoolSocket->SessionSetMutex); sessionStorageAddSession(&rserpoolSocket->SessionSet, session); threadSafetyUnlock(&rserpoolSocket->SessionSetMutex); LOG_ACTION fprintf(stdlog, "Added %s session %u on RSerPool socket %d, socket %d\n", session->IsIncoming ? "incoming" : "outgoing", session->SessionID, rserpoolSocket->Descriptor, rserpoolSocket->Socket); LOG_END }
/* ###### Handle incoming CSP message #################################### */ static void handleMessage(int sd, struct SimpleRedBlackTree* objectStorage, struct SimpleRedBlackTree* objectDisplay) { struct ComponentStatusReport* cspReport; struct CSPObject* cspObject; char buffer[65536]; ssize_t received; size_t i; received = ext_recv(sd, (char*)&buffer, sizeof(buffer), 0); if(received) { cspReport = (struct ComponentStatusReport*)&buffer; if( (received >= (ssize_t)sizeof(struct ComponentStatusReport)) && (cspReport->Header.Type == CSPT_REPORT) && (ntohl(cspReport->Header.Version) == CSP_VERSION) ) { cspReport->Header.Version = ntohl(cspReport->Header.Version); cspReport->Header.Length = ntohs(cspReport->Header.Length); cspReport->Header.SenderID = ntoh64(cspReport->Header.SenderID); cspReport->Header.SenderTimeStamp = ntoh64(cspReport->Header.SenderTimeStamp); cspReport->ReportInterval = ntohl(cspReport->ReportInterval); cspReport->Workload = ntohs(cspReport->Workload); cspReport->Associations = ntohs(cspReport->Associations); if(sizeof(struct ComponentStatusReport) + (cspReport->Associations * sizeof(struct ComponentAssociation)) == (size_t)received) { for(i = 0;i < cspReport->Associations;i++) { cspReport->AssociationArray[i].ReceiverID = ntoh64(cspReport->AssociationArray[i].ReceiverID); cspReport->AssociationArray[i].Duration = ntoh64(cspReport->AssociationArray[i].Duration); cspReport->AssociationArray[i].Flags = ntohs(cspReport->AssociationArray[i].Flags); cspReport->AssociationArray[i].ProtocolID = ntohs(cspReport->AssociationArray[i].ProtocolID); cspReport->AssociationArray[i].PPID = ntohl(cspReport->AssociationArray[i].PPID); } cspObject = findCSPObject(objectStorage, cspReport->Header.SenderID); if(cspObject == NULL) { cspObject = (struct CSPObject*)malloc(sizeof(struct CSPObject)); if(cspObject) { simpleRedBlackTreeNodeNew(&cspObject->StorageNode); simpleRedBlackTreeNodeNew(&cspObject->DisplayNode); cspObject->Identifier = cspReport->Header.SenderID; cspObject->AssociationArray = NULL; switch(CID_GROUP(cspObject->Identifier)) { case CID_GROUP_REGISTRAR: totalPRs++; break; case CID_GROUP_POOLELEMENT: totalPEs++; break; case CID_GROUP_POOLUSER: totalPUs++; break; } } } if(cspObject) { if(simpleRedBlackTreeNodeIsLinked(&cspObject->DisplayNode)) { /* The position within the objectDisplay storage may change, due to updated locationArray! */ CHECK(simpleRedBlackTreeRemove(objectDisplay, &cspObject->DisplayNode) == &cspObject->DisplayNode); simpleRedBlackTreeVerify(objectDisplay); } if(cspReport->Header.Flags != 0x00) { cspObject->LastReportTimeStamp = 0; } else { cspObject->LastReportTimeStamp = getMicroTime(); cspObject->SenderTimeStamp = cspReport->Header.SenderTimeStamp; cspObject->ReportInterval = cspReport->ReportInterval; cspObject->Workload = CSR_GET_WORKLOAD(cspReport->Workload); getDescriptionForID(cspObject->Identifier, (char*)&cspObject->Description, sizeof(cspObject->Description)); memcpy(&cspObject->Status, &cspReport->Status, sizeof(cspObject->Status)); cspObject->Status[sizeof(cspObject->Status) - 1] = 0x00; memcpy(&cspObject->Location, &cspReport->Location, sizeof(cspObject->Location)); /* DisplayNode MUST be re-inserted, since the location may change and the location is part of the sorting key! */ /* for(int i=0;i < 6;i++) { cspObject->Location[i] = 'A' + (random() % 26); } */ cspObject->Location[sizeof(cspObject->Location) - 1] = 0x00; } if(cspObject->AssociationArray) { deleteComponentAssociationArray(cspObject->AssociationArray); } cspObject->AssociationArray = createComponentAssociationArray(cspReport->Associations); CHECK(cspObject->AssociationArray); memcpy(cspObject->AssociationArray, &cspReport->AssociationArray, cspReport->Associations * sizeof(struct ComponentAssociation)); cspObject->Associations = cspReport->Associations; CHECK(simpleRedBlackTreeInsert(objectStorage, &cspObject->StorageNode) == &cspObject->StorageNode); simpleRedBlackTreeVerify(objectStorage); CHECK(simpleRedBlackTreeInsert(objectDisplay, &cspObject->DisplayNode) == &cspObject->DisplayNode); simpleRedBlackTreeVerify(objectDisplay); } } } } }