/* * Dispatch function for forwarding data between the two socket fds involved * in the proxied connection. */ static int proxy_connection_io_dispatch (struct proxy_connection *pc, const int rwflags, struct event_set *es) { const int max_transfer_per_iteration = 10000; struct proxy_connection *cp = pc->counterpart; int rwflags_pc = pc->rwflags; int rwflags_cp = cp->rwflags; ASSERT(pc->defined && cp->defined && cp->counterpart == pc); if (rwflags & EVENT_READ) { const int status = proxy_connection_io_xfer (pc, max_transfer_per_iteration); if (!proxy_connection_io_status (status, &rwflags_pc, &rwflags_cp)) goto bad; } if (rwflags & EVENT_WRITE) { const int status = proxy_connection_io_xfer (cp, max_transfer_per_iteration); if (!proxy_connection_io_status (status, &rwflags_cp, &rwflags_pc)) goto bad; } proxy_connection_io_requeue (pc, rwflags_pc, es); proxy_connection_io_requeue (cp, rwflags_cp, es); return true; bad: proxy_entry_mark_for_close (pc, es); return false; }
/* * Cleanup function, on proxy process exit. */ static void proxy_list_close (struct proxy_connection **list) { if (list) { struct proxy_connection *pc = *list; while (pc) { proxy_entry_mark_for_close (pc, NULL); pc = pc->next; } proxy_list_housekeeping (list); } }
/* * Mark a proxy entry and its counterpart for close. */ static void proxy_entry_mark_for_close (struct proxy_connection *pc, struct event_set *es) { if (pc->defined) { struct proxy_connection *cp = pc->counterpart; proxy_entry_close_sd (pc, es); free_buf (&pc->buf); pc->buffer_initial = false; pc->rwflags = 0; pc->defined = false; if (cp && cp->defined && cp->counterpart == pc) proxy_entry_mark_for_close (cp, es); } }