Пример #1
0
int
citrusleaf_info_auth(as_cluster *cluster, char *hostname, short port, char *names, char **values, int timeout_ms)
{
	int rv = -1;
	as_vector sockaddr_in_v;
	as_vector_inita(&sockaddr_in_v, sizeof(struct sockaddr_in), 5);
	
	if (! as_lookup(NULL, hostname, port, true, &sockaddr_in_v)) {
		goto Done;
	}
	
	for (uint32_t i = 0; i < sockaddr_in_v.size; i++)
	{
		struct sockaddr_in* sa_in = as_vector_get(&sockaddr_in_v, i);
		
		if (0 == citrusleaf_info_host_auth(cluster, sa_in, names, values, timeout_ms, true, /* check bounds */ true)) {
			rv = 0;
			goto Done;
		}
	}
	
Done:
	as_vector_destroy(&sockaddr_in_v);
	return(rv);
}
/**
 *	Send an info request to a specific host. The response must be freed by the caller on success.
 *
 *	~~~~~~~~~~{.c}
 *	char * res = NULL;
 *	if ( aerospike_info_host(&as, &err, NULL, "127.0.0.1", 3000, "info", &res) != AEROSPIKE_OK ) {
 *		// handle error
 *	}
 *	else {
 *		// handle response
 *		free(res);
 *		res = NULL;
 *	}
 *	~~~~~~~~~~
 *
 *	@param as			The aerospike instance to use for this operation.
 *	@param err			The as_error to be populated if an error occurs.
 *	@param policy		The policy to use for this operation. If NULL, then the default policy will be used.
 *	@param addr			The IP address or hostname to send the request to.
 *	@param port			The port to send the request to.
 *	@param req			The info request to send.
 *	@param res			The response from the node. The response will be a NULL terminated string, allocated by the function, and must be freed by the caller.
 *
 *	@return AEROSPIKE_OK on success. Otherwise an error.
 *
 *	@ingroup info_operations
 */
as_status aerospike_info_host(
	aerospike * as, as_error * err, const as_policy_info * policy, 
	const char * addr, uint16_t port, const char * req, 
	char ** res) 
{
	as_error_reset(err);
	
	if (! policy) {
		policy = &as->config.policies.info;
	}
	
	as_vector sockaddr_in_v;
	as_vector_inita(&sockaddr_in_v, sizeof(struct sockaddr_in), 5);
	
	as_status status = as_lookup(NULL, err, (char*)addr, port, &sockaddr_in_v);
	
	if (status) {
		as_vector_destroy(&sockaddr_in_v);
		return status;
	}
	
	uint64_t deadline = as_socket_deadline(policy->timeout);
	as_cluster* cluster = as->cluster;
	status = AEROSPIKE_ERR_CLUSTER;
	bool loop = true;
	
	for (uint32_t i = 0; i < sockaddr_in_v.size && loop; i++) {
		struct sockaddr_in* sa_in = as_vector_get(&sockaddr_in_v, i);
		status = as_info_command_host(cluster, err, sa_in, (char*)req, policy->send_as_is, deadline, res);

		switch (status) {
			case AEROSPIKE_OK:
			case AEROSPIKE_ERR_TIMEOUT:
			case AEROSPIKE_ERR_INDEX_FOUND:
			case AEROSPIKE_ERR_INDEX_NOT_FOUND:
				loop = false;
				break;
				
			default:
				break;
		}
	}
	as_vector_destroy(&sockaddr_in_v);
	return status;
}
Пример #3
0
static void
as_free_roles(as_vector* roles, int offset)
{
    for (uint32_t i = offset; i < roles->size; i++) {
        as_role* role = as_vector_get_ptr(roles, i);
        cf_free(role);
    }
    as_vector_destroy(roles);
}
Пример #4
0
static void
as_free_users(as_vector* users, int offset)
{
    for (uint32_t i = offset; i < users->size; i++) {
        as_user* user = as_vector_get_ptr(users, i);
        cf_free(user);
    }
    as_vector_destroy(users);
}
Пример #5
0
static void
as_free_users(as_vector* users, int offset)
{
	for (uint32_t i = offset; i < users->size; i++) {
		as_user_roles* item = as_vector_get(users, i);
		cf_free(item);
	}
	as_vector_destroy(users);
}
Пример #6
0
void
as_node_destroy(as_node* node)
{
	// Drain out the queue and close the FDs
	int rv;
	do {
		int	fd;
		rv = cf_queue_pop(node->conn_q, &fd, CF_QUEUE_NOWAIT);
		if (rv == CF_QUEUE_OK)
			cf_close(fd);
	} while (rv == CF_QUEUE_OK);
	
	/*
	 do {
	 int	fd;
	 rv = cf_queue_pop(node->conn_q_asyncfd, &fd, CF_QUEUE_NOWAIT);
	 if (rv == CF_QUEUE_OK)
	 cf_close(fd);
	 } while (rv == CF_QUEUE_OK);
	 */
	
	/*
	 do {
	 //When we reach this point, ideally there should not be any workitems.
	 cl_async_work *aw;
	 rv = cf_queue_pop(node->asyncwork_q, &aw, CF_QUEUE_NOWAIT);
	 if (rv == CF_QUEUE_OK) {
	 free(aw);
	 }
	 } while (rv == CF_QUEUE_OK);
	 
	 //We want to delete all the workitems of this node
	 if (g_cl_async_hashtab) {
	 shash_reduce_delete(g_cl_async_hashtab, cl_del_node_asyncworkitems, node);
	 }
	 */
	
	as_vector_destroy(&node->addresses);
	cf_queue_destroy(node->conn_q);
	//cf_queue_destroy(node->conn_q_asyncfd);
	//cf_queue_destroy(node->asyncwork_q);
	
	if (node->info_fd >= 0) {
		cf_close(node->info_fd);
	}

	cf_free(node);
}
Пример #7
0
static as_status
as_cluster_seed_nodes(as_cluster* cluster, as_error* err, bool enable_warnings)
{
	// Add all nodes at once to avoid copying entire array multiple times.
	as_vector nodes_to_add;
	as_vector_inita(&nodes_to_add, sizeof(as_node*), 64);
	
	as_vector addresses;
	as_vector_inita(&addresses, sizeof(struct sockaddr_in), 5);
	
	as_node_info node_info;
	as_error error_local;
	as_error_init(&error_local); // AEROSPIKE_ERR_TIMEOUT doesn't come with a message; make sure it's initialized.
	as_status status = AEROSPIKE_OK;
	
	as_seeds* seeds = as_seeds_reserve(cluster);

	for (uint32_t i = 0; i < seeds->size; i++) {
		as_seed* seed = &seeds->array[i];
		as_vector_clear(&addresses);
		
		status = as_lookup(&error_local, seed->name, seed->port, &addresses);
		
		if (status != AEROSPIKE_OK) {
			if (enable_warnings) {
				as_log_warn("Failed to lookup %s:%d. %s %s", seed->name, seed->port, as_error_string(status), error_local.message);
			}
			continue;
		}

		for (uint32_t i = 0; i < addresses.size; i++) {
			struct sockaddr_in* addr = as_vector_get(&addresses, i);
			status = as_lookup_node(cluster, &error_local, addr, &node_info);
			
			if (status == AEROSPIKE_OK) {
				as_host host;
				if (as_strncpy(host.name, seed->name, sizeof(host.name))) {
					as_log_warn("Hostname has been truncated: %s", host.name);
				}
				host.port = seed->port;

				as_node* node = as_cluster_find_node_in_vector(&nodes_to_add, node_info.name);
				
				if (node) {
					as_close(node_info.fd);
					as_node_add_address(node, &host, addr);
				}
				else {
					node = as_node_create(cluster, &host, addr, &node_info);
					as_address* a = as_node_get_address_full(node);
					as_log_info("Add node %s %s:%d", node->name, a->name, (int)cf_swap_from_be16(a->addr.sin_port));
					as_vector_append(&nodes_to_add, &node);
				}
			}
			else {
				if (enable_warnings) {
					as_log_warn("Failed to connect to seed %s:%d. %s %s", seed->name, seed->port, as_error_string(status), error_local.message);
				}
			}
		}
	}
	
	as_seeds_release(seeds);

	if (nodes_to_add.size > 0) {
		as_cluster_add_nodes(cluster, &nodes_to_add);
		status = AEROSPIKE_OK;
	}
	else {
		status = as_error_set_message(err, AEROSPIKE_ERR_CLIENT, "Failed to seed cluster");
	}
	
	as_vector_destroy(&nodes_to_add);
	as_vector_destroy(&addresses);
	return status;
}
/**
 * @return AEROSPIKE_OK if successful. Otherwise an error occurred.
 */
