|
|
|
|
@ -33,6 +33,7 @@ static void rp_sock_write_cb(socket_t sock, void* arg);
|
|
|
|
|
static void rp_sock_error_cb(socket_t sock, void* arg); |
|
|
|
|
static void rp_sock_retry_cb(void* arg); |
|
|
|
|
static void rp_sock_pause_cb(void* arg); |
|
|
|
|
static void rp_close_retry_cb(void* arg); |
|
|
|
|
static void rp_sock_send(struct remote_proxy_conn* rc, const uint8_t* data, size_t len); |
|
|
|
|
void rp_conn_free(struct remote_proxy_conn* rc); |
|
|
|
|
|
|
|
|
|
@ -59,6 +60,44 @@ static int rp_send_connected(struct UTUN_INSTANCE* inst, uint64_t dst, uint32_t
|
|
|
|
|
return rp_send_msg(inst, dst, TCP_PROXY_SUBCMD_CONNECTED, sid, buf, 3); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void rp_close_retry_cb(void* arg) { |
|
|
|
|
struct remote_proxy_conn* rc = (struct remote_proxy_conn*)arg; |
|
|
|
|
if (!rc) return; |
|
|
|
|
rc->close_timer = NULL; |
|
|
|
|
if (!rc->close_pending) return; |
|
|
|
|
struct UTUN_INSTANCE* inst = rc->ctx ? rc->ctx->inst : NULL; |
|
|
|
|
if (!inst) return; |
|
|
|
|
uint8_t subcmd = rc->error ? TCP_PROXY_SUBCMD_ERROR : TCP_PROXY_SUBCMD_CLOSE; |
|
|
|
|
if (rp_send_msg(inst, rc->peer_node_id, subcmd, rc->stream_id, NULL, 0) < 0) { |
|
|
|
|
rc->close_backoff = rc->close_backoff < 5000 ? rc->close_backoff * 2 : 5000; |
|
|
|
|
rc->close_timer = uasync_set_timeout(rc->ua, rc->close_backoff, rc, rp_close_retry_cb, "rp_close_retry"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
rc->close_pending = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void rp_send_close(struct remote_proxy_conn* rc) { |
|
|
|
|
struct UTUN_INSTANCE* inst = rc->ctx ? rc->ctx->inst : NULL; |
|
|
|
|
if (!inst) return; |
|
|
|
|
if (rp_send_msg(inst, rc->peer_node_id, TCP_PROXY_SUBCMD_CLOSE, rc->stream_id, NULL, 0) < 0) { |
|
|
|
|
rc->close_pending = 1; |
|
|
|
|
rc->close_backoff = 50; |
|
|
|
|
if (!rc->close_timer) |
|
|
|
|
rc->close_timer = uasync_set_timeout(rc->ua, rc->close_backoff, rc, rp_close_retry_cb, "rp_close_retry"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void rp_send_error(struct remote_proxy_conn* rc) { |
|
|
|
|
struct UTUN_INSTANCE* inst = rc->ctx ? rc->ctx->inst : NULL; |
|
|
|
|
if (!inst) return; |
|
|
|
|
if (rp_send_msg(inst, rc->peer_node_id, TCP_PROXY_SUBCMD_ERROR, rc->stream_id, NULL, 0) < 0) { |
|
|
|
|
rc->close_pending = 1; |
|
|
|
|
rc->close_backoff = 50; |
|
|
|
|
if (!rc->close_timer) |
|
|
|
|
rc->close_timer = uasync_set_timeout(rc->ua, rc->close_backoff, rc, rp_close_retry_cb, "rp_close_retry"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static int rp_conn_total(struct remote_proxy_conn* rc) { |
|
|
|
|
if (!rc || !rc->ctx) return 0; |
|
|
|
|
int n = 0; struct remote_proxy_conn* c; |
|
|
|
|
@ -182,9 +221,7 @@ static void rp_sock_read_cb(socket_t sock, void* arg) {
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "SOCK:EOF fd=%d sid=%08x total=%d cli_closed=%d sock_closed=%d", |
|
|
|
|
(int)rc->sock, rc->stream_id, rp_conn_total(rc), rc->cli_closed, rc->sock_closed); |
|
|
|
|
rc->sock_closed = 1; |
|
|
|
|
struct UTUN_INSTANCE* inst = rc->ctx ? rc->ctx->inst : NULL; |
|
|
|
|
if (inst) rp_send_msg(inst, rc->peer_node_id, TCP_PROXY_SUBCMD_CLOSE, rc->stream_id, NULL, 0); |
|
|
|
|
else DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "SOCK:EOF fd=%d sid=%08x — inst is NULL, can't send CLOSE", (int)rc->sock, rc->stream_id); |
|
|
|
|
rp_send_close(rc); |
|
|
|
|
if (rc->read_id) { uasync_remove_socket_t(rc->ua, rc->sock); rc->read_id = NULL; } |
|
|
|
|
if (rc->cli_closed) rp_conn_free(rc); |
|
|
|
|
} else if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) { |
|
|
|
|
@ -232,9 +269,7 @@ static void rp_sock_error_cb(socket_t sock, void* arg) {
|
|
|
|
|
if (!rc || rc->sock == SOCKET_INVALID) return; |
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "SOCK:ERR fd=%d sid=%08x", (int)rc->sock, rc->stream_id); |
|
|
|
|
rc->error = 1; |
|
|
|
|
struct UTUN_INSTANCE* inst = rc->ctx ? rc->ctx->inst : NULL; |
|
|
|
|
if (inst) rp_send_msg(inst, rc->peer_node_id, TCP_PROXY_SUBCMD_ERROR, rc->stream_id, NULL, 0); |
|
|
|
|
else DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "SOCK:ERR fd=%d sid=%08x — inst is NULL", (int)rc->sock, rc->stream_id); |
|
|
|
|
rp_send_error(rc); |
|
|
|
|
rp_conn_free(rc); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -256,6 +291,7 @@ void rp_conn_free(struct remote_proxy_conn* rc) {
|
|
|
|
|
if (rc->out_buf) { u_free(rc->out_buf); rc->out_buf = NULL; } |
|
|
|
|
if (rc->pause_timer) { uasync_cancel_timeout(rc->ua, rc->pause_timer); rc->pause_timer = NULL; } |
|
|
|
|
if (rc->pause_buf) { u_free(rc->pause_buf); rc->pause_buf = NULL; } |
|
|
|
|
if (rc->close_timer) { uasync_cancel_timeout(rc->ua, rc->close_timer); rc->close_timer = NULL; } |
|
|
|
|
u_free(rc); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|