示例#1
0
int nb_io_expect(struct tnt_stream *t, char *sz) {
    struct tnt_stream_net *sn = TNT_SNET_CAST(t);
    char buf[256];
    size_t len = strlen(sz);
    if (len > sizeof(buf)) {
        sn->error = TNT_EBIG;
        return -1;
    }
    if (tnt_io_recv(TNT_SNET_CAST(t), buf, len) == -1)
        return -1;
    if (!memcmp(buf, sz, len))
        return 0;
    sn->error = TNT_EFAIL;
    return -1;
}
示例#2
0
/*
 * tnt_net()
 *
 * create and initialize network stream;
 *
 * s - stream pointer, maybe NULL
 * 
 * if stream pointer is NULL, then new stream will be created. 
 *
 * returns stream pointer, or NULL on error.
*/
struct tnt_stream *tnt_net(struct tnt_stream *s) {
	int allocated = s == NULL;
	s = tnt_net_tryalloc(s);
	if (s == NULL)
		return NULL;
	/* allocating stream data */
	s->data = tnt_mem_alloc(sizeof(struct tnt_stream_net));
	if (s->data == NULL) {
		if (allocated)
			tnt_stream_free(s);
		return NULL;
	}
	memset(s->data, 0, sizeof(struct tnt_stream_net));
	/* initializing interfaces */
	s->read = tnt_net_read;
	s->reply = tnt_net_reply;
	s->write = tnt_net_write;
	s->writev = tnt_net_writev;
	s->free = tnt_net_free;
	/* initializing internal data */
	struct tnt_stream_net *sn = TNT_SNET_CAST(s);
	sn->fd = -1;
	tnt_opt_init(&sn->opt);
	return s;
}
示例#3
0
static void tnt_net_free(struct tnt_stream *s) {
	struct tnt_stream_net *sn = TNT_SNET_CAST(s);
	tnt_io_close(sn);
	tnt_iob_free(&sn->sbuf);
	tnt_iob_free(&sn->rbuf);
	tnt_opt_free(&sn->opt);
	tnt_mem_free(s->data);
}
示例#4
0
/*
 * tnt_set()
 *
 * set options to network stream;
 *
 * s   - network stream pointer
 * opt - option id
 * ... - option value
 * 
 * returns 0 on success, or -1 on error.
*/
int tnt_set(struct tnt_stream *s, int opt, ...) {
	struct tnt_stream_net *sn = TNT_SNET_CAST(s);
	va_list args;
	va_start(args, opt);
	sn->error = tnt_opt_set(&sn->opt, opt, args);
	va_end(args);
	return (sn->error == TNT_EOK) ? 0 : -1;
}
示例#5
0
static ssize_t
tnt_net_write(struct tnt_stream *s, char *buf, size_t size) {
	struct tnt_stream_net *sn = TNT_SNET_CAST(s);
	ssize_t rc = tnt_io_send(sn, buf, size);
	if (rc != -1)
		s->wrcnt++;
	return rc;
}
示例#6
0
static ssize_t
tnt_net_writev(struct tnt_stream *s, struct iovec *iov, int count) {
	struct tnt_stream_net *sn = TNT_SNET_CAST(s);
	ssize_t rc = tnt_io_sendv(sn, iov, count);
	if (rc != -1)
		s->wrcnt++;
	return rc;
}
示例#7
0
/*
 * tnt_connect()
 *
 * connect to server;
 * reconnect to server;
 *
 * s - network stream pointer
 * 
 * returns 0 on success, or -1 on error.
*/
int tnt_connect(struct tnt_stream *s) {
	struct tnt_stream_net *sn = TNT_SNET_CAST(s);
	if (sn->connected)
		tnt_close(s);
	sn->error = tnt_io_connect(sn, sn->opt.hostname, sn->opt.port);
	if (sn->error != TNT_EOK)
		return -1;
	return 0;
}
示例#8
0
/*
 * tnt_strerror()
 *
 * get library error status description string;
 *
 * s - network stream pointer
*/
char *tnt_strerror(struct tnt_stream *s) {
	struct tnt_stream_net *sn = TNT_SNET_CAST(s);
	if (sn->error == TNT_ESYSTEM) {
		static char msg[256];
		snprintf(msg, sizeof(msg), "%s (errno: %d)",
			 strerror(sn->errno_), sn->errno_);
		return msg;
	}
	return tnt_error_list[(int)sn->error].desc;
}
示例#9
0
int
nb_mc_get(struct tnt_stream *t, char *key)
{
	char buf[64];
	int len = snprintf(buf, sizeof(buf), "get %s\r\n", key);
	struct iovec v[1];
	v[0].iov_base = buf;
	v[0].iov_len = len;
	int r = tnt_io_sendv(TNT_SNET_CAST(t), v, 1);
	return (r < 0) ? -1 : 0;
}
示例#10
0
ssize_t
tnt_auth(struct tnt_stream *s, const char *user, int ulen,
	 const char *pass, int plen)
{
	struct tnt_iheader hdr;
	struct iovec v[6]; int v_sz = 5;
	char *data = NULL, *body_start = NULL;
	int guest = !user || (ulen == 5 && !strncmp(user, "guest", 5));
	if (guest) {
		user = "******";
		ulen = 5;
	}
	encode_header(&hdr, TNT_OP_AUTH, s->reqid++);
	v[1].iov_base = (void *)hdr.header;
	v[1].iov_len  = hdr.end - hdr.header;
	char body[64]; data = body; body_start = data;

	data = mp_encode_map(data, 2);
	data = mp_encode_uint(data, TNT_USERNAME);
	data = mp_encode_strl(data, ulen);
	v[2].iov_base = body_start;
	v[2].iov_len  = data - body_start;
	v[3].iov_base = (void *)user;
	v[3].iov_len  = ulen;
	body_start = data;
	data = mp_encode_uint(data, TNT_TUPLE);
	if (!guest) {
		data = mp_encode_array(data, 2);
		data = mp_encode_str(data, "chap-sha1", strlen("chap-sha1"));
		data = mp_encode_strl(data, TNT_SCRAMBLE_SIZE);
		char salt[64], scramble[TNT_SCRAMBLE_SIZE];
		base64_decode(TNT_SNET_CAST(s)->greeting + TNT_VERSION_SIZE,
			      TNT_SALT_SIZE, salt, 64);
		tnt_scramble_prepare(scramble, salt, pass, plen);
		v[5].iov_base = scramble;
		v[5].iov_len  = TNT_SCRAMBLE_SIZE;
		v_sz++;
	} else {
		data = mp_encode_array(data, 0);
	}
	v[4].iov_base = body_start;
	v[4].iov_len  = data - body_start;

	size_t package_len = 0;
	for (int i = 1; i < v_sz; ++i) {
		package_len += v[i].iov_len;
	}
	char len_prefix[9];
	char *len_end = mp_encode_luint32(len_prefix, package_len);
	v[0].iov_base = len_prefix;
	v[0].iov_len = len_end - len_prefix;
	return s->writev(s, v, v_sz);
}
示例#11
0
int
nb_mc_set(struct tnt_stream *t, char *key, char *data, int data_size)
{
	char buf[64];
	int len = snprintf(buf, sizeof(buf), "set %s 0 0 %d\r\n", key, data_size);
	struct iovec v[3];
	v[0].iov_base = buf;
	v[0].iov_len  = len;
	v[1].iov_base = data;
	v[1].iov_len  = data_size;
	v[2].iov_base = "\r\n";
	v[2].iov_len  = 2;
	int r = tnt_io_sendv(TNT_SNET_CAST(t), v, 3);
	tnt_flush(t);
	return (r < 0) ? -1 : 0;
}
示例#12
0
/*
 * tnt_rpl_open()
 *
 * connect to a server and initialize handshake;
 *
 * s   - replication stream pointer
 * lsn - start lsn 
 *
 * network stream must be properly initialized before
 * this function called (see ttnt_rpl_net, tnt_set).
 * 
 * returns 0 on success, or -1 on error.
*/
int tnt_rpl_open(struct tnt_stream *s, uint64_t lsn)
{
	struct tnt_stream_rpl *sr = TNT_RPL_CAST(s);
	/* intializing connection */
	if (tnt_init(sr->net) == -1)
		return -1;
	if (tnt_connect(sr->net) == -1)
		return -1;
	/* sending initial lsn */
	struct tnt_stream_net *sn = TNT_SNET_CAST(sr->net);
	if (tnt_io_send_raw(sn, (char*)&lsn, sizeof(lsn), 1) == -1)
		return -1;
	/* reading and checking version */
	uint32_t version = 0;
	if (tnt_io_recv_raw(sn, (char*)&version, sizeof(version), 1) == -1)
		return -1;
	if (version != tnt_rpl_version)
		return -1;
	return 0;
}
示例#13
0
/*
 * tnt_init()
 *
 * initialize prepared network stream;
 *
 * s - network stream pointer
 * 
 * returns 0 on success, or -1 on error.
*/
int tnt_init(struct tnt_stream *s) {
	struct tnt_stream_net *sn = TNT_SNET_CAST(s);
	if (tnt_iob_init(&sn->sbuf, sn->opt.send_buf, sn->opt.send_cb,
		sn->opt.send_cbv, sn->opt.send_cb_arg) == -1) {
		sn->error = TNT_EMEMORY;
		return -1;
	}
	if (tnt_iob_init(&sn->rbuf, sn->opt.recv_buf, sn->opt.recv_cb, NULL, 
		sn->opt.recv_cb_arg) == -1) {
		sn->error = TNT_EMEMORY;
		return -1;
	}
	if (sn->opt.hostname == NULL) {
		sn->error = TNT_EBADVAL;
		return -1;
	}
	if (sn->opt.port == 0) {
		sn->error = TNT_EBADVAL;
		return -1;
	}
	return 0;
}
示例#14
0
static int
tnt_rpl_request(struct tnt_stream *s, struct tnt_request *r)
{
	struct tnt_stream_rpl *sr = TNT_RPL_CAST(s);
	struct tnt_stream_net *sn = TNT_SNET_CAST(sr->net);
	/* fetching header */
	if (tnt_io_recv(sn, (char*)&sr->hdr, sizeof(sr->hdr)) == -1)
		return -1;
	/* fetching row header */
	if (tnt_io_recv(sn, (char*)&sr->row, sizeof(sr->row)) == -1)
		return -1;
	/* preparing pseudo iproto header */
	struct tnt_header hdr_iproto;
	hdr_iproto.type = sr->row.op;
	hdr_iproto.len = sr->hdr.len - sizeof(struct tnt_log_row_v11);
	hdr_iproto.reqid = 0;
	/* deserializing operation */
	if (tnt_request_from(r, (tnt_request_t)tnt_rpl_recv_cb,
			     sr->net,
			     &hdr_iproto) == -1)
		return -1;
	return 0;
}
示例#15
0
/*
 * tnt_flush()
 *
 * send bufferized data to server;
 *
 * s - network stream pointer
 * 
 * returns size of data been sended on success, or -1 on error.
*/
ssize_t tnt_flush(struct tnt_stream *s) {
	struct tnt_stream_net *sn = TNT_SNET_CAST(s);
	return tnt_io_flush(sn);
}
示例#16
0
static ssize_t
tnt_net_reply_cb(struct tnt_stream *s, char *buf, ssize_t size) {
	struct tnt_stream_net *sn = TNT_SNET_CAST(s);
	return tnt_io_recv(sn, buf, size);
}
示例#17
0
int nb_io_getc(struct tnt_stream *t, char buf[1]) {
    return tnt_io_recv(TNT_SNET_CAST(t), buf, 1);
}
示例#18
0
static ssize_t
tnt_net_read(struct tnt_stream *s, char *buf, size_t size) {
	struct tnt_stream_net *sn = TNT_SNET_CAST(s);
	/* read doesn't touches wrcnt */
	return tnt_io_recv(sn, buf, size);
}
示例#19
0
/*
 * tnt_errno()
 *
 * get saved errno;
 *
 * s - network stream pointer
*/
int tnt_errno(struct tnt_stream *s) {
	struct tnt_stream_net *sn = TNT_SNET_CAST(s);
	return sn->errno_;
}
示例#20
0
/*
 * tnt_close()
 *
 * close connection to server;
 *
 * s - network stream pointer
 * 
 * returns 0 on success, or -1 on error.
*/
void tnt_close(struct tnt_stream *s) {
	struct tnt_stream_net *sn = TNT_SNET_CAST(s);
	tnt_io_close(sn);
}
示例#21
0
/*
 * tnt_error()
 *
 * get library error status;
 *
 * s - network stream pointer
*/
enum tnt_error tnt_error(struct tnt_stream *s) {
	struct tnt_stream_net *sn = TNT_SNET_CAST(s);
	return sn->error;
}
示例#22
0
int
nb_mc_get_recv(struct tnt_stream *t, char **data, int *data_size)
{
	struct tnt_stream_net *sn = TNT_SNET_CAST(t);
	/* VALUE <key> <flags> <bytes> [<cas unique>]\r\n
	 * <data block>\r\n
	 * ...
	 * END\r\n
	*/
	*data = NULL;
	if (nb_io_expect(t, "VALUE ") == -1)
		return -1;
	/* key */
	int key_len = 0;
	char key[128], ch[1];
	for (;; key_len++) {
		if (key_len > (int)sizeof(key)) {
			sn->error = TNT_EBIG;
			goto error;
		}
		if (nb_io_getc(t, ch) == -1)
			goto error;
		if (ch[0] == ' ') {
			key[key_len] = 0;
			break;
		}
		key[key_len] = ch[0];
	}
	/* flags */
	int flags = 0;
	while (1) {
		if (nb_io_getc(t, ch) == -1)
			goto error;
		if (!isdigit(ch[0])) {
			if (ch[0] == ' ')
				break;
			sn->error = TNT_EFAIL;
			goto error;
		}
		flags *= 10;
		flags += ch[0] - 48;
	}
	/* bytes */
	int value_size = 0;
	while (1) {
		if (nb_io_getc(t, ch) == -1)
			goto error;
		if (!isdigit(ch[0])) {
			if (ch[0] == '\r')
				break;
			sn->error = TNT_EFAIL;
			goto error;
		}
		value_size *= 10;
		value_size += ch[0] - 48;
	}
	/* \n */
	if (nb_io_getc(t, ch) == -1)
		goto error;
	/* data */
	*data_size = value_size;
	*data = tnt_mem_alloc(*data_size);
	if (*data == NULL) {
		sn->error = TNT_EMEMORY;
		goto error;
	}
	if (tnt_io_recv(sn, *data, *data_size) == -1)
		goto error;
	if (nb_io_expect(t, "\r\n") == -1)
		goto error;
	if (nb_io_expect(t, "END\r\n") == -1)
		goto error;
	return 0;
error:
	if (*data)
		tnt_mem_free(*data);
	return -1;
}
示例#23
0
/*
 * tnt_fd()
 *
 * get connection socket description;
 *
 * s - network stream pointer
*/
int tnt_fd(struct tnt_stream *s) {
	struct tnt_stream_net *sn = TNT_SNET_CAST(s);
	return sn->fd;
}