/* Accumulate worker messages with statistics */ static void add_stat_message(chunk_ptr msg) { size_t *stat_summary = NULL; stat_messages[stat_message_cnt++] = msg; /* See if we've accumulated a full set */ if (stat_message_cnt >= worker_cnt) { size_t nstat = stat_messages[0]->length - 1; if (flush_requestor_fd >= 0) stat_summary = calloc_or_fail(nstat * 3, sizeof(size_t), "add_stat_message"); /* Accumulate and print */ #if RPT >= 1 report(1, "Worker statistics:"); #endif size_t i, w; for (i = 0; i < nstat; i++) { chunk_ptr msg = stat_messages[0]; word_t minval, maxval, sumval; minval = maxval = sumval = chunk_get_word(msg, i+1); for (w = 1; w < worker_cnt; w++) { chunk_ptr msg = stat_messages[w]; word_t val = chunk_get_word(msg, i+1); if (val < minval) minval = val; if (val > maxval) maxval = val; sumval += val; } if (stat_summary) { stat_summary[3*i + 0] = minval; stat_summary[3*i + 1] = maxval; stat_summary[3*i + 2] = sumval; } #if RPT >= 1 report(1, "Parameter %d\tMin: %" PRIu64 "\tMax: %" PRIu64 "\tAvg: %.2f\tSum: %" PRIu64, (int) i, minval, maxval, (double) sumval/worker_cnt, sumval); #endif } if (flush_requestor_fd >= 0) { chunk_ptr msg = msg_new_stat(worker_cnt, nstat*3, stat_summary); if (chunk_write(flush_requestor_fd, msg)) { #if RPT >= 5 report(5, "Sent statistical summary to client at fd %d", flush_requestor_fd); #endif } else { err(false, "Failed to send statistical summary to client at fd %d", flush_requestor_fd); } chunk_free(msg); free_array(stat_summary, nstat*3, sizeof(size_t)); } for (w = 0; w < worker_cnt; w++) { chunk_free(stat_messages[w]); stat_messages[w] = NULL; } stat_message_cnt = 0; flush_requestor_fd = -1; } }
bool quit_agent(int argc, char *argv[]) { op_ptr op = op_list; word_t w; while (op) { op_ptr ele = op; op = ele->next; free_block(ele, sizeof(op_ele)); } if (router_fd_array) free_array(router_fd_array, nrouters, sizeof(int)); /* Free any pending operations */ chunk_ptr msg; keyvalue_iterstart(operator_table); while (keyvalue_removenext(operator_table, NULL, (word_t *) &msg)) { chunk_free(msg); } keyvalue_free(operator_table); keyvalue_iterstart(deferred_operand_table); while (keyvalue_removenext(deferred_operand_table, NULL, &w)) { operand_ptr ls = (operand_ptr) w; while (ls) { chunk_free(ls->operand); operand_ptr ele = ls; ls = ls->next; free_block(ele, sizeof(operand_ele)); } } keyvalue_free(deferred_operand_table); chunk_deinit(); return true; }
/* * Described in header */ bool botan_get_encoding(botan_pubkey_t pubkey, cred_encoding_type_t type, chunk_t *encoding) { bool success = TRUE; encoding->len = 0; if (botan_pubkey_export(pubkey, NULL, &encoding->len, BOTAN_PRIVKEY_EXPORT_FLAG_DER) != BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE) { return FALSE; } *encoding = chunk_alloc(encoding->len); if (botan_pubkey_export(pubkey, encoding->ptr, &encoding->len, BOTAN_PRIVKEY_EXPORT_FLAG_DER)) { chunk_free(encoding); return FALSE; } if (type != PUBKEY_SPKI_ASN1_DER) { chunk_t asn1_encoding = *encoding; success = lib->encoding->encode(lib->encoding, type, NULL, encoding, CRED_PART_ECDSA_PUB_ASN1_DER, asn1_encoding, CRED_PART_END); chunk_free(&asn1_encoding); } return success; }
/* Add new agent. Send agent ID + number of workers + router map */ static void add_agent(int fd, bool isclient) { unsigned agent = next_agent++; if (agent >= worker_cnt + maxclients) { /* Exceeded client limit */ chunk_ptr msg = msg_new_nack(); if (chunk_write(fd, msg)) { #if RPT >= 1 report(1, "Sent nack to potential client due to client limit being exceeded. Fd = %d", fd); #endif } else { #if RPT >= 3 report(3, "Couldn't send nack to potential client. Fd = %d", fd); #endif } chunk_free(msg); return; } /* Need to break into sequence of messages according to max. chunk length */ chunk_ptr msg = NULL; size_t bcount = 0; size_t ncount = router_addr_set->nelements; set_iterstart(router_addr_set); word_t id; bool ok = true; while (ok && set_iternext(router_addr_set, &id)) { if (bcount == 0) { /* Start new block */ size_t blen = ncount; if (blen > MAX_IDS) blen = MAX_IDS; msg = chunk_new(blen+1); } word_t wd = id << 16; chunk_insert_word(msg, wd, bcount+1); bcount++; if (bcount == MAX_IDS) { /* This block is filled */ size_t h1 = ((word_t) agent << 48) | ((word_t) ncount << 32) | ((word_t) worker_cnt << 16) | MSG_ACK_AGENT; chunk_insert_word(msg, h1, 0); ok = chunk_write(fd, msg); chunk_free(msg); ncount -= bcount; bcount = 0; } } if (ok && ncount > 0) { size_t h1 = ((word_t) agent << 48) | ((word_t) ncount << 32) | ((word_t) worker_cnt << 16) | MSG_ACK_AGENT; chunk_insert_word(msg, h1, 0); ok = chunk_write(fd, msg); chunk_free(msg); ncount -= bcount; } #if RPT >= 3 report(3, "Added agent %u with descriptor %d", agent, fd); #endif }
/* For workers only */ static void receive_operand(chunk_ptr oper) { word_t w; dword_t dh = chunk_get_dword(oper, 0); word_t id = msg_get_dheader_op_id(dh); unsigned offset = msg_get_dheader_offset(dh); if (keyvalue_find(operator_table, id, &w)) { /* Operation exists */ chunk_ptr op = (chunk_ptr) w; op_insert_operand(op, oper, offset); #if RPT >= 5 report(5, "Inserted operand with offset %u into existing operator with id 0x%lx", offset, id); #endif chunk_free(oper); if (check_fire(op)) { #if RPT >= 5 report(5, "Completed firing of dequeued operation with id 0x%lx", id); #endif keyvalue_remove(operator_table, id, NULL, NULL); chunk_free(op); } } else { add_deferred_operand(id, oper, offset); #if RPT >= 5 report(5, "Deferred operand with offset %u for id 0x%lx", offset, id); #endif } }
bool quit_controller(int argc, char *argv[]) { /* Send kill messages to other nodes and close file connections */ chunk_ptr msg = msg_new_kill(); word_t w; int fd; keyvalue_iterstart(new_conn_map); while (keyvalue_iternext(new_conn_map, &w, NULL)) { fd = w; close(fd); } set_iterstart(router_fd_set); while (set_iternext(router_fd_set, &w)) { fd = w; if (!chunk_write(fd, msg)) err(false, "Failed to send kill message to router with descriptor %d", fd); close(fd); } set_iterstart(worker_fd_set); while (set_iternext(worker_fd_set, &w)) { fd = w; if (!chunk_write(fd, msg)) err(false, "Failed to send kill message to worker with descriptor %d", fd); close(fd); } set_iterstart(client_fd_set); while (set_iternext(client_fd_set, &w)) { fd = w; if (!chunk_write(fd, msg)) err(false, "Failed to send kill message to client with descriptor %d", fd); close(fd); } /* Deallocate */ chunk_free(msg); set_free(router_addr_set); keyvalue_free(new_conn_map); set_free(router_fd_set); set_free(worker_fd_set); set_free(client_fd_set); while (stat_message_cnt > 0) { chunk_free(stat_messages[--stat_message_cnt]); } free_array(stat_messages, sizeof(chunk_ptr), worker_cnt); free_global_ops(); if (need_client_fd_set != NULL) set_free(need_client_fd_set); need_client_fd_set = NULL; if (defer_client_fd_set != NULL) set_free(defer_client_fd_set); defer_client_fd_set = NULL; chunk_deinit(); return true; }
/* * Described in header */ bool botan_get_fingerprint(botan_pubkey_t pubkey, void *cache, cred_encoding_type_t type, chunk_t *fp) { hasher_t *hasher; chunk_t key; if (cache && lib->encoding->get_cache(lib->encoding, type, cache, fp)) { return TRUE; } switch (type) { case KEYID_PUBKEY_SHA1: /* subjectPublicKey -> use botan_pubkey_fingerprint() */ *fp = chunk_alloc(HASH_SIZE_SHA1); if (botan_pubkey_fingerprint(pubkey, "SHA-1", fp->ptr, &fp->len)) { chunk_free(fp); return FALSE; } break; case KEYID_PUBKEY_INFO_SHA1: /* subjectPublicKeyInfo -> use botan_pubkey_export(), then hash */ if (!botan_get_encoding(pubkey, PUBKEY_SPKI_ASN1_DER, &key)) { return FALSE; } hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); if (!hasher || !hasher->allocate_hash(hasher, key, fp)) { DBG1(DBG_LIB, "SHA1 hash algorithm not supported, " "fingerprinting failed"); DESTROY_IF(hasher); chunk_free(&key); return FALSE; } hasher->destroy(hasher); chunk_free(&key); break; default: return FALSE; } if (cache) { lib->encoding->cache(lib->encoding, type, cache, *fp); } return TRUE; }
bool do_controller_collect_cmd(int argc, char *argv[]) { word_t w; bool ok = true; if (gc_state != GC_READY) { err(false, "Cannot initiate garbage collection while one is still underway"); return false; } gc_generation++; chunk_ptr msg = msg_new_gc_start(); set_iterstart(worker_fd_set); while (set_iternext(worker_fd_set, &w)) { int fd = (int) w; if (!chunk_write(fd, msg)) { err(false, "Failed to send gc start message to worker with descriptor %d", fd); ok = false; } } chunk_free(msg); #if RPT >= 3 report(3, "GC waiting for workers to start"); #endif gc_state = GC_WAIT_WORKER_START; need_worker_cnt = worker_fd_set->nelements; return ok; }
bool do_controller_flush_cmd(int argc, char *argv[]) { chunk_ptr msg = msg_new_flush(); word_t w; int fd; bool ok = true; set_iterstart(worker_fd_set); while (set_iternext(worker_fd_set, &w)) { fd = w; if (!chunk_write(fd, msg)) { err(false, "Failed to send flush message to worker with descriptor %d", fd); ok = false; } } set_iterstart(client_fd_set); while (set_iternext(client_fd_set, &w)) { fd = w; if (!chunk_write(fd, msg)) { err(false, "Failed to send flush message to client with descriptor %d", fd); ok = false; } } chunk_free(msg); free_global_ops(); gc_state = GC_READY; need_worker_cnt = 0; if (need_client_fd_set != NULL) set_free(need_client_fd_set); need_client_fd_set = NULL; if (defer_client_fd_set != NULL) set_free(defer_client_fd_set); defer_client_fd_set = NULL; return ok; }
END_TEST START_TEST(test_newhope_ke_fail_i) { diffie_hellman_t *i_nh; char buf_ff[2048]; int i; chunk_t i_msg; chunk_t r_msg[] = { chunk_empty, chunk_from_chars(0x00), chunk_create(buf_ff, 2047), chunk_create(buf_ff, 2048), }; memset(buf_ff, 0xff, sizeof(buf_ff)); for (i = 0; i < countof(r_msg); i++) { i_nh = lib->crypto->create_dh(lib->crypto, NH_128_BIT); ck_assert(i_nh != NULL); ck_assert(i_nh->get_my_public_value(i_nh, &i_msg)); ck_assert(!i_nh->set_other_public_value(i_nh, r_msg[i])); chunk_free(&i_msg); i_nh->destroy(i_nh); } }
/* skip up to length bytes in a chunkqueue, return number of bytes skipped */ goffset li_chunkqueue_skip(liChunkQueue *cq, goffset length) { liChunk *c; goffset bytes = 0; goffset we_have; while ( (NULL != (c = li_chunkqueue_first_chunk(cq))) && (0 == (we_have = li_chunk_length(c)) || length > 0) ) { if (we_have <= length) { /* skip (delete) complete chunk */ if (c->type == STRING_CHUNK) cqlimit_update(cq, - (goffset)c->data.str->len); else if (c->type == MEM_CHUNK) cqlimit_update(cq, - (goffset)c->mem->len); else if (c->type == BUFFER_CHUNK) cqlimit_update(cq, - (goffset)c->data.buffer.length); chunk_free(cq, c); bytes += we_have; length -= we_have; } else { /* skip first part of a chunk */ c->offset += length; bytes += length; length = 0; } } cq->bytes_out += bytes; cq->length -= bytes; return bytes; }
static int remove_oldest_chunk(struct chunk_buffer *cb, int id, uint64_t ts) { int i, min, pos_min; if (cb->buffer[0].id == id) { return E_CB_DUPLICATE; } min = cb->buffer[0].id; pos_min = 0; for (i = 1; i < cb->num_chunks; i++) { if (cb->buffer[i].id == id) { return E_CB_DUPLICATE; } if (cb->buffer[i].id < min) { min = cb->buffer[i].id; pos_min = i; } } if (min < id) { chunk_free(&cb->buffer[pos_min]); cb->num_chunks--; return pos_min; } // check for ID looparound and other anomalies if (cb->buffer[pos_min].timestamp < ts) { cb_clear(cb); return 0; } return E_CB_OLD; }
/** * Try to decrypt the given blob with multiple passwords using the given * pkcs5 object. */ static private_key_t *decrypt_private_key(pkcs5_t *pkcs5, chunk_t blob) { enumerator_t *enumerator; shared_key_t *shared; private_key_t *private_key = NULL; enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr, SHARED_PRIVATE_KEY_PASS, NULL, NULL); while (enumerator->enumerate(enumerator, &shared, NULL, NULL)) { chunk_t decrypted; if (!pkcs5->decrypt(pkcs5, shared->get_key(shared), blob, &decrypted)) { continue; } private_key = parse_private_key(decrypted); if (private_key) { chunk_clear(&decrypted); break; } chunk_free(&decrypted); } enumerator->destroy(enumerator); return private_key; }
END_TEST START_TEST(test_extract_buf) { bio_writer_t *writer; chunk_t data1, data2; writer = bio_writer_create(0); writer->write_uint8(writer, 1); data1 = writer->extract_buf(writer); ck_assert_int_eq(data1.len, 1); ck_assert(data1.ptr[0] == 1); data2 = writer->get_buf(writer); ck_assert_int_eq(data2.len, 0); ck_assert(data2.ptr == NULL); data2 = writer->extract_buf(writer); ck_assert_int_eq(data2.len, 0); ck_assert(data2.ptr == NULL); writer->write_uint8(writer, 1); data2 = writer->get_buf(writer); ck_assert(chunk_equals(data1, data2)); ck_assert(data1.ptr != data2.ptr); writer->destroy(writer); chunk_free(&data1); }
static void *huge_chunk_alloc(struct thread_cache *cache, size_t size, size_t alignment, struct arena **out_arena) { struct arena *arena = get_arena(cache); void *chunk = chunk_recycle(&arena->chunks, NULL, size, alignment); if (chunk) { if (unlikely(memory_commit(chunk, size))) { chunk_free(&arena->chunks, chunk, size); return NULL; } } else { if (unlikely(!(chunk = chunk_alloc(NULL, size, alignment)))) { return NULL; } // Work around the possibility of holes created by huge_move_expand (see below). struct arena *chunk_arena = get_huge_arena(chunk); if (chunk_arena != arena) { mutex_unlock(&arena->mutex); if (chunk_arena) { mutex_lock(&chunk_arena->mutex); } arena = chunk_arena; } } *out_arena = arena; return chunk; }
int gridfs_store_buffer( gridfs *gfs, const char *data, gridfs_offset length, const char *remotename, const char *contenttype ) { char const *end = data + length; const char *data_ptr = data; bson_oid_t id; int chunkNumber = 0; int chunkLen; bson *oChunk; /* Large files Assertion */ assert( length <= 0xffffffff ); /* Generate and append an oid*/ bson_oid_gen( &id ); /* Insert the file's data chunk by chunk */ while ( data_ptr < end ) { chunkLen = DEFAULT_CHUNK_SIZE < ( unsigned int )( end - data_ptr ) ? DEFAULT_CHUNK_SIZE : ( unsigned int )( end - data_ptr ); oChunk = chunk_new( id, chunkNumber, data_ptr, chunkLen ); mongo_insert( gfs->client, gfs->chunks_ns, oChunk ); chunk_free( oChunk ); chunkNumber++; data_ptr += chunkLen; } /* Inserts file's metadata */ return gridfs_insert_file( gfs, remotename, id, length, contenttype ); }
/* * Described in header */ bool botan_get_privkey_encoding(botan_privkey_t key, cred_encoding_type_t type, chunk_t *encoding) { uint32_t format = BOTAN_PRIVKEY_EXPORT_FLAG_DER; switch (type) { case PRIVKEY_PEM: format = BOTAN_PRIVKEY_EXPORT_FLAG_PEM; /* fall-through */ case PRIVKEY_ASN1_DER: encoding->len = 0; if (botan_privkey_export(key, NULL, &encoding->len, format) != BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE) { return FALSE; } *encoding = chunk_alloc(encoding->len); if (botan_privkey_export(key, encoding->ptr, &encoding->len, format)) { chunk_free(encoding); return FALSE; } return TRUE; default: return FALSE; } }
/** * Add ITA Settings attribute to the send queue */ static void add_settings(enumerator_t *enumerator, imc_msg_t *msg) { pa_tnc_attr_t *attr = NULL; ita_attr_settings_t *attr_cast; chunk_t value; char *name; bool first = TRUE; while (enumerator->enumerate(enumerator, &name)) { DBG1(DBG_IMC, "setting '%s'", name); value = os->get_setting(os, name); if (!value.ptr) { continue; } if (first) { attr = ita_attr_settings_create(); first = FALSE; } attr_cast = (ita_attr_settings_t*)attr; attr_cast->add(attr_cast, name, value); chunk_free(&value); } if (attr) { msg->add_attribute(msg, attr); } }
/* load a coded key or certificate file with autodetection * of binary DER or base64 PEM ASN.1 formats and armored PGP format */ bool pem_asn1_load_file(const char *filename, chunk_t *passphrase, const char *type, chunk_t *blob, bool *pgp) { err_t ugh = NULL; FILE *fd = fopen(filename, "r"); pem_init_logger(); if (fd) { int bytes; fseek(fd, 0, SEEK_END ); blob->len = ftell(fd); rewind(fd); blob->ptr = malloc(blob->len); bytes = fread(blob->ptr, 1, blob->len, fd); fclose(fd); logger->log(logger, CONTROL, " loading %s file '%s' (%d bytes)", type, filename, bytes); *pgp = FALSE; /* try DER format */ if (is_asn1(*blob)) { logger->log(logger, CONTROL|LEVEL1, " file coded in DER format"); return TRUE; } if (passphrase != NULL) logger->log_bytes(logger, PRIVATE, " passphrase:", passphrase->ptr, passphrase->len); /* try PEM format */ ugh = pem_to_bin(blob, passphrase, pgp); if (ugh == NULL) { if (*pgp) { logger->log(logger, CONTROL|LEVEL1, " file coded in armored PGP format"); return TRUE; } if (is_asn1(*blob)) { logger->log(logger, CONTROL|LEVEL1, " file coded in PEM format"); return TRUE; } ugh = "file coded in unknown format, discarded"; } /* a conversion error has occured */ logger->log(logger, ERROR, " %s", ugh); chunk_free(blob); } else { logger->log(logger, ERROR, " could not open %s file '%s'", type, filename); } return FALSE; }
static void fetch_ocsp_status(ocsp_location_t* location) { chunk_t request = build_ocsp_request(location); chunk_t response = chunk_empty; DBG1(DBG_LIB, " requesting ocsp status from '%s' ...", location->uri); if (lib->fetcher->fetch(lib->fetcher, location->uri, &response, FETCH_REQUEST_DATA, request, FETCH_REQUEST_TYPE, "application/ocsp-request", FETCH_END) == SUCCESS) { parse_ocsp(location, response); } else { DBG1(DBG_LIB, "ocsp request to %s failed", location->uri); } free(request.ptr); chunk_free(&location->nonce); /* increment the trial counter of the unresolved fetch requests */ { ocsp_certinfo_t *certinfo = location->certinfo; while (certinfo != NULL) { certinfo->trials++; certinfo = certinfo->next; } } }
/* Send single-valued operand */ bool send_as_operand(dword_t dest, word_t val) { chunk_ptr oper = msg_new_operand(dest, 1 + OPER_HEADER_CNT); chunk_insert_word(oper, val, 0 + OPER_HEADER_CNT); bool ok = send_op(oper); chunk_free(oper); return ok; }
static void run_test(diffie_hellman_group_t group, int rounds) { diffie_hellman_t *l[rounds], *r; chunk_t chunk; struct timespec timing; int round; r = lib->crypto->create_dh(lib->crypto, group); if (!r) { printf("skipping %N, not supported\n", diffie_hellman_group_names, group); return; } printf("%N:\t", diffie_hellman_group_names, group); start_timing(&timing); for (round = 0; round < rounds; round++) { l[round] = lib->crypto->create_dh(lib->crypto, group); } printf("A = g^a/s: %8.1f", rounds / end_timing(&timing)); for (round = 0; round < rounds; round++) { l[round]->get_my_public_value(l[round], &chunk); r->set_other_public_value(r, chunk); chunk_free(&chunk); } r->get_my_public_value(r, &chunk); start_timing(&timing); for (round = 0; round < rounds; round++) { l[round]->set_other_public_value(l[round], chunk); } printf(" | S = B^a/s: %8.1f\n", rounds / end_timing(&timing)); chunk_free(&chunk); for (round = 0; round < rounds; round++) { l[round]->destroy(l[round]); } r->destroy(r); }
static void __chunk_free(gpointer _c, gpointer userdata) { liChunk *c = (liChunk *)_c; liChunkQueue *cq = (liChunkQueue*) userdata; if (c->type == STRING_CHUNK) cqlimit_update(cq, - (goffset)c->data.str->len); else if (c->type == MEM_CHUNK) cqlimit_update(cq, - (goffset)c->mem->len); else if (c->type == BUFFER_CHUNK) cqlimit_update(cq, - (goffset)c->data.buffer.length); chunk_free(cq, c); }
/* * decrypts a DES-EDE-CBC encrypted data block */ static err_t pem_decrypt(chunk_t *blob, encryption_algorithm_t alg, size_t key_size, chunk_t *iv, chunk_t *passphrase) { hasher_t *hasher; crypter_t *crypter; chunk_t salt = { iv->ptr, PKCS5_SALT_LEN }; chunk_t hash; chunk_t decrypted; chunk_t key = {alloca(key_size), key_size}; u_int8_t padding, *last_padding_pos, *first_padding_pos; if (passphrase == NULL || passphrase->len == 0) return "missing passphrase"; /* build key from passphrase and IV */ hasher = hasher_create(HASH_MD5); hash.len = hasher->get_hash_size(hasher); hash.ptr = alloca(hash.len); hasher->get_hash(hasher, *passphrase, NULL); hasher->get_hash(hasher, salt, hash.ptr); memcpy(key.ptr, hash.ptr, hash.len); if (key.len > hash.len) { hasher->get_hash(hasher, hash, NULL); hasher->get_hash(hasher, *passphrase, NULL); hasher->get_hash(hasher, salt, hash.ptr); memcpy(key.ptr + hash.len, hash.ptr, key.len - hash.len); } hasher->destroy(hasher); /* decrypt blob */ crypter = crypter_create(alg, key_size); crypter->set_key(crypter, key); if (crypter->decrypt(crypter, *blob, *iv, &decrypted) != SUCCESS) { return "data size is not multiple of block size"; } memcpy(blob->ptr, decrypted.ptr, blob->len); chunk_free(&decrypted); /* determine amount of padding */ last_padding_pos = blob->ptr + blob->len - 1; padding = *last_padding_pos; first_padding_pos = (padding > blob->len) ? blob->ptr : last_padding_pos - padding; /* check the padding pattern */ while (--last_padding_pos > first_padding_pos) { if (*last_padding_pos != padding) return "invalid passphrase"; } /* remove padding */ blob->len -= padding; return NULL; }
void chunkqueue_free(chunkqueue *cq) { chunk *c, *pc; if (NULL == cq) return; for (c = cq->first; c; ) { pc = c; c = c->next; chunk_free(pc); } for (c = cq->unused; c; ) { pc = c; c = c->next; chunk_free(pc); } free(cq); }
END_TEST /******************************************************************************* * integer */ START_TEST(test_asn1_integer) { typedef struct { chunk_t b; chunk_t c; } testdata_t; chunk_t b0 = chunk_from_chars(0x02, 0x01, 0x00); chunk_t b1 = chunk_from_chars(0x02, 0x01, 0x7f); chunk_t b2 = chunk_from_chars(0x02, 0x02, 0x00, 0x80); chunk_t c0 = chunk_empty; chunk_t c1 = chunk_from_chars(0x7f); chunk_t c2 = chunk_from_chars(0x80); chunk_t c3 = chunk_from_chars(0x00, 0x80); testdata_t test[] = { { b0, c0 }, { b1, c1 }, { b2, c2 }, { b2, c3 } }; chunk_t a = chunk_empty; int i; for (i = 0; i < countof(test); i++) { a = asn1_integer("c", test[i].c); ck_assert(chunk_equals(a, test[i].b)); chunk_free(&a); a = asn1_integer("m", chunk_clone(test[i].c)); ck_assert(chunk_equals(a, test[i].b)); chunk_free(&a); } }
/* Accept operation and either fire it or defer it */ static void receive_operation(chunk_ptr op) { word_t w; dword_t dh = chunk_get_dword(op, 0); word_t id = msg_get_dheader_op_id(dh); #if RPT >= 5 report(5, "Received operation. id 0x%lx", id); #endif /* Check if there's already an outstanding operation with the same ID */ if (keyvalue_find(operator_table, id, NULL)) { err(false, "Operator ID collision encountered. Op id = 0x%lx", id); chunk_free(op); return; } /* See if there are any pending operands for this operation */ if (keyvalue_remove(deferred_operand_table, id, NULL, &w)) { operand_ptr ls = (operand_ptr) w; while (ls) { operand_ptr ele = ls; op_insert_operand(op, ls->operand, ls->offset); #if RPT >= 5 report(5, "Inserted operand with offset %u into received operator with id 0x%lx", ls->offset, id); #endif chunk_free(ls->operand); ls = ls->next; free_block(ele, sizeof(operand_ele)); } } if (check_fire(op)) { #if RPT >= 5 report(5, "Completed firing of newly received operation with id 0x%lx", id); #endif chunk_free(op); } else { keyvalue_insert(operator_table, (word_t) id, (word_t) op); #if RPT >= 5 report(5, "Queued operation with id 0x%lx", id); #endif } }
void container_clean (container_t *container){ // {{{ container_chunk_t *chunk; container_chunk_t *chunk_next; for(chunk = container->head; chunk; chunk = chunk_next){ chunk_next = chunk->cnext; chunk_free(chunk); } container->head = NULL; container->tail = NULL; } // }}}
/** Free <b>area</b>, invalidating all pointers returned from memarea_alloc() * and friends for this area */ void memarea_drop_all(memarea_t *area) { memarea_chunk_t *chunk, *next; for (chunk = area->first; chunk; chunk = next) { next = chunk->next_chunk; chunk_free(chunk); } area->first = NULL; /*fail fast on */ tor_free(area); }
void chunkpool_free(void) { if (!chunkpool) return; /* free the pool */ while(chunkpool) { chunk *c = chunkpool->next; chunk_free(chunkpool); chunkpool = c; } chunkpool_chunks = 0; }