summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorluwenpeng <[email protected]>2023-12-11 16:22:46 +0800
committerluwenpeng <[email protected]>2023-12-11 16:22:46 +0800
commit37aeb10e5997826b516529718aa00bc3f7af194f (patch)
tree1897904b5adf2ced5713586631b6f05a4568be4f
parent252c74719b34198fa8bf346468479315e7284be1 (diff)
Add session address
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/packet/packet.h15
-rw-r--r--src/session/gtest_session_address.cpp100
-rw-r--r--src/session/session_address.cpp184
-rw-r--r--src/session/session_address.h72
5 files changed, 372 insertions, 0 deletions
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 <gtest/gtest.h>
+
+#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 <string.h>
+#include <stdio.h>
+
+#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 <arpa/inet.h>
+
+#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