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; }
/** * 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); }