/* ============================================================================= * TMhashtable_getSize * -- Returns number of elements in hash table * ============================================================================= */ long TMhashtable_getSize (TM_ARGDECL hashtable_t* hashtablePtr) { #ifdef HASHTABLE_SIZE_FIELD return (long)TM_SHARED_READ(hashtablePtr->size); #else long i; long size = 0; for (i = 0; i < hashtablePtr->numBucket; i++) { size += TMLIST_GETSIZE(hashtablePtr->buckets[i]); } return size; #endif }
/* ============================================================================= * TMdecoder_process * ============================================================================= */ int_error_t TMdecoder_process (TM_ARGDECL decoder_t* decoderPtr, char* bytes, long numByte) { bool_t status; /* * Basic error checking */ if (numByte < (long)PACKET_HEADER_LENGTH) { return ERROR_SHORT; } packet_t* packetPtr = (packet_t*)bytes; long flowId = packetPtr->flowId; long fragmentId = packetPtr->fragmentId; long numFragment = packetPtr->numFragment; long length = packetPtr->length; if (flowId < 0) { return ERROR_FLOWID; } if ((fragmentId < 0) || (fragmentId >= numFragment)) { return ERROR_FRAGMENTID; } if (length < 0) { return ERROR_LENGTH; } #if 0 /* * With the above checks, this one is redundant */ if (numFragment < 1) { return ERROR_NUMFRAGMENT; } #endif /* * Add to fragmented map for reassembling */ if (numFragment > 1) { MAP_T* fragmentedMapPtr = decoderPtr->fragmentedMapPtr; list_t* fragmentListPtr = (list_t*)TMMAP_FIND(fragmentedMapPtr, (void*)flowId); if (fragmentListPtr == NULL) { fragmentListPtr = TMLIST_ALLOC(&decoder_comparator); assert(fragmentListPtr); status = TMLIST_INSERT(fragmentListPtr, (void*)packetPtr); assert(status); status = TMMAP_INSERT(fragmentedMapPtr, (void*)flowId, (void*)fragmentListPtr); assert(status); } else { list_iter_t it; TMLIST_ITER_RESET(&it, fragmentListPtr); assert(TMLIST_ITER_HASNEXT(&it, fragmentListPtr)); packet_t* firstFragmentPtr = (packet_t*)TMLIST_ITER_NEXT(&it, fragmentListPtr); long expectedNumFragment = firstFragmentPtr->numFragment; if (numFragment != expectedNumFragment) { status = TMMAP_REMOVE(fragmentedMapPtr, (void*)flowId); assert(status); return ERROR_NUMFRAGMENT; } status = TMLIST_INSERT(fragmentListPtr, (void*)packetPtr); assert(status); /* * If we have all the fragments we can reassemble them */ if (TMLIST_GETSIZE(fragmentListPtr) == numFragment) { long numByte = 0; long i = 0; TMLIST_ITER_RESET(&it, fragmentListPtr); while (TMLIST_ITER_HASNEXT(&it, fragmentListPtr)) { packet_t* fragmentPtr = (packet_t*)TMLIST_ITER_NEXT(&it, fragmentListPtr); if(fragmentPtr->flowId != flowId) printf("fragflow %lx floId %lx\n", fragmentPtr->flowId, flowId); assert(fragmentPtr->flowId == flowId); if (fragmentPtr->fragmentId != i) { status = TMMAP_REMOVE(fragmentedMapPtr, (void*)flowId); assert(status); return ERROR_INCOMPLETE; /* should be sequential */ } numByte += fragmentPtr->length; i++; } char* data = (char*)TM_MALLOC(numByte + 1); assert(data); data[numByte] = '\0'; char* dst = data; TMLIST_ITER_RESET(&it, fragmentListPtr); while (TMLIST_ITER_HASNEXT(&it, fragmentListPtr)) { packet_t* fragmentPtr = (packet_t*)TMLIST_ITER_NEXT(&it, fragmentListPtr); memcpy(dst, (void*)fragmentPtr->data, fragmentPtr->length); dst += fragmentPtr->length; } assert(dst == data + numByte); decoded_t* decodedPtr = (decoded_t*)TM_MALLOC(sizeof(decoded_t)); assert(decodedPtr); decodedPtr->flowId = flowId; decodedPtr->data = data; queue_t* decodedQueuePtr = decoderPtr->decodedQueuePtr; status = TMQUEUE_PUSH(decodedQueuePtr, (void*)decodedPtr); assert(status); TMLIST_FREE(fragmentListPtr); status = TMMAP_REMOVE(fragmentedMapPtr, (void*)flowId); assert(status); } } } else { /* * This is the only fragment, so it is ready */ if (fragmentId != 0) { return ERROR_FRAGMENTID; } char* data = (char*)TM_MALLOC(length + 1); assert(data); data[length] = '\0'; memcpy(data, (void*)packetPtr->data, length); decoded_t* decodedPtr = (decoded_t*)TM_MALLOC(sizeof(decoded_t)); assert(decodedPtr); decodedPtr->flowId = flowId; decodedPtr->data = data; queue_t* decodedQueuePtr = decoderPtr->decodedQueuePtr; status = TMQUEUE_PUSH(decodedQueuePtr, (void*)decodedPtr); assert(status); } return ERROR_NONE; }