int trice_conn_debug(struct re_printf *pf, const struct ice_tcpconn *conn)
{
	int err;

	if (!conn)
		return 0;

	err = re_hprintf(pf, "... {%u} [%s|%5s] %J - %J "
			  " (usage = %u) ",
			  conn->compid,
			  conn->active ? "Active" : "Passive",
			  conn->estab ? "ESTAB" : "     ",
			  &conn->laddr, &conn->paddr,
			  mem_nrefs(conn)-1);

	if (conn->shim)
		err |= shim_debug(pf, conn->shim);

	return err;
}
Beispiel #2
0
/**
 * Debug loadable modules
 *
 * @param pf     Print handler for debug output
 * @param unused Unused parameter
 *
 * @return 0 if success, otherwise errorcode
 */
int mod_debug(struct re_printf *pf, void *unused)
{
	struct le *le;
	int err;

	(void)unused;

	err = re_hprintf(pf, "\n--- Modules (%u) ---\n", list_count(&modl));

	for (le = modl.head; le && !err; le = le->next) {
		const struct mod *m = le->data;
		const struct mod_export *me = m->me;

		err = re_hprintf(pf, " %16s type=%-12s ref=%u\n",
				 me->name, me->type, mem_nrefs(m));
	}

	err |= re_hprintf(pf, "\n");

	return err;
}
static void tcp_recv_handler(int flags, void *arg)
{
	struct tcp_conn *tc = arg;
	struct mbuf *mb = NULL;
	bool hlp_estab = false;
	struct le *le;
	ssize_t n;
	int err;
	socklen_t err_len = sizeof(err);

	if (flags & FD_EXCEPT) {
		DEBUG_INFO("recv handler: got FD_EXCEPT on fd=%d\n", tc->fdc);
	}

	/* check for any errors */
	if (-1 == getsockopt(tc->fdc, SOL_SOCKET, SO_ERROR,
			     BUF_CAST &err, &err_len)) {
		DEBUG_WARNING("recv handler: getsockopt: (%m)\n", errno);
		return;
	}

	if (err) {
		conn_close(tc, err);
		return;
	}
#if 0
	if (EINPROGRESS != err && EALREADY != err) {
		DEBUG_WARNING("recv handler: Socket error (%m)\n", err);
		return;
	}
#endif

	if (flags & FD_WRITE) {

		if (tc->connected) {

			uint32_t nrefs;

			mem_ref(tc);

			err = dequeue(tc);

			nrefs = mem_nrefs(tc);
			mem_deref(tc);

			/* check if connection was deref'd from send handler */
			if (nrefs == 1)
				return;

			if (err) {
				conn_close(tc, err);
				return;
			}

			if (!tc->sendq.head && !tc->sendh) {

				err = fd_listen(tc->fdc, FD_READ,
						tcp_recv_handler, tc);
				if (err) {
					conn_close(tc, err);
					return;
				}
			}

			if (flags & FD_READ)
				goto read;

			return;
		}

		tc->connected = true;

		err = fd_listen(tc->fdc, FD_READ, tcp_recv_handler, tc);
		if (err) {
			DEBUG_WARNING("recv handler: fd_listen(): %m\n", err);
			conn_close(tc, err);
			return;
		}

		le = tc->helpers.head;
		while (le) {
			struct tcp_helper *th = le->data;

			le = le->next;

			if (th->estabh(&err, tc->active, th->arg) || err) {
				if (err)
					conn_close(tc, err);
				return;
			}
		}

		if (tc->estabh)
			tc->estabh(tc->arg);

		return;
	}

 read:
	mb = mbuf_alloc(tc->rxsz);
	if (!mb)
		return;

	n = recv(tc->fdc, BUF_CAST mb->buf, mb->size, 0);
	if (0 == n) {
		mem_deref(mb);
		conn_close(tc, 0);
		return;
	}
	else if (n < 0) {
		DEBUG_WARNING("recv handler: recv(): %m\n", errno);
		goto out;
	}

	mb->end = n;

	le = tc->helpers.head;
	while (le) {
		struct tcp_helper *th = le->data;
		bool hdld = false;

		le = le->next;

		if (hlp_estab) {

			hdld |= th->estabh(&err, tc->active, th->arg);
			if (err) {
				conn_close(tc, err);
				goto out;
			}
		}

		if (mb->pos < mb->end) {

		        hdld |= th->recvh(&err, mb, &hlp_estab, th->arg);
			if (err) {
				conn_close(tc, err);
				goto out;
			}
		}

		if (hdld)
			goto out;
	}

	mbuf_trim(mb);

	if (hlp_estab && tc->estabh) {

		uint32_t nrefs;

		mem_ref(tc);

		tc->estabh(tc->arg);

		nrefs = mem_nrefs(tc);
		mem_deref(tc);

		/* check if connection was deref'ed from establish handler */
		if (nrefs == 1)
			goto out;
	}

	if (mb->pos < mb->end && tc->recvh) {
		tc->recvh(mb, tc->arg);
	}

 out:
	mem_deref(mb);
}