static as_status as_admin_read_blocks(as_error* err, int fd, uint64_t deadline_ms, as_admin_parse_fn parse_fn, as_vector* list) { as_status status = AEROSPIKE_OK; uint8_t* buf = 0; size_t capacity = 0; while (true) { // Read header as_proto proto; status = as_socket_read_deadline(err, fd, (uint8_t*)&proto, sizeof(as_proto), deadline_ms); if (status) { break; } as_proto_swap_from_be(&proto); size_t size = proto.sz; if (size > 0) { // Prepare buffer if (size > capacity) { as_command_free(buf, capacity); capacity = size; buf = as_command_init(capacity); } // Read remaining message bytes in group status = as_socket_read_deadline(err, fd, buf, size, deadline_ms); if (status) { break; } status = parse_fn(err, buf, size, list); if (status != AEROSPIKE_OK) { if (status == AEROSPIKE_QUERY_END) { status = AEROSPIKE_OK; } else { as_error_set_message(err, status, as_error_string(status)); } break; } } } as_command_free(buf, capacity); return status; }
as_status as_authenticate(as_error* err, int fd, const char* user, const char* credential, uint64_t deadline_ms) { uint8_t buffer[AS_STACK_BUF_SIZE]; uint8_t* p = buffer + 8; p = as_admin_write_header(p, AUTHENTICATE, 2); p = as_admin_write_field_string(p, USER, user); p = as_admin_write_field_string(p, CREDENTIAL, credential); as_status status = as_admin_send(err, fd, buffer, p, deadline_ms); if (status) { return status; } status = as_socket_read_deadline(err, fd, buffer, HEADER_SIZE, deadline_ms); if (status) { return status; } status = buffer[RESULT_CODE]; if (status) { as_error_set_message(err, status, as_error_string(status)); } return status; }
static as_status as_scan_parse(as_error* err, int fd, uint64_t deadline_ms, void* udata) { as_scan_task* task = udata; as_status status = AEROSPIKE_OK; uint8_t* buf = 0; size_t capacity = 0; while (true) { // Read header as_proto proto; status = as_socket_read_deadline(err, fd, (uint8_t*)&proto, sizeof(as_proto), deadline_ms); if (status) { break; } as_proto_swap_from_be(&proto); size_t size = proto.sz; if (size > 0) { // Prepare buffer if (size > capacity) { as_command_free(buf, capacity); capacity = size; buf = as_command_init(capacity); } // Read remaining message bytes in group status = as_socket_read_deadline(err, fd, buf, size, deadline_ms); if (status) { break; } status = as_scan_parse_records(buf, size, task, err); if (status != AEROSPIKE_OK) { if (status == AEROSPIKE_NO_MORE_RECORDS) { status = AEROSPIKE_OK; } break; } } } as_command_free(buf, capacity); return status; }
as_status as_command_parse_header(as_error* err, int fd, uint64_t deadline_ms, void* user_data) { // Read header as_proto_msg* msg = user_data; as_status status = as_socket_read_deadline(err, fd, (uint8_t*)msg, sizeof(as_proto_msg), deadline_ms); if (status) { return status; } // Ensure that there is no data left to read. as_proto_swap_from_be(&msg->proto); as_msg_swap_header_from_be(&msg->m); size_t size = msg->proto.sz - msg->m.header_sz; if (size > 0) { as_log_warn("Unexpected data received from socket after a write: fd=%d size=%zu", fd, size); // Verify size is not corrupted. if (size > 100000) { // The socket will be closed on this error, so we don't have to worry about emptying it. return as_error_update(err, AEROSPIKE_ERR_CLIENT, "Unexpected data received from socket after a write: fd=%d size=%zu", fd, size); } // Empty socket. uint8_t* buf = cf_malloc(size); status = as_socket_read_deadline(err, fd, buf, size, deadline_ms); cf_free(buf); if (status) { return status; } } if (msg->m.result_code) { return as_error_set_message(err, msg->m.result_code, as_error_string(msg->m.result_code)); } return msg->m.result_code; }
static as_status as_admin_execute(aerospike* as, as_error* err, const as_policy_admin* policy, uint8_t* buffer, uint8_t* end) { uint32_t timeout_ms = (policy)? policy->timeout : as->config.policies.admin.timeout; if (timeout_ms <= 0) { timeout_ms = DEFAULT_TIMEOUT; } uint64_t deadline_ms = as_socket_deadline(timeout_ms); as_cluster* cluster = as->cluster; as_node* node = as_node_get_random(cluster); if (! node) { return as_error_set_message(err, AEROSPIKE_ERR_CLIENT, "Failed to find server node."); } int fd; as_status status = as_node_get_connection(err, node, deadline_ms, &fd); if (status) { as_node_release(node); return status; } status = as_admin_send(err, fd, buffer, end, deadline_ms); if (status) { as_node_close_connection(node, fd); as_node_release(node); return status; } status = as_socket_read_deadline(err, fd, buffer, HEADER_SIZE, deadline_ms); if (status) { as_node_close_connection(node, fd); as_node_release(node); return status; } as_node_put_connection(node, fd); as_node_release(node); status = buffer[RESULT_CODE]; if (status) { return as_error_set_message(err, status, as_error_string(status)); } return status; }
as_status as_command_parse_success_failure(as_error* err, int fd, uint64_t deadline_ms, void* user_data) { // Read header as_proto_msg msg; as_status status = as_socket_read_deadline(err, fd, (uint8_t*)&msg, sizeof(as_proto_msg), deadline_ms); if (status) { return status; } as_proto_swap_from_be(&msg.proto); as_msg_swap_header_from_be(&msg.m); size_t size = msg.proto.sz - msg.m.header_sz; uint8_t* buf = 0; if (size > 0) { // Read remaining message bytes. buf = as_command_init(size); status = as_socket_read_deadline(err, fd, buf, size, deadline_ms); if (status) { as_command_free(buf, size); return status; } } as_val** val = user_data; // Parse result code and record. status = msg.m.result_code; switch (status) { case AEROSPIKE_OK: { uint8_t* p = buf; status = as_command_parse_success_failure_bins(&p, err, &msg.m, val); if (status != AEROSPIKE_OK) { if (val) { *val = 0; } } break; } case AEROSPIKE_ERR_UDF: { status = as_command_parse_udf_failure(buf, err, &msg.m, status); if (val) { *val = 0; } break; } default: as_error_set_message(err, status, as_error_string(status)); if (val) { *val = 0; } break; } as_command_free(buf, size); return status; }
as_status as_command_parse_result(as_error* err, int fd, uint64_t deadline_ms, void* user_data) { // Read header as_proto_msg msg; as_status status = as_socket_read_deadline(err, fd, (uint8_t*)&msg, sizeof(as_proto_msg), deadline_ms); if (status) { return status; } as_proto_swap_from_be(&msg.proto); as_msg_swap_header_from_be(&msg.m); size_t size = msg.proto.sz - msg.m.header_sz; uint8_t* buf = 0; if (size > 0) { // Read remaining message bytes. buf = as_command_init(size); status = as_socket_read_deadline(err, fd, buf, size, deadline_ms); if (status) { as_command_free(buf, size); return status; } } // Parse result code and record. status = msg.m.result_code; as_command_parse_result_data* data = user_data; switch (status) { case AEROSPIKE_OK: { if (data->record) { as_record* rec = *data->record; if (rec) { if (msg.m.n_ops > rec->bins.capacity) { if (rec->bins._free) { free(rec->bins.entries); } rec->bins.capacity = msg.m.n_ops; rec->bins.size = 0; rec->bins.entries = malloc(sizeof(as_bin) * msg.m.n_ops); rec->bins._free = true; } } else { rec = as_record_new(msg.m.n_ops); *data->record = rec; } rec->gen = msg.m.generation; rec->ttl = cf_server_void_time_to_ttl(msg.m.record_ttl); uint8_t* p = as_command_ignore_fields(buf, msg.m.n_fields); as_command_parse_bins(rec, p, msg.m.n_ops, data->deserialize); } break; } case AEROSPIKE_ERR_UDF: { status = as_command_parse_udf_failure(buf, err, &msg.m, status); break; } default: as_error_set_message(err, status, as_error_string(status)); break; } as_command_free(buf, size); return status; }