Skip to content

Commit f4d0596

Browse files
authored
Merge pull request #22 from Dream95/fix_port_conflict
fix: fix potential port conflict
2 parents 7cd95b9 + 700ce31 commit f4d0596

3 files changed

Lines changed: 49 additions & 18 deletions

File tree

cmd/proxy.c

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ struct Socket {
4242
__u16 dst_port;
4343
};
4444

45+
struct PortKey {
46+
__u32 src_ip;
47+
__u16 src_port;
48+
__u16 pad;
49+
};
50+
4551
struct {
4652
__uint(type, BPF_MAP_TYPE_HASH);
4753
__uint(max_entries, 10);
@@ -87,7 +93,7 @@ struct {
8793
struct {
8894
int (*type)[BPF_MAP_TYPE_HASH];
8995
int (*max_entries)[MAX_CONNECTIONS];
90-
__u16 *key;
96+
struct PortKey *key;
9197
__u64 *value;
9298
} map_ports SEC(".maps");
9399

@@ -341,10 +347,13 @@ int cg_sock_ops(struct bpf_sock_ops *ctx) {
341347

342348
struct Socket *sock = bpf_map_lookup_elem(&map_socks, &cookie);
343349
if (sock) {
344-
__u16 src_port = ctx->local_port;
345-
bpf_map_update_elem(&map_ports, &src_port, &cookie, 0);
346-
BPF_LOG_INFO("sockops: map_ports set src_port=%u dst=%x:%u\n",
347-
src_port, sock->dst_addr, sock->dst_port);
350+
struct PortKey pkey;
351+
__builtin_memset(&pkey, 0, sizeof(pkey));
352+
pkey.src_ip = ctx->local_ip4;
353+
pkey.src_port = ctx->local_port;
354+
bpf_map_update_elem(&map_ports, &pkey, &cookie, 0);
355+
BPF_LOG_INFO("sockops: map_ports set src=%x:%u dst=%x:%u\n",
356+
pkey.src_ip, pkey.src_port, sock->dst_addr, sock->dst_port);
348357
} else {
349358
BPF_LOG_INFO("sockops: map_socks miss local_port=%u\n", ctx->local_port);
350359
}
@@ -353,7 +362,7 @@ int cg_sock_ops(struct bpf_sock_ops *ctx) {
353362
}
354363

355364
// This is triggered when the proxy queries the original destination information through getsockopt SO_ORIGINAL_DST.
356-
// This program uses the source port of the client to retrieve the socket's cookie from map_ports,
365+
// This program uses the client source ip+port to retrieve the socket's cookie from map_ports,
357366
// and then from map_socks to get the original destination information,
358367
// then establishes a connection with the original target and forwards the client's request.
359368
SEC("cgroup/getsockopt")
@@ -390,19 +399,24 @@ int cg_sock_opt(struct bpf_sockopt *ctx) {
390399
return 1;
391400
}
392401

393-
__u16 src_port = bpf_ntohs(ctx->sk->dst_port);
402+
struct PortKey pkey;
403+
__builtin_memset(&pkey, 0, sizeof(pkey));
404+
pkey.src_ip = ctx->sk->dst_ip4;
405+
pkey.src_port = bpf_ntohs(ctx->sk->dst_port);
394406

395-
// Retrieve the socket cookie using the clients' src_port
396-
__u64 *cookie = bpf_map_lookup_elem(&map_ports, &src_port);
407+
// Retrieve socket cookie using clients' source ip+port
408+
__u64 *cookie = bpf_map_lookup_elem(&map_ports, &pkey);
397409
if (!cookie) {
398-
BPF_LOG_INFO("getsockopt: map_ports miss src_port=%u\n", src_port);
410+
BPF_LOG_INFO("getsockopt: map_ports miss src=%x:%u\n",
411+
pkey.src_ip, pkey.src_port);
399412
return 1;
400413
}
401414

402415
// Using the cookie (socket identifier), retrieve the original socket (client connect to destination) from map_socks
403416
struct Socket *sock = bpf_map_lookup_elem(&map_socks, cookie);
404417
if (!sock) {
405-
BPF_LOG_INFO("getsockopt: map_socks miss src_port=%u\n", src_port);
418+
BPF_LOG_INFO("getsockopt: map_socks miss src=%x:%u\n",
419+
pkey.src_ip, pkey.src_port);
406420
return 1;
407421
}
408422

@@ -418,8 +432,8 @@ int cg_sock_opt(struct bpf_sockopt *ctx) {
418432
sa->sin_addr.s_addr = bpf_htonl(sock->dst_addr);
419433
sa->sin_port = bpf_htons(sock->dst_port);
420434
ctx->retval = 0;
421-
BPF_LOG_INFO("getsockopt: restore src_port=%u dst=%x:%u\n",
422-
src_port, sock->dst_addr, sock->dst_port);
435+
BPF_LOG_INFO("getsockopt: restore src=%x:%u dst=%x:%u\n",
436+
pkey.src_ip, pkey.src_port, sock->dst_addr, sock->dst_port);
423437
return 1;
424438
}
425439

@@ -431,13 +445,16 @@ int tcp_set_state(struct pt_regs *ctx)
431445

432446
if (state == TCP_CLOSE)
433447
{
434-
__u16 src_port = BPF_CORE_READ(sk, __sk_common.skc_num);
435-
__u64 *cookie = bpf_map_lookup_elem(&map_ports, &src_port);
448+
struct PortKey pkey;
449+
__builtin_memset(&pkey, 0, sizeof(pkey));
450+
pkey.src_ip = BPF_CORE_READ(sk, __sk_common.skc_rcv_saddr);
451+
pkey.src_port = BPF_CORE_READ(sk, __sk_common.skc_num);
452+
__u64 *cookie = bpf_map_lookup_elem(&map_ports, &pkey);
436453
if (cookie)
437454
{
438-
BPF_LOG_INFO("tcp_close: cleanup src_port=%u\n", src_port);
439-
bpf_map_delete_elem(&map_ports, &src_port);
440-
bpf_map_delete_elem(&map_socks, &cookie);
455+
BPF_LOG_INFO("tcp_close: cleanup src=%x:%u\n", pkey.src_ip, pkey.src_port);
456+
bpf_map_delete_elem(&map_ports, &pkey);
457+
bpf_map_delete_elem(&map_socks, cookie);
441458
}
442459
}
443460

cmd/proxy_arm64_bpfel.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/proxy_x86_bpfel.go

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)