From 37aeb10e5997826b516529718aa00bc3f7af194f Mon Sep 17 00:00:00 2001 From: luwenpeng Date: Mon, 11 Dec 2023 16:22:46 +0800 Subject: [PATCH] Add session address --- src/CMakeLists.txt | 1 + src/packet/packet.h | 15 +++ src/session/gtest_session_address.cpp | 100 ++++++++++++++ src/session/session_address.cpp | 184 ++++++++++++++++++++++++++ src/session/session_address.h | 72 ++++++++++ 5 files changed, 372 insertions(+) create mode 100644 src/packet/packet.h create mode 100644 src/session/gtest_session_address.cpp create mode 100644 src/session/session_address.cpp create mode 100644 src/session/session_address.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 40a51e7..b3b8322 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1 +1,2 @@ +add_subdirectory(session) add_subdirectory(stellar) \ No newline at end of file diff --git a/src/packet/packet.h b/src/packet/packet.h new file mode 100644 index 0000000..fbde808 --- /dev/null +++ b/src/packet/packet.h @@ -0,0 +1,15 @@ +#ifndef _PACKET_H +#define _PACKET_H + +#ifdef __cpluscplus +extern "C" +{ +#endif + +struct packet; + +#ifdef __cpluscplus +} +#endif + +#endif diff --git a/src/session/gtest_session_address.cpp b/src/session/gtest_session_address.cpp new file mode 100644 index 0000000..a76f746 --- /dev/null +++ b/src/session/gtest_session_address.cpp @@ -0,0 +1,100 @@ +#include + +#include "session_address.h" + +#define SESSION_ADDRESS_IPV4_TCP(name) \ + struct session_address name = {0}; \ + (name).layers[0].type = LAYER_IPV4; \ + (name).layers[0].tuple.ipv4.src.s_addr = inet_addr("192.168.1.2"); \ + (name).layers[0].tuple.ipv4.dst.s_addr = inet_addr("192.168.1.3"); \ + (name).layers[1].type = LAYER_TCP; \ + (name).layers[1].tuple.tcp.src = htons(1234); \ + (name).layers[1].tuple.tcp.dst = htons(5678); \ + (name).used = 2; + +#define SESSION_ADDRESS_IPV6_UDP(name) \ + struct session_address name = {0}; \ + (name).layers[0].type = LAYER_IPV6; \ + inet_pton(AF_INET6, "2001:db8:0:0:0:ff00:42:8329", &(name).layers[0].tuple.ipv6.src); \ + inet_pton(AF_INET6, "2001:db8:0:0:0:ff00:42:832a", &(name).layers[0].tuple.ipv6.dst); \ + (name).layers[1].type = LAYER_UDP; \ + (name).layers[1].tuple.udp.src = htons(2345); \ + (name).layers[1].tuple.udp.dst = htons(443); \ + (name).used = 2; + +#define SESSION_ADDRESS_IPV4_UDP_IPV6_TCP(name) \ + struct session_address name = {0}; \ + (name).layers[0].type = LAYER_IPV4; \ + (name).layers[0].tuple.ipv4.src.s_addr = inet_addr("192.168.1.2"); \ + (name).layers[0].tuple.ipv4.dst.s_addr = inet_addr("192.168.1.3"); \ + (name).layers[1].type = LAYER_UDP; \ + (name).layers[1].tuple.udp.src = htons(1234); \ + (name).layers[1].tuple.udp.dst = htons(5678); \ + (name).layers[2].type = LAYER_IPV6; \ + inet_pton(AF_INET6, "2001:db8:0:0:0:ff00:42:8329", &(name).layers[2].tuple.ipv6.src); \ + inet_pton(AF_INET6, "2001:db8:0:0:0:ff00:42:832a", &(name).layers[2].tuple.ipv6.dst); \ + (name).layers[3].type = LAYER_TCP; \ + (name).layers[3].tuple.tcp.src = htons(2345); \ + (name).layers[3].tuple.tcp.dst = htons(443); \ + (name).used = 4; + +TEST(SESSION_ADDRESS, TOSTRING) +{ + char buff[256] = {0}; + + SESSION_ADDRESS_IPV4_TCP(sess1_addr); + SESSION_ADDRESS_IPV6_UDP(sess2_addr); + SESSION_ADDRESS_IPV4_UDP_IPV6_TCP(sess3_addr); + + session_address_tostring(&sess1_addr, buff, sizeof(buff)); + EXPECT_STREQ(buff, "192.168.1.2-192.168.1.3/1234-5678/"); + session_address_tostring(&sess2_addr, buff, sizeof(buff)); + EXPECT_STREQ(buff, "2001:db8::ff00:42:8329-2001:db8::ff00:42:832a/2345-443/"); + session_address_tostring(&sess3_addr, buff, sizeof(buff)); + EXPECT_STREQ(buff, "192.168.1.2-192.168.1.3/1234-5678/2001:db8::ff00:42:8329-2001:db8::ff00:42:832a/2345-443/"); +} + +TEST(SESSION_ADDRESS, REVERSE) +{ + char buff[256] = {0}; + + SESSION_ADDRESS_IPV4_TCP(sess1_addr); + SESSION_ADDRESS_IPV6_UDP(sess2_addr); + SESSION_ADDRESS_IPV4_UDP_IPV6_TCP(sess3_addr); + + session_address_reverse(&sess1_addr); + session_address_reverse(&sess2_addr); + session_address_reverse(&sess3_addr); + + session_address_tostring(&sess1_addr, buff, sizeof(buff)); + EXPECT_STREQ(buff, "192.168.1.3-192.168.1.2/5678-1234/"); + session_address_tostring(&sess2_addr, buff, sizeof(buff)); + EXPECT_STREQ(buff, "2001:db8::ff00:42:832a-2001:db8::ff00:42:8329/443-2345/"); + session_address_tostring(&sess3_addr, buff, sizeof(buff)); + EXPECT_STREQ(buff, "192.168.1.3-192.168.1.2/5678-1234/2001:db8::ff00:42:832a-2001:db8::ff00:42:8329/443-2345/"); +} + +TEST(SESSION_ADDRESS, SELFCMP) +{ + SESSION_ADDRESS_IPV4_TCP(sess1_addr); + SESSION_ADDRESS_IPV6_UDP(sess2_addr); + SESSION_ADDRESS_IPV4_UDP_IPV6_TCP(sess3_addr); + + EXPECT_TRUE(session_address_selfcmp(&sess1_addr) < 0); + EXPECT_TRUE(session_address_selfcmp(&sess2_addr) < 0); + EXPECT_TRUE(session_address_selfcmp(&sess3_addr) < 0); + + session_address_reverse(&sess1_addr); + session_address_reverse(&sess2_addr); + session_address_reverse(&sess3_addr); + + EXPECT_TRUE(session_address_selfcmp(&sess1_addr) > 0); + EXPECT_TRUE(session_address_selfcmp(&sess2_addr) > 0); + EXPECT_TRUE(session_address_selfcmp(&sess3_addr) > 0); +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/session/session_address.cpp b/src/session/session_address.cpp new file mode 100644 index 0000000..d151417 --- /dev/null +++ b/src/session/session_address.cpp @@ -0,0 +1,184 @@ +#include +#include + +#include "session_address.h" + +void session_address_init(struct session_address *addr, const struct packet *packet) +{ + // TODO +} + +void session_address_tostring(const struct session_address *addr, char *buf, size_t len) +{ + char *ptr = buf; + size_t used = 0; + size_t tlen = 0; + for (int i = 0; i < addr->used; i++) + { + const struct layer_tuple *tuple = &addr->layers[i]; + switch (tuple->type) + { + case LAYER_IPV4: + if (len - used < 32) + { + return; + } + inet_ntop(AF_INET, &tuple->tuple.ipv4.src, ptr, len - used); + tlen = strlen(ptr); + used += tlen; + ptr += tlen; + *ptr++ = '-'; + used += 1; + + inet_ntop(AF_INET, &tuple->tuple.ipv4.dst, ptr, len - used); + tlen = strlen(ptr); + used += tlen; + ptr += tlen; + *ptr++ = '/'; + used += 1; + break; + case LAYER_IPV6: + if (len - used < 64) + { + return; + } + inet_ntop(AF_INET6, &tuple->tuple.ipv6.src, ptr, len - used); + tlen = strlen(ptr); + used += tlen; + ptr += tlen; + *ptr++ = '-'; + used += 1; + + inet_ntop(AF_INET6, &tuple->tuple.ipv6.dst, ptr, len - used); + tlen = strlen(ptr); + used += tlen; + ptr += tlen; + *ptr++ = '/'; + used += 1; + break; + case LAYER_TCP: + if (len - used < 16) + { + return; + } + snprintf(ptr, len - used, "%u-%u", ntohs(tuple->tuple.tcp.src), ntohs(tuple->tuple.tcp.dst)); + tlen = strlen(ptr); + used += tlen; + ptr += tlen; + *ptr++ = '/'; + used += 1; + break; + case LAYER_UDP: + if (len - used < 16) + { + return; + } + snprintf(ptr, len - used, "%u-%u", ntohs(tuple->tuple.udp.src), ntohs(tuple->tuple.udp.dst)); + tlen = strlen(ptr); + used += tlen; + ptr += tlen; + *ptr++ = '/'; + used += 1; + break; + default: + return; + } + } +} + +void session_address_reverse(struct session_address *addr) +{ + for (int i = 0; i < addr->used; i++) + { + struct layer_tuple *tuple = &addr->layers[i]; + switch (tuple->type) + { + case LAYER_IPV4: + { + struct in_addr tmp = tuple->tuple.ipv4.src; + tuple->tuple.ipv4.src = tuple->tuple.ipv4.dst; + tuple->tuple.ipv4.dst = tmp; + break; + } + case LAYER_IPV6: + { + struct in6_addr tmp = tuple->tuple.ipv6.src; + tuple->tuple.ipv6.src = tuple->tuple.ipv6.dst; + tuple->tuple.ipv6.dst = tmp; + break; + } + case LAYER_TCP: + { + uint16_t tmp = tuple->tuple.tcp.src; + tuple->tuple.tcp.src = tuple->tuple.tcp.dst; + tuple->tuple.tcp.dst = tmp; + break; + } + case LAYER_UDP: + { + uint16_t tmp = tuple->tuple.udp.src; + tuple->tuple.udp.src = tuple->tuple.udp.dst; + tuple->tuple.udp.dst = tmp; + break; + } + default: + return; + } + } +} + +// cmp src and dst +// return: src - dst +int session_address_selfcmp(struct session_address *addr) +{ + int ret = 0; + for (int i = 0; i < addr->used; i++) + { + struct layer_tuple *tuple = &addr->layers[i]; + switch (tuple->type) + { + case LAYER_IPV4: + { + ret = tuple->tuple.ipv4.src.s_addr - tuple->tuple.ipv4.dst.s_addr; + if (ret != 0) + { + return ret; + } + break; + } + case LAYER_IPV6: + { + for (int j = 0; j < 16; j++) + { + ret = tuple->tuple.ipv6.src.s6_addr[j] - tuple->tuple.ipv6.dst.s6_addr[j]; + if (ret != 0) + { + return ret; + } + } + break; + } + case LAYER_TCP: + { + ret = tuple->tuple.tcp.src - tuple->tuple.tcp.dst; + if (ret != 0) + { + return ret; + } + break; + } + case LAYER_UDP: + { + ret = tuple->tuple.udp.src - tuple->tuple.udp.dst; + if (ret != 0) + { + return ret; + } + break; + } + default: + break; + } + } + return 0; +} diff --git a/src/session/session_address.h b/src/session/session_address.h new file mode 100644 index 0000000..5b45465 --- /dev/null +++ b/src/session/session_address.h @@ -0,0 +1,72 @@ +#ifndef _SESSION_ADDRESS_H +#define _SESSION_ADDRESS_H + +#ifdef __cpluscplus +extern "C" +{ +#endif + +#include + +#define SESSION_ADDR_MAX_LAYER 8 + +enum layer_type +{ + LAYER_IPV4 = 0, + LAYER_IPV6 = 1, + LAYER_TCP = 2, + LAYER_UDP = 3, +}; + +struct ipv4_address +{ + struct in_addr src; /* network order */ + struct in_addr dst; /* network order */ +}; + +struct ipv6_address +{ + struct in6_addr src; /* network order */ + struct in6_addr dst; /* network order */ +}; + +struct tcp_port +{ + uint16_t src; /* network order */ + uint16_t dst; /* network order */ +}; + +struct udp_port +{ + uint16_t src; /* network order */ + uint16_t dst; /* network order */ +}; + +struct layer_tuple +{ + enum layer_type type; + union + { + struct ipv4_address ipv4; + struct ipv6_address ipv6; + struct tcp_port tcp; + struct udp_port udp; + } tuple; +}; + +struct session_address +{ + uint8_t used; + struct layer_tuple layers[SESSION_ADDR_MAX_LAYER]; +}; + +void session_address_init(struct session_address *addr, const struct packet *packet); +void session_address_tostring(const struct session_address *addr, char *buf, size_t len); +void session_address_reverse(struct session_address *addr); +int session_address_selfcmp(struct session_address *addr); + +#ifdef __cpluscplus +} +#endif + +#endif