Exemple #1
0
as_status
as_key_set_digest(as_error* err, as_key* key)
{
	if (key->digest.init) {
		return AEROSPIKE_OK;
	}
	
	size_t set_len = strlen(key->set);
	size_t size;
	
	as_val* val = (as_val*)key->valuep;
	uint8_t* buf;
	
	switch (val->type) {
		case AS_INTEGER: {
			as_integer* v = as_integer_fromval(val);
			size = 9;
			buf = alloca(size);
			buf[0] = AS_BYTES_INTEGER;
			*(uint64_t*)&buf[1] = cf_swap_to_be64(v->value);
			break;
		}
		case AS_DOUBLE: {
			as_double* v = as_double_fromval(val);
			size = 9;
			buf = alloca(size);
			buf[0] = AS_BYTES_DOUBLE;
			*(double*)&buf[1] = cf_swap_to_big_float64(v->value);
			break;
		}
		case AS_STRING: {
			as_string* v = as_string_fromval(val);
			size_t len = as_string_len(v);
			size = len + 1;
			buf = alloca(size);
			buf[0] = AS_BYTES_STRING;
			memcpy(&buf[1], v->value, len);
			break;
		}
		case AS_BYTES: {
			as_bytes* v = as_bytes_fromval(val);
			size = v->size + 1;
			buf = alloca(size);
			// Note: v->type must be a blob type (AS_BYTES_BLOB, AS_BYTES_JAVA, AS_BYTES_PYTHON ...).
			// Otherwise, the particle type will be reassigned to a non-blob which causes a
			// mismatch between type and value.
			buf[0] = v->type;
			memcpy(&buf[1], v->value, v->size);
			break;
		}
		default: {
			return as_error_update(err, AEROSPIKE_ERR_PARAM, "Invalid key type: %d", val->type);
		}
	}
		
	cf_digest_compute2(key->set, set_len, buf, size, (cf_digest*)key->digest.value);
	key->digest.init = true;
	return AEROSPIKE_OK;
}
static as_status
as_admin_send(as_error* err, int fd, uint8_t* buffer, uint8_t* end, uint64_t deadline_ms)
{
    uint64_t len = end - buffer;
    uint64_t proto = (len - 8) | (MSG_VERSION << 56) | (MSG_TYPE << 48);
    *(uint64_t*)buffer = cf_swap_to_be64(proto);

    return as_socket_write_deadline(err, fd, buffer, len, deadline_ms);
}
static int
as_send(int fd, uint8_t* buffer, uint8_t* end, uint64_t deadline_ms, int timeout_ms)
{
	uint64_t len = end - buffer;
	uint64_t proto = (len - 8) | (MSG_VERSION << 56) | (MSG_TYPE << 48);
	*(uint64_t*)buffer = cf_swap_to_be64(proto);
	
	return cf_socket_write_timeout(fd, buffer, len, deadline_ms, timeout_ms);
}
// Byte swap proto from current machine byte order to network byte order (big endian).
void
as_proto_swap_to_be(as_proto *p)
{
	uint8_t	 version = p->version;
	uint8_t  type = p->type;
	p->version = p->type = 0;
	p->sz = cf_swap_to_be64(*(uint64_t*)p);
	p->version = version;
	p->type = type;
}
static uint8_t*
as_command_write_user_key(uint8_t* begin, const as_key* key)
{
    uint8_t* p = begin + AS_FIELD_HEADER_SIZE;
    as_val* val = (as_val*)key->valuep;
    uint32_t len;

    // Key must not be list or map.
    switch (val->type) {
    default:
    case AS_NIL: {
        *p++ = AS_BYTES_UNDEF;
        len = 0;
        break;
    }
    case AS_INTEGER: {
        as_integer* v = as_integer_fromval(val);
        *p++ = AS_BYTES_INTEGER;
        *(uint64_t*)p = cf_swap_to_be64(v->value);
        p += 8;
        len = 8;
        break;
    }
    case AS_DOUBLE: {
        as_double* v = as_double_fromval(val);
        *p++ = AS_BYTES_DOUBLE;
        *(double*)p = cf_swap_to_big_float64(v->value);
        p += 8;
        len = 8;
        break;
    }
    case AS_STRING: {
        as_string* v = as_string_fromval(val);
        *p++ = AS_BYTES_STRING;
        // v->len should have been already set when calculating the digest.
        memcpy(p, v->value, v->len);
        p += v->len;
        len = (uint32_t)v->len;
        break;
    }
    case AS_BYTES: {
        as_bytes* v = as_bytes_fromval(val);
        // Note: v->type must be a blob type (AS_BYTES_BLOB, AS_BYTES_JAVA, AS_BYTES_PYTHON ...).
        // Otherwise, the particle type will be reassigned to a non-blob which causes a
        // mismatch between type and value.
        *p++ = v->type;
        memcpy(p, v->value, v->size);
        p += v->size;
        len = v->size;
        break;
    }
    }
    as_command_write_field_header(begin, AS_FIELD_KEY, ++len);
    return p;
}
uint32_t
as_authenticate_set(const char* user, const char* credential, uint8_t* buffer)
{
    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);

    uint64_t len = p - buffer;
    uint64_t proto = (len - 8) | (MSG_VERSION << 56) | (MSG_TYPE << 48);
    *(uint64_t*)buffer = cf_swap_to_be64(proto);
    return (uint32_t)len;
}
uint32_t
geojson_to_wire(const as_particle *p, uint8_t *wire)
{
	// Use blob routine first.
	uint32_t sz = blob_to_wire(p, wire);

	// Swap ncells.
	uint16_t *p_ncells = (uint16_t *)(wire + sizeof(uint8_t));
	uint16_t ncells = *p_ncells;

	*p_ncells = cf_swap_to_be16(*p_ncells);
	++p_ncells;

	// Swap the cells.
	uint64_t *p_cell_begin = (uint64_t *)p_ncells;
	uint64_t *p_cell_end = p_cell_begin + ncells;

	for (uint64_t *p_cell = p_cell_begin; p_cell < p_cell_end; ++p_cell) {
		*p_cell = cf_swap_to_be64(*p_cell);
	}

	return sz;
}
uint8_t*
as_command_write_bin(uint8_t* begin, uint8_t operation_type, const as_bin* bin, as_buffer* buffer)
{
    uint8_t* p = begin + AS_OPERATION_HEADER_SIZE;
    const char* name = bin->name;

    // Copy string, but do not transfer null byte.
    while (*name) {
        *p++ = *name++;
    }
    uint8_t name_len = p - begin - AS_OPERATION_HEADER_SIZE;
    as_val* val = (as_val*)bin->valuep;
    uint32_t val_len;
    uint8_t val_type;

    switch (val->type) {
    default:
    case AS_NIL: {
        val_len = 0;
        val_type = AS_BYTES_UNDEF;
        break;
    }
    case AS_INTEGER: {
        as_integer* v = as_integer_fromval(val);
        *(uint64_t*)p = cf_swap_to_be64(v->value);
        p += 8;
        val_len = 8;
        val_type = AS_BYTES_INTEGER;
        break;
    }
    case AS_DOUBLE: {
        as_double* v = as_double_fromval(val);
        *(double*)p = cf_swap_to_big_float64(v->value);
        p += 8;
        val_len = 8;
        val_type = AS_BYTES_DOUBLE;
        break;
    }
    case AS_STRING: {
        as_string* v = as_string_fromval(val);
        // v->len should have been already set by as_command_value_size().
        memcpy(p, v->value, v->len);
        p += v->len;
        val_len = (uint32_t)v->len;
        val_type = AS_BYTES_STRING;
        break;
    }
    case AS_BYTES: {
        as_bytes* v = as_bytes_fromval(val);
        memcpy(p, v->value, v->size);
        p += v->size;
        val_len = v->size;
        // Note: v->type must be a blob type (AS_BYTES_BLOB, AS_BYTES_JAVA, AS_BYTES_PYTHON ...).
        // Otherwise, the particle type will be reassigned to a non-blob which causes a
        // mismatch between type and value.
        val_type = v->type;
        break;
    }
    case AS_LIST: {
        memcpy(p, buffer->data, buffer->size);
        p += buffer->size;
        val_len = buffer->size;
        val_type = AS_BYTES_LIST;
        break;
    }
    case AS_MAP: {
        memcpy(p, buffer->data, buffer->size);
        p += buffer->size;
        val_len = buffer->size;
        val_type = AS_BYTES_MAP;
        break;
    }
    }
    *(uint32_t*)begin = cf_swap_to_be32(name_len + val_len + 4);
    begin += 4;
    *begin++ = operation_type;
    *begin++ = val_type;
    *begin++ = 0;
    *begin++ = name_len;
    return p;
}
Exemple #9
0
cl_msg *
as_msg_make_response_msg(uint32_t result_code, uint32_t generation,
		uint32_t void_time, as_msg_op **ops, as_bin **bins, uint16_t bin_count,
		as_namespace *ns, cl_msg *msgp_in, size_t *msg_sz_in, uint64_t trid,
		const char *setname)
{
	size_t msg_sz = sizeof(cl_msg);

	msg_sz += sizeof(as_msg_op) * bin_count;

	for (uint16_t i = 0; i < bin_count; i++) {
		if (ops) {
			msg_sz += ops[i]->name_sz;
		}
		else if (bins[i]) {
			msg_sz += ns->single_bin ?
					0 : strlen(as_bin_get_name_from_id(ns, bins[i]->id));
		}
		else {
			cf_crash(AS_PROTO, "making response message with null bin and op");
		}

		if (bins[i]) {
			msg_sz += as_bin_particle_client_value_size(bins[i]);
		}
	}

	if (trid != 0) {
		msg_sz += sizeof(as_msg_field) + sizeof(trid);
	}

	uint32_t setname_len = 0;

	if (setname) {
		setname_len = strlen(setname);
		msg_sz += sizeof(as_msg_field) + setname_len;
	}

	uint8_t *b;

	if (! msgp_in || *msg_sz_in < msg_sz) {
		b = cf_malloc(msg_sz);

		if (! b) {
			return NULL;
		}
	}
	else {
		b = (uint8_t *)msgp_in;
	}

	*msg_sz_in = msg_sz;

	uint8_t *buf = b;
	cl_msg *msgp = (cl_msg *)buf;

	msgp->proto.version = PROTO_VERSION;
	msgp->proto.type = PROTO_TYPE_AS_MSG;
	msgp->proto.sz = msg_sz - sizeof(as_proto);
	as_proto_swap(&msgp->proto);

	as_msg *m = &msgp->msg;

	m->header_sz = sizeof(as_msg);
	m->info1 = 0;
	m->info2 = 0;
	m->info3 = 0;
	m->unused = 0;
	m->result_code = result_code;
	m->generation = generation;
	m->record_ttl = void_time;
	m->transaction_ttl = 0;
	m->n_ops = bin_count;
	m->n_fields = 0;

	buf += sizeof(cl_msg);

	if (trid != 0) {
		m->n_fields++;

		as_msg_field *trfield = (as_msg_field *)buf;

		trfield->field_sz = 1 + sizeof(uint64_t);
		trfield->type = AS_MSG_FIELD_TYPE_TRID;
		*(uint64_t *)trfield->data = cf_swap_to_be64(trid);

		buf += sizeof(as_msg_field) + sizeof(uint64_t);
		as_msg_swap_field(trfield);
	}

	if (setname) {
		m->n_fields++;

		as_msg_field *trfield = (as_msg_field *)buf;

		trfield->field_sz = 1 + setname_len;
		trfield->type = AS_MSG_FIELD_TYPE_SET;
		memcpy(trfield->data, setname, setname_len);

		buf += sizeof(as_msg_field) + setname_len;
		as_msg_swap_field(trfield);
	}

	as_msg_swap_header(m);

	for (uint16_t i = 0; i < bin_count; i++) {
		as_msg_op *op = (as_msg_op *)buf;

		op->version = 0;

		if (ops) {
			op->op = ops[i]->op;
			memcpy(op->name, ops[i]->name, ops[i]->name_sz);
			op->name_sz = ops[i]->name_sz;
		}
		else {
			op->op = AS_MSG_OP_READ;
			op->name_sz = as_bin_memcpy_name(ns, op->name, bins[i]);
		}

		op->op_sz = 4 + op->name_sz;

		buf += sizeof(as_msg_op) + op->name_sz;
		buf += as_bin_particle_to_client(bins[i], op);

		as_msg_swap_op(op);
	}

	return (cl_msg *)b;
}
Exemple #10
0
uint8_t*
as_command_write_bin(uint8_t* begin, uint8_t operation_type, const as_bin* bin, as_buffer* buffer)
{
	uint8_t* p = begin + AS_OPERATION_HEADER_SIZE;
	const char* name = bin->name;

	// Copy string, but do not transfer null byte.
	while (*name) {
		*p++ = *name++;
	}
	uint8_t name_len = p - begin - AS_OPERATION_HEADER_SIZE;
	as_val* val = (as_val*)bin->valuep;
	uint32_t val_len;
	uint8_t val_type;
	
	switch (val->type) {
		default:
		case AS_NIL: {
			val_len = 0;
			val_type = AS_BYTES_UNDEF;
			break;
		}
		case AS_INTEGER: {
			as_integer* v = as_integer_fromval(val);
			*(uint64_t*)p = cf_swap_to_be64(v->value);
			p += 8;
			val_len = 8;
			val_type = AS_BYTES_INTEGER;
			break;
		}
		case AS_DOUBLE: {
			as_double* v = as_double_fromval(val);
			*(double*)p = cf_swap_to_big_float64(v->value);
			p += 8;
			val_len = 8;
			val_type = AS_BYTES_DOUBLE;
			break;
		}
		case AS_STRING: {
			as_string* v = as_string_fromval(val);
			// v->len should have been already set by as_command_value_size().
			memcpy(p, v->value, v->len);
			p += v->len;
			val_len = (uint32_t)v->len;
			val_type = AS_BYTES_STRING;
			break;
		}
		case AS_GEOJSON: {
			// We send a cellid placeholder so we can fill in points
			// in place on the server w/o changing object size.

			as_geojson* v = as_geojson_fromval(val);
			// v->len should have been already set by as_command_value_size().

			// as_particle_geojson_mem::flags
			*p++ = 0;

			// as_particle_geojson_mem::ncells
			*(uint16_t *) p = cf_swap_to_be16(0);
			p += sizeof(uint16_t);
			
			// placeholder cellid
			// THIS LOOP EXECUTES 0 TIMES (still, it belongs here ...)
			for (int ii = 0; ii < 0; ++ii) {
				*(uint64_t *) p = cf_swap_to_be64(0);
				p += sizeof(uint64_t);
			}

			// json data itself
			memcpy(p, v->value, v->len);
			p += v->len;

			val_len = (uint32_t)(1 + 2 + (0 * 8) + v->len);
			val_type = AS_BYTES_GEOJSON;
			break;
		}
		case AS_BYTES: {
			as_bytes* v = as_bytes_fromval(val);
			memcpy(p, v->value, v->size);
			p += v->size;
			val_len = v->size;
			// Note: v->type must be a blob type (AS_BYTES_BLOB, AS_BYTES_JAVA, AS_BYTES_PYTHON ...).
			// Otherwise, the particle type will be reassigned to a non-blob which causes a
			// mismatch between type and value.
			val_type = v->type;
			break;
		}
		case AS_LIST: {
			memcpy(p, buffer->data, buffer->size);
			p += buffer->size;
			val_len = buffer->size;
			val_type = AS_BYTES_LIST;
			cf_free(buffer->data);
			break;
		}
		case AS_MAP: {
			memcpy(p, buffer->data, buffer->size);
			p += buffer->size;
			val_len = buffer->size;
			val_type = AS_BYTES_MAP;
			cf_free(buffer->data);
			break;
		}
	}
	*(uint32_t*)begin = cf_swap_to_be32(name_len + val_len + 4);
	begin += 4;
	*begin++ = operation_type;
	*begin++ = val_type;
	*begin++ = 0;
	*begin++ = name_len;
	return p;
}