|
|
|
|
@ -43,6 +43,7 @@ static err_t tcp_proxy_client_output_cb(void *arg, struct pbuf *p, uint32_t src_
|
|
|
|
|
static void tcp_proxy_client_feed_from_transport(struct tcp_proxy_client_conn *pc); |
|
|
|
|
static struct ll_entry* tcp_proxy_client_entry_from_data(struct memory_pool* pool, const uint8_t* data, uint16_t len); |
|
|
|
|
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 int tcp_proxy_client_send_msg(struct UTUN_INSTANCE* inst, uint64_t group_id, uint64_t dst, uint8_t subcmd, uint32_t sid, const uint8_t* data, size_t len, int force); |
|
|
|
|
static int tcp_proxy_client_send_data(struct tcp_proxy_client_conn* pc, const uint8_t* data, uint16_t len); |
|
|
|
|
static void tcp_proxy_client_tx_waiter_cb(struct ll_queue* q, void* arg); |
|
|
|
|
@ -263,6 +264,7 @@ static void tcp_proxy_client_tx_waiter_cb(struct ll_queue* q, void* arg) {
|
|
|
|
|
else |
|
|
|
|
tcp_proxy_client_send_fin(pc); |
|
|
|
|
} |
|
|
|
|
if (pc->fin_local && pc->fin_remote) tcp_proxy_client_conn_finish(pc); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -282,6 +284,7 @@ static err_t tcp_proxy_client_recv_cb(void *arg, struct tcp_pcb *pcb, struct pbu
|
|
|
|
|
tcp_proxy_client_send_fin(pc); |
|
|
|
|
if (pc->fin_remote && !pc->close_sent && !pc->close_pending) |
|
|
|
|
tcp_proxy_client_send_close(pc); |
|
|
|
|
if (pc->fin_remote) { tcp_proxy_client_conn_finish(pc); return LERR_OK; } |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "PROXY ERROR recv sid=%08x pcb_state=%u err=%d", |
|
|
|
|
@ -326,9 +329,13 @@ 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 || !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 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->pcb = NULL;// pcb уже уничтожен стеком lwip
|
|
|
|
|
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); |
|
|
|
|
pc->pcb = NULL; // pcb уже освобождён (или вот-вот) стеком lwip — не разыменовывать
|
|
|
|
|
if (err == LERR_CLSD) { // graceful close активной стороной — ERROR слать не нужно
|
|
|
|
|
tcp_proxy_client_conn_free(pc); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
pc->error = 1; |
|
|
|
|
if (tcp_proxy_client_send_error(pc) < 0) DEBUG_ERROR(DEBUG_CATEGORY_PROXY, "PROXY send_error failed sid=%08x", pc->stream_id); |
|
|
|
|
} |
|
|
|
|
@ -433,6 +440,22 @@ static void tcp_proxy_client_conn_free(struct tcp_proxy_client_conn *pc) {
|
|
|
|
|
u_free(pc); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Завершить локальное TCP-соединение: отвязать коллбэки, сбросить pc->pcb
|
|
|
|
|
// (lwIP дальше сам освободит pcb — в т.ч. молча по истечении TIME_WAIT) и освободить conn.
|
|
|
|
|
// Вызывается, когда обе стороны обменялись FIN (fin_local && fin_remote) — релей завершён.
|
|
|
|
|
static void tcp_proxy_client_conn_finish(struct tcp_proxy_client_conn *pc) { |
|
|
|
|
if (!pc) return; |
|
|
|
|
if (pc->pcb) { |
|
|
|
|
tcp_arg(pc->pcb, NULL); |
|
|
|
|
tcp_recv(pc->pcb, NULL); |
|
|
|
|
tcp_sent(pc->pcb, NULL); |
|
|
|
|
tcp_err(pc->pcb, NULL); |
|
|
|
|
tcp_poll(pc->pcb, NULL, 0); |
|
|
|
|
pc->pcb = NULL; |
|
|
|
|
} |
|
|
|
|
tcp_proxy_client_conn_free(pc); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ====================================================================
|
|
|
|
|
// Обработчики входящих сообщений (сторона клиента)
|
|
|
|
|
// ====================================================================
|
|
|
|
|
@ -508,6 +531,7 @@ static void tcp_proxy_client_handle_fin(struct tcp_proxy_client* p, uint32_t str
|
|
|
|
|
} |
|
|
|
|
if (pc->fin_local && !pc->close_sent && !pc->close_pending) |
|
|
|
|
tcp_proxy_client_send_close(pc); |
|
|
|
|
if (pc->fin_local) tcp_proxy_client_conn_finish(pc); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ====================================================================
|
|
|
|
|
@ -525,7 +549,19 @@ void tcp_proxy_client_router_recv_cb(struct ETCP_CONN* conn, struct ll_entry* en
|
|
|
|
|
(unsigned long long)peer_id); |
|
|
|
|
if (proxy) { |
|
|
|
|
struct tcp_proxy_client_conn *pc, *next; |
|
|
|
|
for (pc = proxy->conns; pc; pc = next) { next = pc->next; tcp_proxy_client_conn_free(pc); } |
|
|
|
|
for (pc = proxy->conns; pc; pc = next) { |
|
|
|
|
next = pc->next; |
|
|
|
|
if (pc->pcb) { |
|
|
|
|
tcp_arg(pc->pcb, NULL); |
|
|
|
|
tcp_recv(pc->pcb, NULL); |
|
|
|
|
tcp_sent(pc->pcb, NULL); |
|
|
|
|
tcp_err(pc->pcb, NULL); |
|
|
|
|
tcp_poll(pc->pcb, NULL, 0); |
|
|
|
|
tcp_abort(pc->pcb); |
|
|
|
|
pc->pcb = NULL; |
|
|
|
|
} |
|
|
|
|
tcp_proxy_client_conn_free(pc); |
|
|
|
|
} |
|
|
|
|
proxy->conns = NULL; proxy->conn_count = 0; |
|
|
|
|
socks_proxy_conn_free_all(&proxy->socks_conns, &proxy->socks_conn_count); |
|
|
|
|
socks_proxy_conn_free_all(&proxy->http_conns, &proxy->http_conn_count); |
|
|
|
|
@ -657,7 +693,7 @@ void tcp_proxy_client_destroy(struct tcp_proxy_client* p) {
|
|
|
|
|
struct tcp_proxy_client_conn* pc = p->conns; |
|
|
|
|
while (pc) { |
|
|
|
|
struct tcp_proxy_client_conn* next = pc->next; |
|
|
|
|
if (pc->pcb && pc->pcb->state != CLOSED) { |
|
|
|
|
if (pc->pcb && !memory_pool_is_freed(p->lwip->pcb_pool, pc->pcb) && pc->pcb->state != CLOSED) { |
|
|
|
|
tcp_arg(pc->pcb, NULL); |
|
|
|
|
tcp_recv(pc->pcb, NULL); |
|
|
|
|
tcp_sent(pc->pcb, NULL); |
|
|
|
|
|