|
|
|
|
@ -54,6 +54,16 @@ static int rp_send_connected(struct UTUN_INSTANCE* inst, uint64_t dst, uint64_t
|
|
|
|
|
return rp_send_msg(inst, dst, TCP_PROXY_SUBCMD_CONNECTED, sid, 0, buf, 3); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ====================================================================
|
|
|
|
|
// Socket event logging helper
|
|
|
|
|
// ====================================================================
|
|
|
|
|
static int rp_conn_total(struct remote_proxy_conn* rc) { |
|
|
|
|
if (!rc || !rc->ctx) return 0; |
|
|
|
|
int n = 0; struct remote_proxy_conn* c; |
|
|
|
|
for (c = rc->ctx->conns; c; c = c->next) n++; |
|
|
|
|
return n; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// ====================================================================
|
|
|
|
|
// Socket callbacks
|
|
|
|
|
// ====================================================================
|
|
|
|
|
@ -62,7 +72,7 @@ static void rp_sock_read_cb(socket_t sock, void* arg) {
|
|
|
|
|
if (!rc || rc->sock == SOCKET_INVALID) return; |
|
|
|
|
uint8_t buf[8192]; ssize_t n = recv(rc->sock, buf, sizeof(buf), 0); |
|
|
|
|
if (n > 0) { |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_TRAFFIC, "RP RECV ← stream=%016llx len=%zd seq=%u", (unsigned long long)rc->stream_id, n, rc->send_seq); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "SOCK:RECV fd=%d stream=%016llx len=%zd total=%d", (int)rc->sock, (unsigned long long)rc->stream_id, n, rp_conn_total(rc)); |
|
|
|
|
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, rc->send_seq, buf, (size_t)n); |
|
|
|
|
@ -89,9 +99,10 @@ static void rp_sock_write_cb(socket_t sock, void* arg) {
|
|
|
|
|
struct sockaddr_in local; socklen_t llen = sizeof(local); |
|
|
|
|
uint16_t local_port = 0; |
|
|
|
|
if (getsockname(rc->sock, (struct sockaddr*)&local, &llen) == 0) local_port = local.sin_port; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "remote_proxy: connected stream=%016llx to %d.%d.%d.%d:%d local_port=%d", |
|
|
|
|
(unsigned long long)rc->stream_id, rc->dest_ip[0], rc->dest_ip[1], rc->dest_ip[2], rc->dest_ip[3], |
|
|
|
|
ntohs(rc->dest_port), ntohs(local_port)); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "SOCK:CONN fd=%d stream=%016llx local=%d dest=%d.%d.%d.%d:%d total=%d", |
|
|
|
|
(int)rc->sock, (unsigned long long)rc->stream_id, ntohs(local_port), |
|
|
|
|
rc->dest_ip[0], rc->dest_ip[1], rc->dest_ip[2], rc->dest_ip[3], ntohs(rc->dest_port), |
|
|
|
|
rp_conn_total(rc)); |
|
|
|
|
struct UTUN_INSTANCE* inst = rc->ctx ? rc->ctx->inst : NULL; |
|
|
|
|
if (inst) rp_send_connected(inst, rc->peer_node_id, rc->stream_id, local_port, TCP_PROXY_CONNECTED_OK); |
|
|
|
|
} else { |
|
|
|
|
@ -118,7 +129,7 @@ static void rp_conn_free(struct remote_proxy_conn* rc) {
|
|
|
|
|
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; } |
|
|
|
|
while (*prev) { if (*prev == rc) { *prev = rc->next; rc->ctx->conn_count--; break; } prev = &(*prev)->next; } |
|
|
|
|
} |
|
|
|
|
if (rc->sock != SOCKET_INVALID) { |
|
|
|
|
if (rc->read_id) { uasync_remove_socket_t(rc->ua, rc->sock); rc->read_id = NULL; } |
|
|
|
|
@ -171,14 +182,15 @@ int remote_proxy_handle_connect(struct UTUN_INSTANCE* inst, struct ll_entry* ent
|
|
|
|
|
|
|
|
|
|
rc->sock = socket(AF_INET, SOCK_STREAM, 0); |
|
|
|
|
if (rc->sock == SOCKET_INVALID) { DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "remote_proxy: socket() failed"); rp_conn_free(rc); queue_dgram_free(entry); queue_entry_free(entry); return -1; } |
|
|
|
|
ctx->conn_count++; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "SOCK:NEW fd=%d stream=%016llx dest=%d.%d.%d.%d:%d total=%d", (int)rc->sock, (unsigned long long)stream_id, |
|
|
|
|
dest_ip[0],dest_ip[1],dest_ip[2],dest_ip[3],ntohs(dest_port), ctx->conn_count); |
|
|
|
|
socket_set_nonblocking(rc->sock); |
|
|
|
|
rc->read_id = uasync_add_socket_t(rc->ua, rc->sock, rp_sock_read_cb, rp_sock_write_cb, rp_sock_error_cb, rc); |
|
|
|
|
if (!rc->read_id) { DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "remote_proxy: uasync_add_socket_t failed"); rp_conn_free(rc); queue_dgram_free(entry); queue_entry_free(entry); return -1; } |
|
|
|
|
|
|
|
|
|
struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); |
|
|
|
|
addr.sin_family = AF_INET; memcpy(&addr.sin_addr.s_addr, dest_ip, 4); addr.sin_port = dest_port; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "remote_proxy: connecting stream=%016llx to %d.%d.%d.%d:%d", |
|
|
|
|
(unsigned long long)stream_id, dest_ip[0], dest_ip[1], dest_ip[2], dest_ip[3], ntohs(dest_port)); |
|
|
|
|
rc->connect_called = 1; |
|
|
|
|
int ret = connect(rc->sock, (struct sockaddr*)&addr, sizeof(addr)); |
|
|
|
|
if (ret < 0 && errno != EINPROGRESS) { |
|
|
|
|
@ -215,7 +227,7 @@ int remote_proxy_handle_data(struct UTUN_INSTANCE* inst, struct ll_entry* entry,
|
|
|
|
|
rc->recv_last_seq = seq; |
|
|
|
|
} |
|
|
|
|
size_t data_len = entry->len - TCP_PROXY_HDR_SIZE; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_TRAFFIC, "RP SEND → stream=%016llx seq=%u len=%zu", (unsigned long long)stream_id, seq, data_len); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "SOCK:SEND fd=%d stream=%016llx len=%zu total=%d", (int)rc->sock, (unsigned long long)stream_id, data_len, rp_conn_total(rc)); |
|
|
|
|
uint8_t* data = entry->dgram + TCP_PROXY_HDR_SIZE; |
|
|
|
|
ssize_t n = send(rc->sock, data, data_len, MSG_NOSIGNAL); |
|
|
|
|
if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { |
|
|
|
|
@ -228,7 +240,7 @@ int remote_proxy_handle_data(struct UTUN_INSTANCE* inst, struct ll_entry* entry,
|
|
|
|
|
static void rp_close_timer_cb(void* arg) { |
|
|
|
|
struct remote_proxy_conn* rc = (struct remote_proxy_conn*)arg; |
|
|
|
|
if (!rc || rc->connected == -1) return; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "RP CLOSE timer stream=%016llx", (unsigned long long)rc->stream_id); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "SOCK:TIMER stream=%016llx total=%d", (unsigned long long)rc->stream_id, rp_conn_total(rc)); |
|
|
|
|
rp_conn_free(rc); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -239,7 +251,7 @@ void remote_proxy_handle_close(struct UTUN_INSTANCE* inst, uint64_t stream_id) {
|
|
|
|
|
while (*prev) { |
|
|
|
|
struct remote_proxy_conn* rc = *prev; |
|
|
|
|
if (rc->stream_id == stream_id) { |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "RP CLOSE stream=%016llx", (unsigned long long)stream_id); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "SOCK:CLOSE fd=%d stream=%016llx total=%d", (int)rc->sock, (unsigned long long)stream_id, rp_conn_total(rc)); |
|
|
|
|
*prev = rc->next; |
|
|
|
|
if (rc->sock != SOCKET_INVALID && rc->connected == 1) shutdown(rc->sock, SHUT_WR); |
|
|
|
|
if (rc->read_id) { uasync_remove_socket_t(rc->ua, rc->sock); rc->read_id = NULL; } |
|
|
|
|
|