Example #1
0
File: net.c Project: aido/picocoin
static void nc_conn_write_evt(int fd, short events, void *priv)
{
	struct nc_conn *conn = priv;
	struct iovec *iov = NULL;
	unsigned int iov_len = 0;

	/* build list of outgoing data buffers */
	nc_conn_build_iov(conn->write_q, conn->write_partial, &iov, &iov_len);

	/* send data to network */
	ssize_t wrc = writev(conn->fd, iov, iov_len);

	free(iov);

	if (wrc < 0) {
		if (errno != EAGAIN && errno != EWOULDBLOCK)
			goto err_out;
		return;
	}

	/* handle partially and fully completed buffers */
	nc_conn_written(conn, wrc);

	/* thaw read, if write fully drained */
	if (!conn->write_q) {
		nc_conn_write_disable(conn);
		nc_conn_read_enable(conn);
	}

	return;

err_out:
	nc_conn_kill(conn);
}
Example #2
0
/*  connection begins */
static void nc_conn_evt_connected(int fd, short events, void *priv)
{
	struct nc_conn *conn = priv;

	if ((events & EV_WRITE) == 0) {
		fprintf(plog, "net: %s connection timeout\n", conn->addr_str);
		goto err_out;
	}

	int err = 0;
	socklen_t len = sizeof(err);

	/* check success of connect(2) */
	if ((getsockopt(conn->fd, SOL_SOCKET, SO_ERROR, &err, &len) < 0) ||
	    (err != 0)) {
		fprintf(plog, "net: connect %s failed: %s\n",
			conn->addr_str, strerror(err));
		goto err_out;
	}

	if (debugging)
		fprintf(plog, "net: connected to %s\n", conn->addr_str);

	conn->connected = true;

	/* clear event used for watching connect(2) */
	event_free(conn->ev);
	conn->ev = NULL;

	/* build and send "version" message */

	cstring *msg_data = nc_version_build(conn);
	bool rc = nc_conn_send(conn, "version", msg_data->str, msg_data->len);
	cstr_free(msg_data, true);

	if (!rc) {
		fprintf(plog, "net: %s !conn_send\n", conn->addr_str);
		goto err_out;
	}

	/* switch to read-header state */
	conn->msg_p = conn->hdrbuf;
	/* from message.c #define P2P_HDR_SZ	(4 + 12 + 4 + 4)*/
	conn->expected = P2P_HDR_SZ;
	conn->reading_hdr = true;

	if (!nc_conn_read_enable(conn)) {
		fprintf(plog, "net: %s read not enabled\n", conn->addr_str);
		goto err_out;
	}

	return;

err_out:
	nc_conn_kill(conn);
}