add orig_src_ip to ICMP proxy protocol, fix deliver_reply dst_ip (was wrong tun_ip_addr)
This commit is contained in:
1 parent
67d57c9751
commit
13d469d866
4 files changed
+37
-30
No files matched your search
+26
-21
@@ -34,7 +34,7 @@ static struct icmp_request* req_find_by_id(struct icmp_request* head, uint16_t e
|
||||
|
||||
// Build and send a raw ICMP echo request
|
||||
static int exit_send_echo(struct UTUN_INSTANCE* inst, uint64_t client_node_id,
|
||||
uint32_t dst_ip, uint16_t echo_id, uint16_t echo_seq,
|
||||
uint32_t dst_ip, uint32_t orig_src_ip, uint16_t echo_id, uint16_t echo_seq,
|
||||
const uint8_t* payload, size_t payload_len) {
|
||||
if (!g_icmp_ctx || g_icmp_ctx->raw_sock == SOCKET_INVALID) return -1;
|
||||
size_t icmp_len = ICMP_MINLEN + payload_len;
|
||||
@@ -64,7 +64,7 @@ static int exit_send_echo(struct UTUN_INSTANCE* inst, uint64_t client_node_id,
|
||||
|
||||
struct icmp_request* r = u_calloc(1, sizeof(struct icmp_request));
|
||||
if (!r) return 0;
|
||||
r->client_node_id = client_node_id; r->dst_ip = dst_ip;
|
||||
r->client_node_id = client_node_id; r->dst_ip = dst_ip; r->orig_src_ip = orig_src_ip;
|
||||
r->echo_id = echo_id; r->echo_seq = echo_seq;
|
||||
r->payload_len = payload_len > sizeof(r->payload) ? sizeof(r->payload) : payload_len;
|
||||
if (payload_len > 0) memcpy(r->payload, payload, r->payload_len);
|
||||
@@ -108,8 +108,9 @@ static void raw_read_cb(socket_t sock, void* arg) {
|
||||
e->dgram[1] = ICMP_PROXY_SUBCMD_REPLY;
|
||||
memcpy(e->dgram + 2, &r->client_node_id, 8);
|
||||
memcpy(e->dgram + 10, &r->dst_ip, 4);
|
||||
memcpy(e->dgram + 14, &icmp_hdr->icmp_id, 2);
|
||||
memcpy(e->dgram + 16, &icmp_hdr->icmp_seq, 2);
|
||||
memcpy(e->dgram + 14, &r->orig_src_ip, 4);
|
||||
memcpy(e->dgram + 18, &icmp_hdr->icmp_id, 2);
|
||||
memcpy(e->dgram + 20, &icmp_hdr->icmp_seq, 2);
|
||||
if (payload_len > 0) memcpy(e->dgram + ICMP_PROXY_HDR_SIZE, payload, payload_len);
|
||||
e->len = ICMP_PROXY_HDR_SIZE + payload_len;
|
||||
int ret = etcp_route_send(g_icmp_ctx->inst, r->client_node_id, e);
|
||||
@@ -125,14 +126,15 @@ static void exit_handle_request(struct ETCP_CONN* conn, struct ll_entry* entry)
|
||||
if (!inst || !g_icmp_ctx || entry->len < ICMP_PROXY_HDR_SIZE + 1) goto drop;
|
||||
|
||||
uint64_t client_node_id; memcpy(&client_node_id, entry->dgram + 2, 8);
|
||||
uint32_t dst_ip; memcpy(&dst_ip, entry->dgram + 10, 4);
|
||||
uint16_t echo_id; memcpy(&echo_id, entry->dgram + 14, 2);
|
||||
uint16_t echo_seq; memcpy(&echo_seq, entry->dgram + 16, 2);
|
||||
uint32_t dst_ip; memcpy(&dst_ip, entry->dgram + 10, 4);
|
||||
uint32_t orig_src_ip; memcpy(&orig_src_ip, entry->dgram + 14, 4);
|
||||
uint16_t echo_id; memcpy(&echo_id, entry->dgram + 18, 2);
|
||||
uint16_t echo_seq; memcpy(&echo_seq, entry->dgram + 20, 2);
|
||||
uint8_t* payload = entry->dgram + ICMP_PROXY_HDR_SIZE;
|
||||
size_t payload_len = entry->len - ICMP_PROXY_HDR_SIZE;
|
||||
|
||||
if (g_icmp_ctx->raw_sock != SOCKET_INVALID) {
|
||||
exit_send_echo(inst, client_node_id, dst_ip, echo_id, echo_seq, payload, payload_len);
|
||||
exit_send_echo(inst, client_node_id, dst_ip, orig_src_ip, echo_id, echo_seq, payload, payload_len);
|
||||
} else if (g_icmp_ctx->test_loopback) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "icmp_proxy: test loopback reply to 0x%08x", dst_ip);
|
||||
struct ll_entry* e = queue_entry_new(0);
|
||||
@@ -143,8 +145,9 @@ static void exit_handle_request(struct ETCP_CONN* conn, struct ll_entry* entry)
|
||||
e->dgram[1] = ICMP_PROXY_SUBCMD_REPLY;
|
||||
memcpy(e->dgram + 2, &client_node_id, 8);
|
||||
memcpy(e->dgram + 10, &dst_ip, 4);
|
||||
memcpy(e->dgram + 14, &echo_id, 2);
|
||||
memcpy(e->dgram + 16, &echo_seq, 2);
|
||||
memcpy(e->dgram + 14, &orig_src_ip, 4);
|
||||
memcpy(e->dgram + 18, &echo_id, 2);
|
||||
memcpy(e->dgram + 20, &echo_seq, 2);
|
||||
if (payload_len > 0) memcpy(e->dgram + ICMP_PROXY_HDR_SIZE, payload, payload_len);
|
||||
e->len = ICMP_PROXY_HDR_SIZE + payload_len;
|
||||
etcp_route_send(inst, client_node_id, e);
|
||||
@@ -164,14 +167,16 @@ drop:
|
||||
static void client_handle_reply(struct ETCP_CONN* conn, struct ll_entry* entry) {
|
||||
if (entry->len < ICMP_PROXY_HDR_SIZE + 1) { queue_entry_free(entry); queue_dgram_free(entry); return; }
|
||||
uint32_t src_ip;
|
||||
uint32_t orig_src_ip;
|
||||
uint16_t echo_id, echo_seq;
|
||||
memcpy(&src_ip, entry->dgram + 10, 4);
|
||||
memcpy(&echo_id, entry->dgram + 14, 2);
|
||||
memcpy(&echo_seq, entry->dgram + 16, 2);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "icmp_proxy: client got reply id=0x%04x seq=%u from=0x%08x",
|
||||
echo_id, echo_seq, src_ip);
|
||||
memcpy(&src_ip, entry->dgram + 10, 4);
|
||||
memcpy(&orig_src_ip, entry->dgram + 14, 4);
|
||||
memcpy(&echo_id, entry->dgram + 18, 2);
|
||||
memcpy(&echo_seq, entry->dgram + 20, 2);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_SOCKET, "icmp_proxy: client got reply id=0x%04x seq=%u from=0x%08x dst=0x%08x",
|
||||
echo_id, echo_seq, src_ip, orig_src_ip);
|
||||
struct UTUN_INSTANCE* inst = conn ? conn->instance : (g_icmp_ctx ? g_icmp_ctx->inst : NULL);
|
||||
icmp_proxy_deliver_reply(inst, src_ip, echo_id, echo_seq,
|
||||
icmp_proxy_deliver_reply(inst, orig_src_ip, src_ip, echo_id, echo_seq,
|
||||
entry->dgram + ICMP_PROXY_HDR_SIZE, entry->len - ICMP_PROXY_HDR_SIZE);
|
||||
queue_entry_free(entry); queue_dgram_free(entry);
|
||||
}
|
||||
@@ -194,7 +199,7 @@ void icmp_proxy_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry) {
|
||||
// Client side: send ICMP echo request to exit node
|
||||
// ====================================================================
|
||||
int icmp_proxy_send_to_exit(struct UTUN_INSTANCE* inst, uint64_t exit_node_id,
|
||||
uint32_t dst_ip, uint16_t echo_id, uint16_t echo_seq,
|
||||
uint32_t dst_ip, uint32_t orig_src_ip, uint16_t echo_id, uint16_t echo_seq,
|
||||
const uint8_t* payload, size_t payload_len) {
|
||||
if (!inst) return -1;
|
||||
struct ll_entry* e = queue_entry_new(0);
|
||||
@@ -205,8 +210,9 @@ int icmp_proxy_send_to_exit(struct UTUN_INSTANCE* inst, uint64_t exit_node_id,
|
||||
e->dgram[1] = ICMP_PROXY_SUBCMD_REQUEST;
|
||||
memcpy(e->dgram + 2, &inst->node_id, 8);
|
||||
memcpy(e->dgram + 10, &dst_ip, 4);
|
||||
memcpy(e->dgram + 14, &echo_id, 2);
|
||||
memcpy(e->dgram + 16, &echo_seq, 2);
|
||||
memcpy(e->dgram + 14, &orig_src_ip, 4);
|
||||
memcpy(e->dgram + 18, &echo_id, 2);
|
||||
memcpy(e->dgram + 20, &echo_seq, 2);
|
||||
if (payload_len > 0) memcpy(e->dgram + ICMP_PROXY_HDR_SIZE, payload, payload_len);
|
||||
e->len = ICMP_PROXY_HDR_SIZE + payload_len;
|
||||
return etcp_route_send(inst, exit_node_id, e);
|
||||
@@ -216,7 +222,7 @@ int icmp_proxy_send_to_exit(struct UTUN_INSTANCE* inst, uint64_t exit_node_id,
|
||||
// Client side: deliver ICMP echo reply to TUN
|
||||
// ====================================================================
|
||||
int icmp_proxy_deliver_reply(struct UTUN_INSTANCE* inst,
|
||||
uint32_t src_ip, uint16_t echo_id, uint16_t echo_seq,
|
||||
uint32_t dst_ip, uint32_t src_ip, uint16_t echo_id, uint16_t echo_seq,
|
||||
const uint8_t* payload, size_t payload_len) {
|
||||
if (!inst || !inst->tcp_proxy || !inst->tcp_proxy->tun) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "icmp_proxy: deliver_reply failed — no %s",
|
||||
@@ -224,7 +230,6 @@ int icmp_proxy_deliver_reply(struct UTUN_INSTANCE* inst,
|
||||
return -1;
|
||||
}
|
||||
struct tun_if* tun = inst->tcp_proxy->tun;
|
||||
uint32_t dst_ip = inst->tcp_proxy->tun_ip_addr;
|
||||
|
||||
size_t icmp_len = ICMP_MINLEN + payload_len;
|
||||
size_t pkt_len = 20 + icmp_len;
|
||||
|
||||
+5
-4
@@ -15,14 +15,15 @@ struct ETCP_CONN;
|
||||
#define ICMP_PROXY_SUBCMD_REPLY 0x02 // exit→client: echo reply
|
||||
|
||||
// Message header (excluding svc_id byte)
|
||||
// svc_id(1) + subcmd(1) + sender_node_id(8) + dst_ip(4) + icmp_id(2) + icmp_seq(2) + payload
|
||||
#define ICMP_PROXY_HDR_SIZE 18
|
||||
// svc_id(1) + subcmd(1) + sender_node_id(8) + dst_ip(4) + orig_src_ip(4) + icmp_id(2) + icmp_seq(2) + payload
|
||||
#define ICMP_PROXY_HDR_SIZE 22
|
||||
|
||||
// In-flight ICMP echo request (exit node side)
|
||||
struct icmp_request {
|
||||
struct icmp_request* next;
|
||||
uint64_t client_node_id;
|
||||
uint32_t dst_ip;
|
||||
uint32_t orig_src_ip; // IP исходного отправителя (чтобы вернуть reply правильному адресату)
|
||||
uint16_t echo_id;
|
||||
uint16_t echo_seq;
|
||||
uint8_t payload[1500];
|
||||
@@ -51,11 +52,11 @@ void icmp_proxy_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry);
|
||||
|
||||
// Client side: принять IP/ICMP echo request с TUN, отправить через etcp
|
||||
int icmp_proxy_send_to_exit(struct UTUN_INSTANCE* inst, uint64_t exit_node_id,
|
||||
uint32_t dst_ip, uint16_t echo_id, uint16_t echo_seq,
|
||||
uint32_t dst_ip, uint32_t orig_src_ip, uint16_t echo_id, uint16_t echo_seq,
|
||||
const uint8_t* payload, size_t payload_len);
|
||||
|
||||
int icmp_proxy_deliver_reply(struct UTUN_INSTANCE* inst,
|
||||
uint32_t src_ip, uint16_t echo_id, uint16_t echo_seq,
|
||||
uint32_t dst_ip, uint32_t src_ip, uint16_t echo_id, uint16_t echo_seq,
|
||||
const uint8_t* payload, size_t payload_len);
|
||||
|
||||
void icmp_proxy_set_test_loopback(struct UTUN_INSTANCE* inst, int enabled);
|
||||
|
||||
+3
-2
@@ -162,10 +162,11 @@ static int tcp_proxy_handle_non_tcp(struct tcp_proxy* p, uint8_t* buf, size_t le
|
||||
if (len < 28) return 0;
|
||||
uint8_t icmp_type = buf[20];
|
||||
if (icmp_type != 8) return 0;
|
||||
uint32_t dst_ip; memcpy(&dst_ip, buf + 16, 4);
|
||||
uint32_t src_ip, dst_ip;
|
||||
memcpy(&src_ip, buf + 12, 4); memcpy(&dst_ip, buf + 16, 4);
|
||||
uint16_t icmp_id, icmp_seq;
|
||||
memcpy(&icmp_id, buf + 24, 2); memcpy(&icmp_seq, buf + 26, 2);
|
||||
icmp_proxy_send_to_exit(p->inst, p->via_node_id, dst_ip, icmp_id, icmp_seq, buf + 28, len - 28);
|
||||
icmp_proxy_send_to_exit(p->inst, p->via_node_id, dst_ip, src_ip, icmp_id, icmp_seq, buf + 28, len - 28);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
Reference in new issue
Block a user