Skip to content

Commit

Permalink
finish ip overrider
Browse files Browse the repository at this point in the history
  • Loading branch information
radkesvat committed Aug 7, 2024
1 parent b91bf4e commit d75608e
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 34 deletions.
13 changes: 13 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ set(ENABLE_TSAN OFF CACHE BOOL "enable thread sanitizer" FORCE)
set(ENABLE_LSAN OFF CACHE BOOL "enable leak sanitizer" FORCE)
set(ENABLE_USAN OFF CACHE BOOL "enable undefined behaviour sanitizer" FORCE)


option(INCLUDE_LAYER3_IP_OVERRIDER "link Layer3IpOverrider staticly to the core" TRUE)

option(INCLUDE_TCP_LISTENER "link TcpListener staticly to the core" TRUE)
option(INCLUDE_UDP_LISTENER "link UdpListener staticly to the core" TRUE)
option(INCLUDE_LISTENER "link Listener staticly to the core" TRUE)
Expand Down Expand Up @@ -123,6 +126,16 @@ target_link_directories(Waterwall PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/ww)
target_include_directories(Waterwall PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/ww)
target_link_libraries(Waterwall ww)



#layer3 ip overrider
if (INCLUDE_LAYER3_IP_OVERRIDER)
target_compile_definitions(Waterwall PUBLIC INCLUDE_LAYER3_IP_OVERRIDER=1)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tunnels/layer3/ip_overrider)
target_link_directories(Waterwall PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/tunnels/layer3/ip_overrider)
target_link_libraries(Waterwall Layer3IpOverrider)
endif()

#tcp listener
if (INCLUDE_TCP_LISTENER)
target_compile_definitions(Waterwall PUBLIC INCLUDE_TCP_LISTENER=1)
Expand Down
2 changes: 1 addition & 1 deletion tunnels/layer3/ip_overrider/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@


add_library(Layer3IpOverrider STATIC
connector.c
ip_overrider.c

)

Expand Down
136 changes: 103 additions & 33 deletions tunnels/layer3/ip_overrider/ip_overrider.c
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
#include "ip_overrider.h"
#include "hsocket.h"
#include "loggers/network_logger.h"
#include "managers/node_manager.h"
#include "utils/jsonutils.h"
#include "utils/stringutils.h"
#include <endian.h>

typedef struct layer3_ip_overrider_state_s
{

bool dest_mode;
bool support4;
bool support6;
struct in6_addr ov_6;
uint32_t ov_4;
bool support4;
bool support6;

} layer3_ip_overrider_state_t;

Expand Down Expand Up @@ -62,63 +63,101 @@ struct ipv6hdr
struct in6_addr daddr;
};

static void upStream(tunnel_t *self, context_t *c)
typedef union {
struct ipv4hdr ip4_header;
struct ipv6hdr ip6_header;

} packet_mask;

static void upStreamSrcMode(tunnel_t *self, context_t *c)
{
layer3_ip_overrider_state_t *state = TSTATE(self);

struct ipv4hdr *ip4_header = (struct ipv4hdr *) (rawBufMut(c->payload));
struct ipv6hdr *ip6_header = (struct ipv6hdr *) (rawBufMut(c->payload));

if (WW_UNLIKELY(bufLen(c->payload) < 1))
if (WW_UNLIKELY(bufLen(c->payload) < sizeof(struct ipv4hdr)))
{
LOGW("Layer3IpOverrider: dropped a packet that was too small");
dropContexPayload(c);
destroyContext(c);
return;
}
packet_mask *packet = (packet_mask *) (rawBufMut(c->payload));

bool isv4 = ip4_header->version == 4;

if (isv4)
if (packet->ip4_header.version == 4)
{
if (! state->support4)
{
goto bypass;
}
if (WW_UNLIKELY(bufLen(c->payload) < sizeof(struct ipv4hdr)))
// alignment must be correct
packet->ip4_header.saddr = state->ov_4;
}
else if (packet->ip4_header.version == 6)
{
if (WW_UNLIKELY(bufLen(c->payload) < sizeof(struct ipv6hdr)))
{
LOGW("Layer3IpOverrider: dropped a packet that was too small");
LOGW("Layer3IpOverrider: dropped a ipv6 packet that was too small");
dropContexPayload(c);
destroyContext(c);
return;
}
// alignment must be correct
packet->ip6_header.saddr = state->ov_6;
}
else
{
if (! state->support6)
{
goto bypass;
}
if (WW_UNLIKELY(ip4_header->version != 6))
{
LOGW("Layer3IpOverrider: dropped a non ip protocol packet");
dropContexPayload(c);
destroyContext(c);
return;
}
LOGW("Layer3IpOverrider: dropped a non ip protocol packet");
dropContexPayload(c);
destroyContext(c);
return;
}

self->up->upStream(self->up, c);
}

