Browse Source

fix remote_proxy: cleanup socket on EOF/error/connect-fail to prevent infinite callback loop

congestion
Evgeny 5 months ago
parent
commit
238fb0eb23
  1. 24
      src/remote_proxy.c

24
src/remote_proxy.c

@ -30,6 +30,7 @@ static struct remote_proxy_ctx* g_rp_ctx = NULL;
static void rp_sock_read_cb (socket_t sock, void* arg); static void rp_sock_read_cb (socket_t sock, void* arg);
static void rp_sock_write_cb(socket_t sock, void* arg); 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_error_cb(socket_t sock, void* arg);
static void rp_conn_free(struct remote_proxy_conn* rc);
static int rp_send_msg(struct UTUN_INSTANCE* inst, uint64_t dst, uint8_t subcmd, static int rp_send_msg(struct UTUN_INSTANCE* inst, uint64_t dst, uint8_t subcmd,
uint64_t sid, const uint8_t* data, size_t len) { uint64_t sid, const uint8_t* data, size_t len) {
@ -62,13 +63,13 @@ static void rp_sock_read_cb(socket_t sock, void* arg) {
if (n > 0) { if (n > 0) {
struct UTUN_INSTANCE* inst = rc->ctx ? rc->ctx->inst : NULL; struct UTUN_INSTANCE* inst = rc->ctx ? rc->ctx->inst : NULL;
if (inst) rp_send_msg(inst, rc->peer_node_id, TCP_PROXY_SUBCMD_DATA, rc->stream_id, buf, (size_t)n); if (inst) rp_send_msg(inst, rc->peer_node_id, TCP_PROXY_SUBCMD_DATA, rc->stream_id, buf, (size_t)n);
} else if (n == 0) { } else {
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "remote_proxy: EOF stream=%016llx", (unsigned long long)rc->stream_id); if (n == 0) DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "remote_proxy: EOF stream=%016llx", (unsigned long long)rc->stream_id);
else DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "remote_proxy: recv error %s", strerror(errno));
struct UTUN_INSTANCE* inst = rc->ctx ? rc->ctx->inst : NULL; 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); if (inst) rp_send_msg(inst, rc->peer_node_id, TCP_PROXY_SUBCMD_CLOSE, rc->stream_id, NULL, 0);
rc->connected = -1; rc->connected = -1;
} else if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR) { rp_conn_free(rc);
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "remote_proxy: recv error %s", strerror(errno));
} }
} }
@ -93,21 +94,30 @@ static void rp_sock_write_cb(socket_t sock, void* arg) {
struct UTUN_INSTANCE* inst = rc->ctx ? rc->ctx->inst : NULL; struct UTUN_INSTANCE* inst = rc->ctx ? rc->ctx->inst : NULL;
if (inst) rp_send_connected(inst, rc->peer_node_id, rc->stream_id, 0, TCP_PROXY_CONNECTED_REFUSED); if (inst) rp_send_connected(inst, rc->peer_node_id, rc->stream_id, 0, TCP_PROXY_CONNECTED_REFUSED);
rc->connected = -1; rc->connected = -1;
rp_conn_free(rc);
} }
} }
} }
static void rp_sock_error_cb(socket_t sock, void* arg) { static void rp_sock_error_cb(socket_t sock, void* arg) {
(void)sock; struct remote_proxy_conn* rc = (struct remote_proxy_conn*)arg; (void)sock; struct remote_proxy_conn* rc = (struct remote_proxy_conn*)arg;
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "remote_proxy: socket error stream=%016llx", (unsigned long long)rc->stream_id); if (!rc || rc->sock == SOCKET_INVALID) return;
if (rc) rc->connected = -1; DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "remote_proxy: socket error stream=%016llx", (unsigned long long)(rc ? rc->stream_id : 0));
rc->connected = -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);
rp_conn_free(rc);
} }
static void rp_conn_free(struct remote_proxy_conn* rc) { static void rp_conn_free(struct remote_proxy_conn* rc) {
if (!rc) return; if (!rc) return;
if (rc->ctx) {
struct remote_proxy_conn** prev = &rc->ctx->conns;
while (*prev) { if (*prev == rc) { *prev = rc->next; break; } prev = &(*prev)->next; }
}
if (rc->sock != SOCKET_INVALID) { if (rc->sock != SOCKET_INVALID) {
if (rc->read_id) { uasync_remove_socket_t(rc->ua, rc->sock); rc->read_id = NULL; } if (rc->read_id) { uasync_remove_socket_t(rc->ua, rc->sock); rc->read_id = NULL; }
socket_close_wrapper(rc->sock); socket_close_wrapper(rc->sock); rc->sock = SOCKET_INVALID;
} }
u_free(rc); u_free(rc);
} }

Loading…
Cancel
Save