|
|
|
|
@ -173,7 +173,8 @@ static int tcp_proxy_client_handle_non_tcp(struct tcp_proxy_client* p, uint8_t*
|
|
|
|
|
// Помощник: передача данных из очереди to_lwip в lwIP TCP
|
|
|
|
|
// ====================================================================
|
|
|
|
|
static void tcp_proxy_client_feed_from_transport(struct tcp_proxy_client_conn *pc) { |
|
|
|
|
if (!pc->to_lwip || !pc->pcb || pc->tun_closed) return; |
|
|
|
|
if (!pc->to_lwip || !pc->pcb) return; |
|
|
|
|
if (pc->rem_closed) return; |
|
|
|
|
int sent_any = 0; |
|
|
|
|
uint32_t q_pre = queue_entry_count(pc->to_lwip); |
|
|
|
|
while (1) { |
|
|
|
|
@ -254,8 +255,12 @@ static void tcp_proxy_client_tx_waiter_cb(struct ll_queue* q, void* arg) {
|
|
|
|
|
if (ret == 0) { |
|
|
|
|
tcp_recved(pc->pcb, pc->tx_len); |
|
|
|
|
u_free(pc->tx_buf); pc->tx_buf = NULL; pc->tx_len = 0; |
|
|
|
|
if (pc->tun_closed && !pc->close_sent && !pc->close_pending) |
|
|
|
|
tcp_proxy_client_send_fin(pc); |
|
|
|
|
if (pc->fin_local && !pc->close_sent && !pc->close_pending) { |
|
|
|
|
if (pc->fin_remote || pc->rem_closed) |
|
|
|
|
tcp_proxy_client_send_close(pc); |
|
|
|
|
else |
|
|
|
|
tcp_proxy_client_send_fin(pc); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -264,13 +269,24 @@ static err_t tcp_proxy_client_recv_cb(void *arg, struct tcp_pcb *pcb, struct pbu
|
|
|
|
|
if (!pc) { if (p) pbuf_free(p); return LERR_OK; } |
|
|
|
|
|
|
|
|
|
if (p == NULL || err != LERR_OK) { |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY FIN sid=%08x pcb_state=%u sndbuf=%u cwnd=%u unsent=%p unacked=%p", |
|
|
|
|
pc->stream_id, pcb->state, pcb->snd_buf, pcb->cwnd, |
|
|
|
|
(void*)pcb->unsent, (void*)pcb->unacked); |
|
|
|
|
{ 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->tx_buf) tcp_proxy_client_send_fin(pc); |
|
|
|
|
pc->fin_local = 1; |
|
|
|
|
if (p == NULL && err == ERR_OK) { |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY FIN sid=%08x pcb_state=%u sndbuf=%u cwnd=%u unsent=%p unacked=%p", |
|
|
|
|
pc->stream_id, pcb->state, pcb->snd_buf, pcb->cwnd, |
|
|
|
|
(void*)pcb->unsent, (void*)pcb->unacked); |
|
|
|
|
{ uint16_t wnd_gap = TCP_WND_MAX(pcb) - pcb->rcv_wnd; |
|
|
|
|
if (wnd_gap > 0) tcp_recved(pcb, wnd_gap); } |
|
|
|
|
if (!pc->tx_buf) { |
|
|
|
|
tcp_proxy_client_send_fin(pc); |
|
|
|
|
if (pc->fin_remote && !pc->close_sent && !pc->close_pending) |
|
|
|
|
tcp_proxy_client_send_close(pc); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "PROXY ERROR recv sid=%08x pcb_state=%u err=%d", |
|
|
|
|
pc->stream_id, pcb->state, err); |
|
|
|
|
pc->error = 1; |
|
|
|
|
tcp_proxy_client_send_error(pc); |
|
|
|
|
} |
|
|
|
|
return LERR_OK; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -308,8 +324,8 @@ static err_t tcp_proxy_client_sent_cb(void *arg, struct tcp_pcb *pcb, uint16_t l
|
|
|
|
|
static void tcp_proxy_client_err_cb(void *arg, err_t err) { |
|
|
|
|
struct tcp_proxy_client_conn *pc = (struct tcp_proxy_client_conn *)arg; |
|
|
|
|
if (!pc) { DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "PROXY tcp_proxy_client_err_cb: pc=NULL err=%d", err); return; } |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "TCP proxy client: error %d sid=%08x pcb_state=%u tun_closed=%d rem_closed=%d", |
|
|
|
|
err, pc->stream_id, pc->pcb ? pc->pcb->state : 0, pc->tun_closed, pc->rem_closed); |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "TCP proxy client: error %d sid=%08x pcb_state=%u fin_local=%d rem_closed=%d", |
|
|
|
|
err, pc->stream_id, pc->pcb ? pc->pcb->state : 0, pc->fin_local, pc->rem_closed); |
|
|
|
|
pc->error = 1; |
|
|
|
|
if (tcp_proxy_client_send_error(pc) < 0) DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "PROXY send_error failed sid=%08x", pc->stream_id); |
|
|
|
|
} |
|
|
|
|
@ -417,7 +433,7 @@ static struct tcp_proxy_client_conn* tcp_proxy_client_find_conn(struct tcp_proxy
|
|
|
|
|
|
|
|
|
|
static void tcp_proxy_client_handle_data(struct tcp_proxy_client* p, struct ETCP_CONN* conn, uint32_t stream_id, struct ll_entry* entry) { |
|
|
|
|
struct tcp_proxy_client_conn* pc = tcp_proxy_client_find_conn(p, stream_id); |
|
|
|
|
if (!pc || pc->rem_closed || pc->error || pc->tun_closed) { |
|
|
|
|
if (!pc || pc->rem_closed || pc->error) { |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY DATA sid=%08x — no conn/closed, dropping", stream_id); |
|
|
|
|
queue_dgram_free(entry); queue_entry_free(entry); return; |
|
|
|
|
} |
|
|
|
|
@ -434,7 +450,7 @@ static void tcp_proxy_client_handle_data(struct tcp_proxy_client* p, struct ETCP
|
|
|
|
|
static void tcp_proxy_client_handle_close(struct tcp_proxy_client* p, uint32_t stream_id) { |
|
|
|
|
struct tcp_proxy_client_conn* pc = tcp_proxy_client_find_conn(p, stream_id); |
|
|
|
|
if (!pc) { DEBUG_WARN(DEBUG_CATEGORY_SOCKET, "PROXY CLOSE sid=%08x — no conn, dropping", stream_id); return; } |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY REM_CLOSED sid=%08x tun_closed=%d", stream_id, pc->tun_closed); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY REM_CLOSED sid=%08x fin_local=%d", stream_id, pc->fin_local); |
|
|
|
|
pc->rem_closed = 1; |
|
|
|
|
if (pc->tx_buf) { u_free(pc->tx_buf); pc->tx_buf = NULL; pc->tx_len = 0; } |
|
|
|
|
etcp_router_waiter_cancel(pc->proxy->inst, pc->proxy->via_node_id, &pc->tx_waiter); |
|
|
|
|
@ -445,7 +461,7 @@ static void tcp_proxy_client_handle_close(struct tcp_proxy_client* p, uint32_t s
|
|
|
|
|
static void tcp_proxy_client_handle_error(struct tcp_proxy_client* p, uint32_t stream_id) { |
|
|
|
|
struct tcp_proxy_client_conn* pc = tcp_proxy_client_find_conn(p, stream_id); |
|
|
|
|
if (!pc) { DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY ERROR sid=%08x — no conn, dropping", stream_id); return; } |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "PROXY ERROR from exit sid=%08x tun_closed=%d", stream_id, pc->tun_closed); |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "PROXY ERROR from exit sid=%08x fin_local=%d", stream_id, pc->fin_local); |
|
|
|
|
tcp_proxy_client_handle_close(p, stream_id); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -453,7 +469,10 @@ static void tcp_proxy_client_handle_fin(struct tcp_proxy_client* p, uint32_t str
|
|
|
|
|
struct tcp_proxy_client_conn* pc = tcp_proxy_client_find_conn(p, stream_id); |
|
|
|
|
if (!pc || !pc->pcb) return; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "PROXY FIN FROM exit sid=%08x — shutdown read", stream_id); |
|
|
|
|
pc->fin_remote = 1; |
|
|
|
|
tcp_shutdown(pc->pcb, 0, 1); |
|
|
|
|
if (pc->fin_local && !pc->close_sent && !pc->close_pending) |
|
|
|
|
tcp_proxy_client_send_close(pc); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ====================================================================
|
|
|
|
|
|