enum mode_dynamic_value_status
{
kDvsSourceMode = kDvsFirstOption,
kDvsDestMode
};

static void upStreamDestMode(tunnel_t *self, context_t *c)
{
layer3_ip_overrider_state_t *state = TSTATE(self);

if (WW_UNLIKELY(bufLen(c->payload) < sizeof(struct ipv4hdr)))
{
LOGW("Layer3IpOverrider: dropped a packet that was too small");
dropContexPayload(c);
destroyContext(c);
return;
}
packet_mask *packet = (packet_mask *) (rawBufMut(c->payload));

if (packet->ip4_header.version == 4)
{
// alignment must be correct
packet->ip4_header.daddr = state->ov_4;
}
else if (packet->ip4_header.version == 6)
{
if (WW_UNLIKELY(bufLen(c->payload) < sizeof(struct ipv6hdr)))
{
LOGW("Layer3IpOverrider: dropped a packet that was too small");
LOGW("Layer3IpOverrider: dropped a ipv6 packet that was too small");
dropContexPayload(c);
destroyContext(c);
return;
}
}

bypass:
// alignment must be correct
packet->ip6_header.daddr = state->ov_6;
}
else
{
LOGW("Layer3IpOverrider: dropped a non ip protocol packet");
dropContexPayload(c);
destroyContext(c);
return;
}

self->up->upStream(self->up, c);
}

static void downStream(tunnel_t *self, context_t *c)
{
self->dw->downStream(self->dw, c);
Expand All @@ -136,9 +175,40 @@ tunnel_t *newLayer3IpOverrider(node_instance_context_t *instance_info)
return NULL;
}

tunnel_t *t = newTunnel();
dynamic_value_t mode_dv =
parseDynamicNumericValueFromJsonObject(settings, "mode", 2, "dest-override", "src-override");

if ((int) mode_dv.status != kDvsDestMode && (int) mode_dv.status != kDvsSourceMode)
{
LOGF("Layer3IpOverrider: Layer3IpOverrider->settings->mode (string field) mode is not set or invalid, do you "
"want to override source ip or dest ip?");
exit(1);
}

char ipbuf[128];

if (getStringFromJsonObject((char **) &ipbuf, settings, "ipv4"))
{
state->support4 = true;
sockaddr_u sa;
sockaddr_set_ip(&(sa), ipbuf);

memcpy(&(state->ov_4), &(sa.sin.sin_addr.s_addr), sizeof(sa.sin.sin_addr.s_addr));
}

if (getStringFromJsonObject((char **) &ipbuf, settings, "ipv6"))
{
state->support6 = true;
sockaddr_u sa;
sockaddr_set_ip(&(sa), ipbuf);

memcpy(&(state->ov_6), &(sa.sin6.sin6_addr.s6_addr), sizeof(sa.sin6.sin6_addr.s6_addr));
}

tunnel_t *t = newTunnel();

t->state = state;
t->upStream = &upStream;
t->upStream = ((int) mode_dv.status == kDvsDestMode) ? &upStreamDestMode : &upStreamSrcMode;
t->downStream = &downStream;

return t;
Expand Down

0 comments on commit d75608e

Please sign in to comment.