Example #1
0
static as_status
as_parse_roles(as_error* err, uint8_t* buffer, size_t size, as_vector* /*<as_role*>*/ roles)
{
    uint8_t* p = buffer;
    uint8_t* end = buffer + size;

    as_role* role;
    char role_name[AS_ROLE_SIZE];
    int len;
    int sz;
    uint8_t id;
    uint8_t field_count;
    uint8_t result;

    while (p < end) {
        result = p[1];

        if (result != 0) {
            return result;
        }

        field_count = p[3];
        p += HEADER_REMAINING;

        role_name[0] = 0;
        role = 0;

        for (uint8_t b = 0; b < field_count; b++) {
            len = cf_swap_from_be32(*(int*)p);
            p += 4;
            id = *p++;
            len--;

            if (id == ROLE) {
                sz = (len <= (AS_ROLE_SIZE-1))? len : (AS_ROLE_SIZE-1);
                memcpy(role_name, p, sz);
                role_name[sz] = 0;
                p += len;
            }
            else if (id == PRIVILEGES) {
                p = as_parse_privileges(p, &role);
            }
            else {
                p += len;
            }
        }

        if (role_name[0] == 0 && role == 0) {
            continue;
        }

        if (! role) {
            role = cf_malloc(sizeof(as_role));
            role->privileges_size = 0;
        }
        strcpy(role->name, role_name);
        as_vector_append(roles, &role);
    }
    return AEROSPIKE_OK;
}
Example #2
0
static as_status
as_parse_users(as_error* err, uint8_t* buffer, size_t size, as_vector* /*<as_user*>*/ users)
{
    uint8_t* p = buffer;
    uint8_t* end = buffer + size;

    as_user* user;
    char user_name[AS_USER_SIZE];
    int len;
    int sz;
    uint8_t id;
    uint8_t field_count;
    uint8_t result;

    while (p < end) {
        result = p[1];

        if (result != 0) {
            return result;
        }

        field_count = p[3];
        p += HEADER_REMAINING;

        user_name[0] = 0;
        user = 0;

        for (uint8_t b = 0; b < field_count; b++) {
            len = cf_swap_from_be32(*(int*)p);
            p += 4;
            id = *p++;
            len--;

            if (id == USER) {
                sz = (len <= (AS_USER_SIZE-1))? len : (AS_USER_SIZE-1);
                memcpy(user_name, p, sz);
                user_name[sz] = 0;
                p += len;
            }
            else if (id == ROLES) {
                p = as_parse_users_roles(p, &user);
            }
            else {
                p += len;
            }
        }

        if (user_name[0] == 0 && user == 0) {
            continue;
        }

        if (! user) {
            user = cf_malloc(sizeof(as_user));
            user->roles_size = 0;
        }
        strcpy(user->name, user_name);
        as_vector_append(users, &user);
    }
    return 0;
}
Example #3
0
void
as_node_add_address(as_node* node, struct sockaddr_in* addr)
{
	as_address address;
	address.addr = *addr;
	as_socket_address_name(addr, address.name);
	as_vector_append(&node->addresses, &address);
}
void
as_seeds_update(as_cluster* cluster, as_seed* seed_list, uint32_t size)
{
	as_seeds* seeds = seeds_create(seed_list, size);
	as_seeds* old = swap_seeds(cluster, seeds);

	as_gc_item item;
	item.data = old;
	item.release_fn = gc_seeds;
	as_vector_append(cluster->gc, &item);
}
static void
as_cluster_find_nodes_to_add(as_cluster* cluster, as_vector* /* <as_host> */ friends, as_vector* /* <as_node*> */ nodes_to_add)
{
	as_error err;
	as_error_init(&err);
	as_vector addresses;
	as_vector_inita(&addresses, sizeof(struct sockaddr_in), 5);
	
	as_node_info node_info;

	for (uint32_t i = 0; i < friends->size; i++) {
		as_host* friend = as_vector_get(friends, i);
		as_vector_clear(&addresses);
		
		as_status status = as_lookup(&err, friend->name, friend->port, &addresses);
		
		if (status != AEROSPIKE_OK) {
			as_log_warn("%s %s", as_error_string(status), err.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, &err, addr, &node_info);
			
			if (status == AEROSPIKE_OK) {
				as_node* node = as_cluster_find_node(cluster->nodes, nodes_to_add, node_info.name);
				
				if (node) {
					// Duplicate node name found.  This usually occurs when the server
					// services list contains both internal and external IP addresses
					// for the same node.  Add new host to list of alias filters
					// and do not add new node.
					as_close(node_info.fd);
					as_address* a = as_node_get_address_full(node);
					as_log_info("Node %s:%d already exists with nodeid %s and address %s:%d", 
						friend->name, friend->port, node->name, a->name,
						(int)cf_swap_from_be16(a->addr.sin_port));
					node->friends++;
					as_node_add_address(node, friend, addr);
					continue;
				}
				
				node = as_node_create(cluster, friend, addr, &node_info);
				as_address* a = as_node_get_address_full(node);
				as_log_info("Add node %s %s:%d", node_info.name, a->name, (int)cf_swap_from_be16(a->addr.sin_port));
				as_vector_append(nodes_to_add, &node);
			}
			else {
				as_log_warn("Failed to connect to friend %s:%d. %s %s", friend->name, friend->port, as_error_string(status), err.message);
			}
		}
Example #6
0
bool
as_vector_append_unique(as_vector* vector, void* value)
{
	char* item = vector->list;
	for (uint32_t i = 0; i < vector->size; i++) {
		if (memcmp(item, value, vector->item_size) == 0) {
			return false;
		}
		item += vector->item_size;
	}
	as_vector_append(vector, value);
	return true;
}
void
as_seeds_add(as_cluster* cluster, as_seed* seed_list, uint32_t size) {
	as_seeds* current = as_seeds_reserve(cluster);
	as_seed concat[current->size + size];
	
	as_seed* src = current->array;
	as_seed* trg = concat;

	for (uint32_t i = 0; i < current->size; i++) {
		trg->name = src->name;
		trg->port = src->port;
		src++;
		trg++;
	}

	uint32_t dups = 0;
	src = seed_list;

	for (uint32_t i = 0; i < size; i++) {
		if (as_find_seed(cluster, src->name, src->port)) {
			as_log_debug("Duplicate seed %s:%d", src->name, src->port);
			dups++;
			continue;
		}

		as_log_debug("Add seed %s:%d", src->name, src->port);
		trg->name = src->name;
		trg->port = src->port;
		src++;
		trg++;
	}

	as_seeds_release(current);

	as_seeds* seeds = seeds_create(concat, current->size + size - dups);
	as_seeds* old = swap_seeds(cluster, seeds);

	as_gc_item item;
	item.data = old;
	item.release_fn = gc_seeds;
	as_vector_append(cluster->gc, &item);
}
/**
 *	Add nodes using copy on write semantics.
 */
void
as_cluster_add_nodes_copy(as_cluster* cluster, as_vector* /* <as_node*> */ nodes_to_add)
{
	// Create temporary nodes array.
	as_nodes* nodes_old = cluster->nodes;
	as_nodes* nodes_new = as_nodes_create(nodes_old->size + nodes_to_add->size);

	// Add existing nodes.
	memcpy(nodes_new->array, nodes_old->array, sizeof(as_node*) * nodes_old->size);
		
	// Add new nodes.
	memcpy(&nodes_new->array[nodes_old->size], nodes_to_add->list, sizeof(as_node*) * nodes_to_add->size);
		
	// Replace nodes with copy.
	set_nodes(cluster, nodes_new);
	
	// Put old nodes on garbage collector stack.
	as_gc_item item;
	item.data = nodes_old;
	item.release_fn = (as_release_fn)release_nodes;
	as_vector_append(cluster->gc, &item);
}
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;
}