as_status aerospike_udf_list(
	aerospike * as, as_error * err, const as_policy_info * policy, 
	as_udf_files * files)
{
	as_error_reset(err);
	
	if (! policy) {
		policy = &as->config.policies.info;
	}

	char* response = 0;
	as_status status = aerospike_info_any(as, err, policy, "udf-list", &response);
	
	if (status) {
		return status;
	}
	
	// response := udf-list\tfilename=<name>,hash=<hash>,type=<type>;[filename=<name>...]
	char* p = strchr(response, '\t');
	
	if (!p) {
		as_error_update(err, AEROSPIKE_ERR_PARAM, "Invalid udf-list response: %s", response);
		free(response);
		return AEROSPIKE_ERR_PARAM;
	}
	p++;
	
	uint32_t capacity = (files->capacity <= 0) ? 500 : files->capacity;
	
	as_vector ptrs;
	as_vector_inita(&ptrs, sizeof(as_udf_file_ptr), capacity);
	
	as_udf_file_ptr ptr = {0,0,0};
	char* token = p;
	
	while (*p) {
		switch (*p) {
			case '=':
				*p++ = 0;
				as_udf_parse_file(token, p, &ptr);
				break;
	
			case ',':
				*p++ = 0;
				token = p;
				break;
				
			case ';':
				*p++ = 0;
				token = p;
				as_vector_append(&ptrs, &ptr);
				ptr.name = 0;
				ptr.hash = 0;
				ptr.type = 0;
				break;
				
			default:
				p++;
				break;
		}
	}
	
	if (files->capacity == 0 && files->entries == NULL) {
		as_udf_files_init(files, ptrs.size);
	}

	uint32_t limit = ptrs.size < files->capacity ? ptrs.size : files->capacity;
	files->size = limit;

	for (uint32_t i = 0; i < limit; i++) {
		as_udf_file_ptr* ptr = as_vector_get(&ptrs, i);
		as_udf_file* file = &files->entries[i];
		
		if (ptr->name) {
			as_strncpy(file->name, ptr->name, AS_UDF_FILE_NAME_SIZE);
		}
		else {
			file->name[0] = 0;
		}
		
		if (ptr->hash) {
			// The hash is not null terminated, so normal strncpy is appropriate here.
			// strncpy will also pad zeroes if hash size is incorrect.
			strncpy((char*)file->hash, ptr->hash, AS_UDF_FILE_HASH_SIZE);
		}
		else {
			file->hash[0] = 0;
		}
		
		file->type = AS_UDF_TYPE_LUA;
		file->content._free = false;
		file->content.size = 0;
		file->content.capacity = 0;
		file->content.bytes = NULL;
	}

	as_vector_destroy(&ptrs);
	free(response);
	return AEROSPIKE_OK;
}