|
|
|
|
@ -93,13 +93,21 @@ static int send_data(struct proxy_conn* pc, const uint8_t* data, uint16_t len) {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int send_close(struct proxy_conn* pc) { |
|
|
|
|
return proxy_send_msg(pc->proxy->inst, pc->proxy->via_node_id, |
|
|
|
|
TCP_PROXY_SUBCMD_CLOSE, pc->stream_id, NULL, 0); |
|
|
|
|
int ret = proxy_send_msg(pc->proxy->inst, pc->proxy->via_node_id, |
|
|
|
|
TCP_PROXY_SUBCMD_CLOSE, pc->stream_id, NULL, 0); |
|
|
|
|
if (ret < 0) { pc->close_pending = 1; return -1; } |
|
|
|
|
pc->close_pending = 0; |
|
|
|
|
pc->close_sent = 1; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int send_error(struct proxy_conn* pc) { |
|
|
|
|
return proxy_send_msg(pc->proxy->inst, pc->proxy->via_node_id, |
|
|
|
|
TCP_PROXY_SUBCMD_ERROR, pc->stream_id, NULL, 0); |
|
|
|
|
int ret = proxy_send_msg(pc->proxy->inst, pc->proxy->via_node_id, |
|
|
|
|
TCP_PROXY_SUBCMD_ERROR, pc->stream_id, NULL, 0); |
|
|
|
|
if (ret < 0) { pc->close_pending = 1; return -1; } |
|
|
|
|
pc->close_pending = 0; |
|
|
|
|
pc->close_sent = 1; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ====================================================================
|
|
|
|
|
@ -238,9 +246,8 @@ static err_t proxy_recv_cb(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t
|
|
|
|
|
{ uint16_t wnd_gap = TCP_WND_MAX(pcb) - pcb->rcv_wnd; |
|
|
|
|
if (wnd_gap > 0) tcp_recved(pcb, wnd_gap); } |
|
|
|
|
pc->tun_closed = 1; |
|
|
|
|
if (!pc->close_sent) { |
|
|
|
|
if (!pc->close_sent && !pc->close_pending) { |
|
|
|
|
if (send_close(pc) < 0) DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "PROXY FIN send_close failed sid=%08x", pc->stream_id); |
|
|
|
|
pc->close_sent = 1; |
|
|
|
|
} |
|
|
|
|
return LERR_OK; |
|
|
|
|
} |
|
|
|
|
@ -276,7 +283,6 @@ static void proxy_err_cb(void *arg, err_t err) {
|
|
|
|
|
err, pc->stream_id, pc->pcb ? pc->pcb->state : 0, pc->tun_closed, pc->rem_closed, pc->connected); |
|
|
|
|
pc->error = 1; |
|
|
|
|
if (send_error(pc) < 0) DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "PROXY send_error failed sid=%08x", pc->stream_id); |
|
|
|
|
pc->close_sent = 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static err_t proxy_poll_cb(void *arg, struct tcp_pcb *pcb) { |
|
|
|
|
@ -290,6 +296,12 @@ static err_t proxy_poll_cb(void *arg, struct tcp_pcb *pcb) {
|
|
|
|
|
return LERR_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* Retry pending CLOSE/ERROR if previous send failed */ |
|
|
|
|
if (pc->close_pending) { |
|
|
|
|
if (pc->error) send_error(pc); |
|
|
|
|
else send_close(pc); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (pc->tun_closed && pc->rem_closed && pc->pcb) { |
|
|
|
|
uint32_t pending = pc->to_lwip ? queue_entry_count(pc->to_lwip) : 0; |
|
|
|
|
int done = (pending == 0 && pcb->unsent == NULL && pcb->unacked == NULL); |
|
|
|
|
|