|
|
|
@ -51,7 +51,6 @@ static int tcp_proxy_client_send_data(struct tcp_proxy_client_conn* pc, const |
|
|
|
static void tcp_proxy_client_tx_queue_drain_cb(struct ll_queue* q, void* arg); |
|
|
|
static void tcp_proxy_client_tx_queue_drain_cb(struct ll_queue* q, void* arg); |
|
|
|
static void tcp_proxy_client_pause_resume_cb(struct ll_queue* q, void* arg); |
|
|
|
static void tcp_proxy_client_pause_resume_cb(struct ll_queue* q, void* arg); |
|
|
|
static void tcp_proxy_client_retry_timer_cb(void* arg); |
|
|
|
static void tcp_proxy_client_retry_timer_cb(void* arg); |
|
|
|
static void tcp_proxy_client_diag_timer_cb(void* arg); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ====================================================================
|
|
|
|
// ====================================================================
|
|
|
|
// Помощник ll_entry
|
|
|
|
// Помощник ll_entry
|
|
|
|
@ -216,6 +215,7 @@ static err_t tcp_proxy_client_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t |
|
|
|
struct tcp_proxy_client_conn *pc = u_calloc(1, sizeof(struct tcp_proxy_client_conn)); |
|
|
|
struct tcp_proxy_client_conn *pc = u_calloc(1, sizeof(struct tcp_proxy_client_conn)); |
|
|
|
if (!pc) { DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "TCP proxy client: accept alloc failed"); return LERR_MEM; } |
|
|
|
if (!pc) { DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "TCP proxy client: accept alloc failed"); return LERR_MEM; } |
|
|
|
pc->proxy = p; pc->pcb = newpcb; pc->stream_id = ++p->next_stream_id; |
|
|
|
pc->proxy = p; pc->pcb = newpcb; pc->stream_id = ++p->next_stream_id; |
|
|
|
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "PROXY ACCEPT pcb=%p sid=%08x", (void*)newpcb, pc->stream_id); |
|
|
|
proxy_flow_init(&pc->flow, p->inst, p->ua, p->via_node_id, ETCP_RT_ID_TCP_PROXY_SERVER, pc->stream_id, tcp_proxy_client_flow_wake, pc); |
|
|
|
proxy_flow_init(&pc->flow, p->inst, p->ua, p->via_node_id, ETCP_RT_ID_TCP_PROXY_SERVER, pc->stream_id, tcp_proxy_client_flow_wake, pc); |
|
|
|
|
|
|
|
|
|
|
|
int i; |
|
|
|
int i; |
|
|
|
@ -251,7 +251,6 @@ static err_t tcp_proxy_client_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t |
|
|
|
if (tcp_proxy_client_send_connect(pc) != 0) { DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "TCP proxy client: send_connect failed sid=%08x to %d.%d.%d.%d:%d", pc->stream_id, pc->dest_ip[0], pc->dest_ip[1], pc->dest_ip[2], pc->dest_ip[3], ntohs(pc->dest_port)); tcp_arg(newpcb, NULL); tcp_abort(newpcb); queue_free(pc->to_lwip); queue_free(pc->tx_queue); u_free(pc); return LERR_ABRT; } |
|
|
|
if (tcp_proxy_client_send_connect(pc) != 0) { DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "TCP proxy client: send_connect failed sid=%08x to %d.%d.%d.%d:%d", pc->stream_id, pc->dest_ip[0], pc->dest_ip[1], pc->dest_ip[2], pc->dest_ip[3], ntohs(pc->dest_port)); tcp_arg(newpcb, NULL); tcp_abort(newpcb); queue_free(pc->to_lwip); queue_free(pc->tx_queue); u_free(pc); return LERR_ABRT; } |
|
|
|
|
|
|
|
|
|
|
|
pc->next = p->conns; p->conns = pc; p->conn_count++; |
|
|
|
pc->next = p->conns; p->conns = pc; p->conn_count++; |
|
|
|
pc->diag_timer = uasync_set_timeout(p->ua, 5000, pc, tcp_proxy_client_diag_timer_cb, "tpc_diag"); |
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_PROXY, "TCP proxy client: new conn sid=%08x local_port=%u -> %d.%d.%d.%d:%d total_conns=%d snd_wnd=%u mss=%u", |
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_PROXY, "TCP proxy client: new conn sid=%08x local_port=%u -> %d.%d.%d.%d:%d total_conns=%d snd_wnd=%u mss=%u", |
|
|
|
pc->stream_id, newpcb->local_port, pc->dest_ip[0], pc->dest_ip[1], pc->dest_ip[2], pc->dest_ip[3], ntohs(pc->dest_port), p->conn_count, newpcb->snd_wnd, newpcb->mss); |
|
|
|
pc->stream_id, newpcb->local_port, pc->dest_ip[0], pc->dest_ip[1], pc->dest_ip[2], pc->dest_ip[3], ntohs(pc->dest_port), p->conn_count, newpcb->snd_wnd, newpcb->mss); |
|
|
|
return LERR_OK; |
|
|
|
return LERR_OK; |
|
|
|
@ -344,28 +343,6 @@ static void tcp_proxy_client_retry_timer_cb(void* arg) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static void tcp_proxy_client_diag_timer_cb(void* arg) { |
|
|
|
|
|
|
|
struct tcp_proxy_client_conn* pc = (struct tcp_proxy_client_conn*)arg; |
|
|
|
|
|
|
|
if (!pc || !pc->proxy) return; |
|
|
|
|
|
|
|
pc->diag_timer = NULL; |
|
|
|
|
|
|
|
if (pc->rem_closed) return; |
|
|
|
|
|
|
|
struct tcp_pcb* pcb = pc->pcb; |
|
|
|
|
|
|
|
if (!pcb || pcb->state == CLOSED) return; |
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, |
|
|
|
|
|
|
|
"PROXY DIAG sid=%08x st=%s fin_l=%d fin_r=%d " |
|
|
|
|
|
|
|
"rcv_wnd=%u rcv_ann=%u snd_wnd=%u snd_buf=%u cwnd=%u " |
|
|
|
|
|
|
|
"unsent=%d unacked=%d ooseq=%d " |
|
|
|
|
|
|
|
"tx_q=%d to_lwip=%d to_exit=%u from_exit=%u bp=%u err=%d rem_closed=%d", |
|
|
|
|
|
|
|
pc->stream_id, tcp_debug_state_str(pcb->state), |
|
|
|
|
|
|
|
pc->fin_local, pc->fin_remote, |
|
|
|
|
|
|
|
pcb->rcv_wnd, pcb->rcv_ann_wnd, pcb->snd_wnd, (unsigned)tcp_sndbuf(pcb), pcb->cwnd, |
|
|
|
|
|
|
|
tcp_seg_count(pcb->unsent), tcp_seg_count(pcb->unacked), tcp_seg_count(pcb->ooseq), |
|
|
|
|
|
|
|
pc->tx_queue ? queue_entry_count(pc->tx_queue) : -1, |
|
|
|
|
|
|
|
pc->to_lwip ? queue_entry_count(pc->to_lwip) : -1, |
|
|
|
|
|
|
|
pc->bytes_to_exit, pc->bytes_from_exit, pc->bp_count, pc->error, pc->rem_closed); |
|
|
|
|
|
|
|
pc->diag_timer = uasync_set_timeout(pc->proxy->ua, 5000, pc, tcp_proxy_client_diag_timer_cb, "tpc_diag"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static err_t tcp_proxy_client_recv_cb(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { |
|
|
|
static err_t tcp_proxy_client_recv_cb(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { |
|
|
|
struct tcp_proxy_client_conn *pc = (struct tcp_proxy_client_conn *)arg; |
|
|
|
struct tcp_proxy_client_conn *pc = (struct tcp_proxy_client_conn *)arg; |
|
|
|
if (!pc || !pc->proxy || pc->rem_closed) { if (p) pbuf_free(p); return LERR_OK; } |
|
|
|
if (!pc || !pc->proxy || pc->rem_closed) { if (p) pbuf_free(p); return LERR_OK; } |
|
|
|
@ -426,6 +403,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) { |
|
|
|
static void tcp_proxy_client_err_cb(void *arg, err_t err) { |
|
|
|
struct tcp_proxy_client_conn *pc = (struct tcp_proxy_client_conn *)arg; |
|
|
|
struct tcp_proxy_client_conn *pc = (struct tcp_proxy_client_conn *)arg; |
|
|
|
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "PROXY ERR_CB pc=%p pcb=%p sid=%08x err=%d rem_closed=%d", |
|
|
|
|
|
|
|
(void*)pc, (void*)(pc ? pc->pcb : NULL), pc ? pc->stream_id : 0, err, pc ? pc->rem_closed : 0); |
|
|
|
if (!pc || !pc->proxy || pc->rem_closed) { DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "PROXY tcp_proxy_client_err_cb: pc=%p proxy=%p rem_closed=%d err=%d", (void*)pc, pc ? (void*)pc->proxy : NULL, pc ? pc->rem_closed : 0, err); return; } |
|
|
|
if (!pc || !pc->proxy || pc->rem_closed) { DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "PROXY tcp_proxy_client_err_cb: pc=%p proxy=%p rem_closed=%d err=%d", (void*)pc, pc ? (void*)pc->proxy : NULL, pc ? pc->rem_closed : 0, err); return; } |
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "TCP proxy client: error %d sid=%08x fin_local=%d rem_closed=%d", |
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "TCP proxy client: error %d sid=%08x fin_local=%d rem_closed=%d", |
|
|
|
err, pc->stream_id, pc->fin_local, pc->rem_closed); |
|
|
|
err, pc->stream_id, pc->fin_local, pc->rem_closed); |
|
|
|
@ -444,6 +423,8 @@ static err_t tcp_proxy_client_poll_cb(void *arg, struct tcp_pcb *pcb) { |
|
|
|
if (pc->error) { |
|
|
|
if (pc->error) { |
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "PROXY CLEANUP error sid=%08x", pc->stream_id); |
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "PROXY CLEANUP error sid=%08x", pc->stream_id); |
|
|
|
if (pc->pcb) { |
|
|
|
if (pc->pcb) { |
|
|
|
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "PROXY POLL_ABORT pcb=%p state=%s sid=%08x", |
|
|
|
|
|
|
|
(void*)pc->pcb, tcp_debug_state_str(pc->pcb->state), pc->stream_id); |
|
|
|
tcp_arg(pc->pcb, NULL); |
|
|
|
tcp_arg(pc->pcb, NULL); |
|
|
|
tcp_recv(pc->pcb, NULL); |
|
|
|
tcp_recv(pc->pcb, NULL); |
|
|
|
tcp_sent(pc->pcb, NULL); |
|
|
|
tcp_sent(pc->pcb, NULL); |
|
|
|
@ -526,6 +507,7 @@ static void tcp_proxy_client_conn_free(struct tcp_proxy_client_conn *pc) { |
|
|
|
if (!pc) return; |
|
|
|
if (!pc) return; |
|
|
|
struct tcp_proxy_client *p = pc->proxy; |
|
|
|
struct tcp_proxy_client *p = pc->proxy; |
|
|
|
proxy_flow_destroy(&pc->flow); |
|
|
|
proxy_flow_destroy(&pc->flow); |
|
|
|
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "PROXY FREE pcb=%p sid=%08x", (void*)pc->pcb, pc->stream_id); |
|
|
|
uint32_t pending = pc->to_lwip ? queue_entry_count(pc->to_lwip) : 0; |
|
|
|
uint32_t pending = pc->to_lwip ? queue_entry_count(pc->to_lwip) : 0; |
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_PROXY, "PROXY FREE sid=%08x total_conns=%d to_lwip_q=%u", |
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_PROXY, "PROXY FREE sid=%08x total_conns=%d to_lwip_q=%u", |
|
|
|
pc->stream_id, p->conn_count, pending); |
|
|
|
pc->stream_id, p->conn_count, pending); |
|
|
|
@ -547,7 +529,6 @@ static void tcp_proxy_client_conn_free(struct tcp_proxy_client_conn *pc) { |
|
|
|
queue_free(pc->tx_queue); pc->tx_queue = NULL; |
|
|
|
queue_free(pc->tx_queue); pc->tx_queue = NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
if (pc->tx_retry_timer) { uasync_cancel_timeout(p->ua, pc->tx_retry_timer); pc->tx_retry_timer = NULL; } |
|
|
|
if (pc->tx_retry_timer) { uasync_cancel_timeout(p->ua, pc->tx_retry_timer); pc->tx_retry_timer = NULL; } |
|
|
|
if (pc->diag_timer) { uasync_cancel_timeout(p->ua, pc->diag_timer); pc->diag_timer = NULL; } |
|
|
|
|
|
|
|
if (p && p->inst) etcp_router_cancel_send_ready(p->inst, TOPO_GROUP_UTUN, p->via_node_id, ETCP_RT_ID_TCP_PROXY_SERVER, &pc->tx_waiter); |
|
|
|
if (p && p->inst) etcp_router_cancel_send_ready(p->inst, TOPO_GROUP_UTUN, p->via_node_id, ETCP_RT_ID_TCP_PROXY_SERVER, &pc->tx_waiter); |
|
|
|
u_free(pc); |
|
|
|
u_free(pc); |
|
|
|
} |
|
|
|
} |
|
|
|
@ -558,6 +539,8 @@ static void tcp_proxy_client_conn_free(struct tcp_proxy_client_conn *pc) { |
|
|
|
static void tcp_proxy_client_conn_finish(struct tcp_proxy_client_conn *pc) { |
|
|
|
static void tcp_proxy_client_conn_finish(struct tcp_proxy_client_conn *pc) { |
|
|
|
if (!pc) return; |
|
|
|
if (!pc) return; |
|
|
|
if (pc->pcb) { |
|
|
|
if (pc->pcb) { |
|
|
|
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "PROXY FINISH pcb=%p state=%s sid=%08x", |
|
|
|
|
|
|
|
(void*)pc->pcb, tcp_debug_state_str(pc->pcb->state), pc->stream_id); |
|
|
|
tcp_arg(pc->pcb, NULL); |
|
|
|
tcp_arg(pc->pcb, NULL); |
|
|
|
tcp_recv(pc->pcb, NULL); |
|
|
|
tcp_recv(pc->pcb, NULL); |
|
|
|
tcp_sent(pc->pcb, NULL); |
|
|
|
tcp_sent(pc->pcb, NULL); |
|
|
|
@ -592,7 +575,7 @@ static void tcp_proxy_client_handle_data(struct tcp_proxy_client* p, struct ETCP |
|
|
|
if (e) { queue_dgram_free(e); queue_entry_free(e); } |
|
|
|
if (e) { queue_dgram_free(e); queue_entry_free(e); } |
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "proxy: receive failed sid=%08x", stream_id); |
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "proxy: receive failed sid=%08x", stream_id); |
|
|
|
tcp_proxy_client_send_error(pc); |
|
|
|
tcp_proxy_client_send_error(pc); |
|
|
|
if (pc->pcb) { tcp_arg(pc->pcb, NULL); tcp_err(pc->pcb, NULL); tcp_abort(pc->pcb); pc->pcb = NULL; } |
|
|
|
if (pc->pcb) { DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "PROXY DATA_ABORT pcb=%p state=%s sid=%08x", (void*)pc->pcb, tcp_debug_state_str(pc->pcb->state), stream_id); tcp_arg(pc->pcb, NULL); tcp_err(pc->pcb, NULL); tcp_abort(pc->pcb); pc->pcb = NULL; } |
|
|
|
tcp_proxy_client_conn_free(pc); |
|
|
|
tcp_proxy_client_conn_free(pc); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
queue_data_put(pc->to_lwip, e); |
|
|
|
queue_data_put(pc->to_lwip, e); |
|
|
|
@ -608,6 +591,8 @@ static void tcp_proxy_client_handle_close(struct tcp_proxy_client* p, uint32_t s |
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_PROXY, "PROXY REM_CLOSED sid=%08x fin_local=%d pcb_state=%u", stream_id, pc->fin_local, pc->pcb ? pc->pcb->state : 0); |
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_PROXY, "PROXY REM_CLOSED sid=%08x fin_local=%d pcb_state=%u", stream_id, pc->fin_local, pc->pcb ? pc->pcb->state : 0); |
|
|
|
pc->rem_closed = 1; |
|
|
|
pc->rem_closed = 1; |
|
|
|
if (pc->pcb) { |
|
|
|
if (pc->pcb) { |
|
|
|
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "PROXY CLOSE pcb=%p state=%s sid=%08x", |
|
|
|
|
|
|
|
(void*)pc->pcb, tcp_debug_state_str(pc->pcb->state), stream_id); |
|
|
|
tcp_arg(pc->pcb, NULL); |
|
|
|
tcp_arg(pc->pcb, NULL); |
|
|
|
tcp_recv(pc->pcb, NULL); |
|
|
|
tcp_recv(pc->pcb, NULL); |
|
|
|
tcp_sent(pc->pcb, NULL); |
|
|
|
tcp_sent(pc->pcb, NULL); |
|
|
|
@ -624,6 +609,8 @@ static void tcp_proxy_client_handle_error(struct tcp_proxy_client* p, uint32_t s |
|
|
|
if (!pc) { DEBUG_INFO(DEBUG_CATEGORY_PROXY, "PROXY ERROR sid=%08x — no conn, dropping", stream_id); return; } |
|
|
|
if (!pc) { DEBUG_INFO(DEBUG_CATEGORY_PROXY, "PROXY ERROR sid=%08x — no conn, dropping", stream_id); return; } |
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "PROXY ERROR from exit sid=%08x fin_local=%d", stream_id, pc->fin_local); |
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "PROXY ERROR from exit sid=%08x fin_local=%d", stream_id, pc->fin_local); |
|
|
|
if (pc->pcb) { |
|
|
|
if (pc->pcb) { |
|
|
|
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "PROXY ERROR pcb=%p state=%s sid=%08x", |
|
|
|
|
|
|
|
(void*)pc->pcb, tcp_debug_state_str(pc->pcb->state), stream_id); |
|
|
|
tcp_arg(pc->pcb, NULL); |
|
|
|
tcp_arg(pc->pcb, NULL); |
|
|
|
tcp_recv(pc->pcb, NULL); |
|
|
|
tcp_recv(pc->pcb, NULL); |
|
|
|
tcp_sent(pc->pcb, NULL); |
|
|
|
tcp_sent(pc->pcb, NULL); |
|
|
|
@ -678,6 +665,8 @@ void tcp_proxy_client_router_recv_cb(struct ETCP_CONN* conn, struct ll_entry* en |
|
|
|
for (pc = proxy->conns; pc; pc = next) { |
|
|
|
for (pc = proxy->conns; pc; pc = next) { |
|
|
|
next = pc->next; |
|
|
|
next = pc->next; |
|
|
|
if (pc->pcb) { |
|
|
|
if (pc->pcb) { |
|
|
|
|
|
|
|
DEBUG_DEBUG(DEBUG_CATEGORY_DEBUG, "PROXY CLOSE_ALL pcb=%p state=%s sid=%08x", |
|
|
|
|
|
|
|
(void*)pc->pcb, tcp_debug_state_str(pc->pcb->state), pc->stream_id); |
|
|
|
tcp_arg(pc->pcb, NULL); |
|
|
|
tcp_arg(pc->pcb, NULL); |
|
|
|
tcp_recv(pc->pcb, NULL); |
|
|
|
tcp_recv(pc->pcb, NULL); |
|
|
|
tcp_sent(pc->pcb, NULL); |
|
|
|
tcp_sent(pc->pcb, NULL); |
|
|
|
@ -854,7 +843,6 @@ void tcp_proxy_client_destroy(struct tcp_proxy_client* p) { |
|
|
|
queue_free(pc->tx_queue); pc->tx_queue = NULL; |
|
|
|
queue_free(pc->tx_queue); pc->tx_queue = NULL; |
|
|
|
} |
|
|
|
} |
|
|
|
if (pc->tx_retry_timer) { uasync_cancel_timeout(p->ua, pc->tx_retry_timer); pc->tx_retry_timer = NULL; } |
|
|
|
if (pc->tx_retry_timer) { uasync_cancel_timeout(p->ua, pc->tx_retry_timer); pc->tx_retry_timer = NULL; } |
|
|
|
if (pc->diag_timer) { uasync_cancel_timeout(p->ua, pc->diag_timer); pc->diag_timer = NULL; } |
|
|
|
|
|
|
|
if (p->inst) etcp_router_cancel_send_ready(p->inst, TOPO_GROUP_UTUN, p->via_node_id, ETCP_RT_ID_TCP_PROXY_SERVER, &pc->tx_waiter); |
|
|
|
if (p->inst) etcp_router_cancel_send_ready(p->inst, TOPO_GROUP_UTUN, p->via_node_id, ETCP_RT_ID_TCP_PROXY_SERVER, &pc->tx_waiter); |
|
|
|
u_free(pc); pc = next; |
|
|
|
u_free(pc); pc = next; |
|
|
|
} |
|
|
|
} |
|
|
|
|