SXE_RETURN sxe_ring_buffer_consumed(void * base, SXE_RING_BUFFER_CONTEXT * context, unsigned len) { SXE_RETURN result = SXE_RETURN_OK; SXEE81("sxe_ring_buffer_consumed(len:%u)", len); if ((result = sxe_ring_buffer_check_over_run(base, context)) == SXE_RETURN_ERROR_INTERNAL) { goto SXE_ERROR_OUT; } SXEL92("data_block was: %p, moving to %p", context->data_block, context->data_block + len); context->data_block += len; context->data_block_len -= len; SXEA10(context->data_block <= SXE_RING_BUFFER_WRITEN_END + 1, "the data block did not go off the end of the array"); if ((context->data_block == SXE_RING_BUFFER_WRITEN_END + 1) && (context->data_block != SXE_RING_BUFFER_CURRENT)) { SXEA10(context->data_block_len == 0, "If this consume brought us to the end of the array, the remaining length must be zero"); SXEL90("Wrapping data_block to the start of the ring"); context->data_block = SXE_RING_BUFFER_ARRAY_BASE; context->itteration++; } SXE_EARLY_OR_ERROR_OUT: SXEL93("context data_block: %p, data_block_len: %u itteration: %u", context->data_block, context->data_block_len, context->itteration); SXER81("return %s", sxe_return_to_string(result)); return result; }
SXE_RETURN sha1_from_hex(SOPHOS_SHA1 * sha1, const char * sha1_in_hex) { SXE_RETURN result; SXEE82("sxe_sha1_from_hex(sha1=%p,sha1_in_hex='%s'", sha1, sha1_in_hex); result = sxe_hex_to_bytes((unsigned char *)sha1, sha1_in_hex, SHA1_IN_HEX_LENGTH); SXER81("return %s", sxe_return_to_string(result)); return result; }
SXE_RETURN md5_from_hex(SOPHOS_MD5 * md5, const char * md5_in_hex) { SXE_RETURN result; SXEE82("(md5=%p,md5_in_hex='%s'", md5, md5_in_hex); result = sxe_hex_to_bytes((unsigned char *)md5, md5_in_hex, MD5_IN_HEX_LENGTH); SXER81("return %s", sxe_return_to_string(result)); return result; }
/* Given a DNS query or reply, extract the DNS question from the DNS packet. * * Note that the encoded question may be rot13 transformed - see the * sxe_dns_rot13_on_string() function to correct this. * * dns_packet - DNS packet containting encoded question * question - character buffer into which the decoded zero terminated question text will be written * question_length_maximum - length of 'question' * question_length - pointer (or NULL) which will be set to actual question length * * Returns * SXE_RETURN_OK on success */ SXE_RETURN sxe_dns_get_question(const unsigned char * dns_packet, char * question, unsigned question_length_maximum, unsigned * question_length) { SXE_RETURN result = SXE_RETURN_ERROR_INTERNAL; SXEE84("sxe_dns_get_question(dns_packet=%p, question=%p, question_length_maximum=%d, question_length=%p)", dns_packet, question, question_length_maximum, question_length); result = sxe_dns_decode_name(dns_packet, SXE_BUF_SIZE, SXE_DNS_QUESTION_OFFSET, question, question_length_maximum, question_length); SXER81("return // result = %s", sxe_return_to_string(result)); return result; }
static int sxe_sync_ev_socket(void) { int sock; SXEE80("sxe_sync_ev_socket()"); SXEA11((sock = socket(AF_INET, SOCK_DGRAM, 0)) != SXE_SOCKET_INVALID, "Error creating sync socket: %s", sxe_socket_get_last_error_as_str()); SXEA12(sxe_socket_set_nonblock(sock, 1) >= 0, "socket %d: couldn't set non-blocking flag: %s", sock, sxe_socket_get_last_error_as_str()); SXER81("return sock=%d", sock); return sock; }
void * sxe_sync_ev_new(void * user_data) { unsigned id; SXEE81("sxe_sync_ev_new(user_data=%p)", user_data); SXEA10((id = sxe_pool_set_oldest_element_state(sxe_sync_ev_pool, 0, 1)) != SXE_POOL_NO_INDEX, "Could not allocate a sync object"); sxe_sync_ev_pool[id].sock = sxe_sync_ev_socket(); sxe_sync_ev_pool[id].user_data = user_data; SXER81("return sync=%p", &sxe_sync_ev_pool[id]); return &sxe_sync_ev_pool[id]; }
void * sxe_ring_buffer_new(unsigned size) { void * base; SXEE81("sxe_ring_buffer_new(size=%u)", size); SXEA10((base = malloc(size + SXE_RING_BUFFER_SIZE_OF_INTERNALS)) != NULL, "Error allocating sxe-ring-buffer"); SXE_RING_BUFFER_SIZE = size; SXE_RING_BUFFER_ITERATION = 0; SXE_RING_BUFFER_CURRENT = SXE_RING_BUFFER_ARRAY_BASE; SXE_RING_BUFFER_WRITEN_END = SXE_RING_BUFFER_CURRENT; SXEL92("Array base=%p, End of Array=%p", SXE_RING_BUFFER_ARRAY_BASE, SXE_RING_BUFFER_END); SXER81("return base=%p", base); return base; }
SXE_RETURN md5_to_hex(SOPHOS_MD5 * md5, char * md5_in_hex, unsigned md5_in_hex_length) { SXE_RETURN result = SXE_RETURN_OK; SXEE86("(md5=%08x%08x%08x%08x,md5_in_hex='%p',md5_in_hex_length='%u'", md5->word[3], md5->word[2], md5->word[1], md5->word[0], md5_in_hex, md5_in_hex_length); SXEA11(md5_in_hex_length == (MD5_IN_HEX_LENGTH + 1), "Incorrect length of char * for md5_to_hex(): '%u'", md5_in_hex_length); snprintf(md5_in_hex , 9, "%08x", htonl(md5->word[0])); snprintf(md5_in_hex + 8, 9, "%08x", htonl(md5->word[1])); snprintf(md5_in_hex + 16, 9, "%08x", htonl(md5->word[2])); snprintf(md5_in_hex + 24, 9, "%08x", htonl(md5->word[3])); SXEL62("md5_in_hex: '%.*s'", MD5_IN_HEX_LENGTH, md5_in_hex); SXER81("return %s", sxe_return_to_string(result)); return result; }
SXE_RETURN sha1_to_hex(SOPHOS_SHA1 * sha1, char * sha1_in_hex, unsigned sha1_in_hex_length) { SXE_RETURN result = SXE_RETURN_OK; SXEE87("sxe_sha1_to_hex(sha1=%08x%08x%08x%08x%08x,sha1_in_hex='%p',sha1_in_hex_length='%u'", sha1->word[4], sha1->word[3], sha1->word[2], sha1->word[1], sha1->word[0], sha1_in_hex, sha1_in_hex_length); SXEA11(sha1_in_hex_length == (SHA1_IN_HEX_LENGTH + 1), "Incorrect length of char * for sha1_to_hex(): '%u'", sha1_in_hex_length); snprintf(sha1_in_hex , 9, "%08x", htonl(sha1->word[0])); snprintf(sha1_in_hex + 8, 9, "%08x", htonl(sha1->word[1])); snprintf(sha1_in_hex + 16, 9, "%08x", htonl(sha1->word[2])); snprintf(sha1_in_hex + 24, 9, "%08x", htonl(sha1->word[3])); snprintf(sha1_in_hex + 32, 9, "%08x", htonl(sha1->word[4])); SXEL62("sha1_in_hex: '%.*s'", 40, sha1_in_hex); SXER81("return %s", sxe_return_to_string(result)); return result; }
static SXE_RETURN sxe_ring_buffer_check_over_run(void * base, SXE_RING_BUFFER_CONTEXT * context) { SXE_RETURN result = SXE_RETURN_OK; SXEE80("sxe_ring_buffer_check_over_run()"); SXEL92("ring context data_block: %p, itteration: %u", SXE_RING_BUFFER_CURRENT, SXE_RING_BUFFER_ITERATION); SXEL92("user context data_block: %p, itteration: %u", context->data_block, context->itteration); if ( (SXE_RING_BUFFER_ITERATION > (context->itteration + 1)) || ((SXE_RING_BUFFER_ITERATION > context->itteration) && (SXE_RING_BUFFER_CURRENT > context->data_block))) { SXEL90("This reader has fallen behind the writer!"); result = SXE_RETURN_ERROR_INTERNAL; SXEL90("Moving data_block to the start of the ring"); context->data_block = SXE_RING_BUFFER_CURRENT; context->itteration = SXE_RING_BUFFER_ITERATION; context->data_block_len = 0; } SXER81("return %s", sxe_return_to_string(result)); return result; }
SXE_RETURN sxe_ring_buffer_next_block(void * base, SXE_RING_BUFFER_CONTEXT * context) { SXE_RETURN result = SXE_RETURN_OK; SXEE80("sxe_ring_buffer_next_block()"); if ((result = sxe_ring_buffer_check_over_run(base, context)) == SXE_RETURN_ERROR_INTERNAL) { goto SXE_ERROR_OUT; } if (SXE_RING_BUFFER_CURRENT > context->data_block) { SXEL90("Reading up to the head of the ring"); context->data_block_len = SXE_RING_BUFFER_CURRENT - context->data_block; } else if (SXE_RING_BUFFER_CURRENT <= context->data_block && SXE_RING_BUFFER_ITERATION == context->itteration + 1 && SXE_RING_BUFFER_WRITEN_END == context->data_block - 1) { SXEL90("The ring was forced wrapped while context was at the head"); SXEL90("Wrap the ring and read up to the head"); context->data_block = SXE_RING_BUFFER_ARRAY_BASE; context->itteration++; context->data_block_len = SXE_RING_BUFFER_CURRENT - context->data_block; } else if (SXE_RING_BUFFER_ITERATION > context->itteration) { SXEL90("Reading to the end of the ring"); context->data_block_len = SXE_RING_BUFFER_WRITEN_END - context->data_block + 1; } else { SXEL90("Nothing to read"); } SXE_EARLY_OR_ERROR_OUT: SXEL93("context data_block: %p, data_block_len: %u itteration: %u", context->data_block, context->data_block_len, context->itteration); SXER81("return %s", sxe_return_to_string(result)); return result; }
/* Note that the decoded_name will be NUL terminated, and therefore the * maximum_name_length_maximum should probably be 254 and not 253 (though, with * pointers, the decoded name could well be *longer* than 253 characters! */ static SXE_RETURN sxe_dns_decode_name( const unsigned char * dns_packet , unsigned dns_packet_length , unsigned name_offset , char * decoded_name , unsigned decoded_name_length_maximum, unsigned * decoded_name_length ) { SXE_RETURN result = SXE_RETURN_ERROR_INTERNAL; unsigned decoded_name_offset = 0; SXEE86("sxe_dns_decode_name(dns_packet=%p, dns_packet_length=%u, name_offset=%u, decoded_name=%p, decoded_name_length_maximum=%u, decoded_name_length=%p)", dns_packet, dns_packet_length, name_offset, decoded_name, decoded_name_length_maximum, decoded_name_length); SXEA10(decoded_name_length != 0, "A value for decoded_name_length must be provided"); SXEA10(decoded_name == NULL || decoded_name_length_maximum != 0, "NAME can not be decoded into an empty buffer"); while (name_offset < dns_packet_length) { unsigned char len = dns_packet[name_offset]; if (len == '\0') { SXEL60("NAME is terminated normally"); if (decoded_name_offset > 0) { --decoded_name_offset; } if (decoded_name != NULL) { decoded_name[decoded_name_offset] = '\0'; } *decoded_name_length = decoded_name_offset; result = SXE_RETURN_OK; goto SXE_EARLY_OUT; } else if ((len & SXE_DNS_LABEL_LENGTH_POINTER) == 0) { SXEL73("Normal label of length %u '%.*s'", len, len, &dns_packet[name_offset + 1]); /* Don't allow the NAME to exceed the known packet length */ if ((decoded_name != NULL) && (decoded_name_offset + len + 1 >= decoded_name_length_maximum)) { SXEL51("sxe_dns_decode_name(): NAME is invalid; Decoded NAME is longer than the provided buffer length %u", decoded_name_length_maximum); goto SXE_ERROR_OUT; } /* Copy the label */ if (decoded_name != NULL) { memcpy((unsigned char*)(decoded_name + decoded_name_offset), dns_packet + name_offset + 1, len); decoded_name[decoded_name_offset + len] = '.'; } decoded_name_offset += len + 1; } else if ((len & SXE_DNS_LABEL_LENGTH_POINTER) == SXE_DNS_LABEL_LENGTH_POINTER) { SXEL60("NAME includes a pointer"); name_offset = (len & ~SXE_DNS_LABEL_LENGTH_POINTER) + dns_packet[name_offset + 1]; SXEL61("New NAME offset is %u", name_offset); /* Prevent looping forever - a pointer should never point to a pointer */ if ((dns_packet[name_offset] & SXE_DNS_LABEL_LENGTH_POINTER) != 0) { SXEL51("sxe_dns_decode_name(): NAME contains a pointer which points to another pointer at packet offset %u", name_offset); goto SXE_ERROR_OUT; } continue; } else { SXEL51("sxe_dns_decode_name(): NAME is invalid; NAME contains an invalid length/pointer value at packet offset %u", name_offset); goto SXE_ERROR_OUT; } name_offset += len + 1; } SXEL60("NAME is invalid because it extends outside the packet"); SXE_ERROR_OUT: SXE_EARLY_OUT: SXER81("return // result=%s", sxe_return_to_string(result)); return result; }
/** * Step to the next object in a pool state * * @param walker Pointer to the pool state walker * * @return Index of the next object or SXE_POOL_NO_INDEX if the end of the state queue has been reached. * * @note Thread safety is implemented by verifying that the last node stepped to is still in the same state queue. If it is not, * the state queue is rewalked to find a node with a time or count greater than or equal to the time that the last stepped * to node had when it was stepped to. */ unsigned sxe_pool_walker_step(SXE_POOL_WALKER * walker) { SXE_POOL_NODE * node; SXE_POOL_IMPL * pool = walker->pool; unsigned result; SXEE81("sxe_pool_walker_step(walker=%p)", walker); if ((result = sxe_pool_lock(pool)) == SXE_POOL_LOCK_NOT_TAKEN) { goto SXE_ERROR_OUT; } /* If not at the head of the state queue and the current object has been moved to another state. */ if (((node = sxe_list_walker_find(&walker->list_walker)) != NULL) && (SXE_LIST_NODE_GET_ID(&node->list_node) != walker->state)) /* TODO: Check for touching */ { SXEL83("sxe_pool_walker_step: node %u moved from state %s to state %s by another thread", node - SXE_POOL_NODES(pool), (*pool->state_to_string)(walker->state), (*pool->state_to_string)(SXE_LIST_NODE_GET_ID(&node->list_node))); /* If there is a previous object and it has not been moved, get the new next one. */ if (((node = sxe_list_walker_back(&walker->list_walker)) != NULL) && (SXE_LIST_NODE_GET_ID(&node->list_node) == walker->state)) /* TODO: Check for touching */ { node = sxe_list_walker_step(&walker->list_walker); } else { sxe_list_walker_construct(&walker->list_walker, &SXE_POOL_QUEUE(pool)[walker->state]); while ((node = sxe_list_walker_step(&walker->list_walker)) != NULL) { if (pool->options & SXE_POOL_OPTION_TIMED) { if (node->last.time >= walker->last.time) { /* Coverage Exclusion: TODO refactor SXE_POOL_TIME */ break; /* Coverage Exclusion: TODO refactor SXE_POOL_TIME */ } } else { if (node->last.count >= walker->last.count) { break; } } } } } else { node = sxe_list_walker_step(&walker->list_walker); } result = SXE_POOL_NO_INDEX; if (node != NULL) { result = node - SXE_POOL_NODES(pool); if (pool->options & SXE_POOL_OPTION_TIMED) { walker->last.time = node->last.time; } else { walker->last.count = node->last.count; } } sxe_pool_unlock(pool); SXE_ERROR_OUT: SXER81("return %s", sxe_pool_return_to_string(result)); return result; }