17static int pump_refill(pc_relay_end *src, pc_relay_end *dst, uint8_t *buf, uint16_t *len, uint16_t *off,
bool *src_eof,
29 int s = dst->send(dst->ctx, buf, *len);
35 *counter += (uint32_t)s;
43static int pump(pc_relay_end *src, pc_relay_end *dst, uint8_t *buf, uint16_t *len, uint16_t *off,
bool *src_eof,
44 bool *dir_done,
bool *dst_shut_sent, uint32_t *counter)
54 int s = dst->send(dst->ctx, buf + *off, (
size_t)(*len - *off));
59 *off = (uint16_t)(*off + s);
60 *counter += (uint32_t)s;
69 if (!*src_eof && pump_refill(src, dst, buf, len, off, src_eof, counter) < 0)
76 if (*src_eof && *off >= *len)
86 if (dst->shutdown && !*dst_shut_sent)
88 dst->shutdown(dst->ctx);
89 *dst_shut_sent =
true;
95void pc_relay_init(pc_relay *r,
const pc_relay_end *client,
const pc_relay_end *origin)
97 if (!r || !client || !origin)
101 memset(r, 0,
sizeof(*r));
106pc_relay_status pc_relay_step(pc_relay *r)
110 return pc_relay_status::PC_RELAY_ERROR;
113 if (pump(&r->a, &r->b, r->buf_a2b, &r->a2b_len, &r->a2b_off, &r->a_eof, &r->a2b_done, &r->b_shut_sent,
116 return pc_relay_status::PC_RELAY_ERROR;
119 if (pump(&r->b, &r->a, r->buf_b2a, &r->b2a_len, &r->b2a_off, &r->b_eof, &r->b2a_done, &r->a_shut_sent,
122 return pc_relay_status::PC_RELAY_ERROR;
125 return (r->a2b_done && r->b2a_done) ? pc_relay_status::PC_RELAY_DONE : pc_relay_status::PC_RELAY_RUNNING;
128void pc_relay_note_eof(pc_relay *r,
bool origin)
#define PC_RELAY_BUF
Per-direction relay buffer size (bytes) for services/net/relay (PC_ENABLE_RELAY).
TCP relay / DNAT port forwarding (PC_ENABLE_RELAY) - a bidirectional byte pump.