Skip to content

Commit

Permalink
reworked infrastructure for pjnat64 module
Browse files Browse the repository at this point in the history
  • Loading branch information
dshamaev-intermedia committed Mar 22, 2024
1 parent 40c3c39 commit bdb97c5
Show file tree
Hide file tree
Showing 8 changed files with 199 additions and 449 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ include build/host-$(HOST_NAME).mak
-include user.mak
include version.mak

LIB_DIRS = pjlib/build pjlib-util/build third_party/build pjmedia/build pjsip/build pjnath/build
LIB_DIRS = pjlib/build pjlib-util/build pjnath/build third_party/build pjmedia/build pjsip/build pjnat64/build
DIRS = $(LIB_DIRS) pjsip-apps/build $(EXTRA_DIRS)

ifdef MINSIZE
Expand Down
1 change: 1 addition & 0 deletions ios_framework/build_ios_framework.sh
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ function copy_headers() {
cp -r ${source_dir}/pjlib-util/include/* $headers_dir
cp -r ${source_dir}/pjmedia/include/* $headers_dir
cp -r ${source_dir}/pjnath/include/* $headers_dir
cp -r ${source_dir}/pjnat64/include/* $headers_dir
#remove unneeded headers that was copied from "pjsip/include"
prev_dir=`pwd -P`
cd $headers_dir
Expand Down
88 changes: 88 additions & 0 deletions pjnat64/build/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@

include ../../build.mak
include ../../version.mak
include $(PJDIR)/build/common.mak

export LIBDIR := ../lib
export BINDIR := ../bin

RULES_MAK := $(PJDIR)/build/rules.mak

PJLIB_LIB:=../../pjlib/lib/libpj-$(TARGET_NAME)$(LIBEXT)
PJSIP_LIB:=../../pjsip/lib/libpjsip-$(TARGET_NAME)$(LIBEXT)
PJMEDIA_LIB:=../../pjmedia/lib/libpjmedia-$(TARGET_NAME)$(LIBEXT)
#PJSIP_SIMPLE_LIB :=
#PJSIP_UA_LIB :=
#PJSUA_LIB_LIB :=
#PJSUA2_LIB_LIB :=

export PJNAT64_LIB:=libpjnat64-$(TARGET_NAME)$(LIBEXT)

ifeq ($(PJ_SHARED_LIBRARIES),)
else
export PJNAT64_SONAME := libpjnat64.$(SHLIB_SUFFIX)
export PJNAT64_SHLIB := $(PJNAT64_SONAME).$(PJ_VERSION_MAJOR)
endif

###############################################################################
# Gather all flags.
#
export _CFLAGS := $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) \
$(CFLAGS) $(CC_INC)../include \
$(CC_INC)../../pjlib/include \
$(CC_INC)../../pjsip/include \
$(CC_INC)../../pjlib-util/include \
$(CC_INC)../../pjnath/include \
$(CC_INC)../../pjmedia/include
export _CXXFLAGS:= $(_CFLAGS) $(CC_CXXFLAGS) $(OS_CXXFLAGS) $(M_CXXFLAGS) \
$(HOST_CXXFLAGS) $(CXXFLAGS)
export _LDFLAGS := $(CC_LDFLAGS) $(OS_LDFLAGS) $(M_LDFLAGS) $(HOST_LDFLAGS) \
$(APP_LDFLAGS) $(LDFLAGS)

###############################################################################
# Defines for building PJNAT64 library
#
export PJNAT64_SRCDIR = ../src/pjnat64
export PJNAT64_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \
pj-nat64.o
export PJNAT64_CFLAGS += $(_CFLAGS)
export PJNAT64_CXXFLAGS += $(_CXXFLAGS)
export PJNAT64_LDFLAGS += $(PJLIB_LDLIB) $(PJSIP_LDLIB) $(PJMEDIA_LDLIB) $(_LDFLAGS)

###############################################################################
# Main entry

TARGETS := $(PJNAT64_LIB) $(PJNAT64_SONAME)

all: $(TARGETS)

lib: $(TARGETS)

doc:

dep: depend
distclean: realclean

.PHONY: all dep depend clean realclean distclean
.PHONY: $(TARGETS)
.PHONY: $(PJNAT64_LIB) $(PJNAT64_SONAME)

pjnat64: $(PJNAT64_LIB)
$(PJNAT64_SONAME): $(PJNAT64_LIB)
$(PJNAT64_LIB) $(PJNAT64_SONAME): $(PJLIB_LIB) $(PJLIB_SONAME) $(PJSIP_LIB) $(PJSIP_SONAME) $(PJMEDIA_LIB) $(PJMEDIA_SONAME)
$(MAKE) -f $(RULES_MAK) APP=PJNAT64 app=pjnat64 $(subst /,$(HOST_PSEP),$(LIBDIR)/$@)

.PHONY: pjnat64.ko
pjnat64.ko:
echo Making $@
$(MAKE) -f $(RULES_MAK) APP=PJNAT64 app=pjnat64 $(subst /,$(HOST_PSEP),$(LIBDIR)/$@)

clean:
$(MAKE) -f $(RULES_MAK) APP=PJNAT64 app=pjnat64 $@

realclean:
$(subst @@,$(subst /,$(HOST_PSEP),.pjnat64-$(TARGET_NAME).depend),$(HOST_RMR))
$(MAKE) -f $(RULES_MAK) APP=PJNAT64 app=pjnat64 $@

depend:
$(MAKE) -d -f $(RULES_MAK) APP=PJNAT64 app=pjnat64 $@
Original file line number Diff line number Diff line change
@@ -1,15 +1,6 @@
#ifndef PJ_NAT64_H_
#define PJ_NAT64_H_

/**
* Use algorithmic map
*
* @see https://datatracker.ietf.org/doc/html/rfc6052#section-2.1
*/
#ifndef USE_RFC6052
# define USE_RFC6052 0
#endif

PJ_BEGIN_DECL

/**
Expand Down
154 changes: 102 additions & 52 deletions pjnath/src/pjnath/pj-nat64.c → pjnat64/src/pjnat64/pj-nat64.c
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@

#include <pj/types.h>

#include <pjsip-ua/sip_inv.h>
#include <pjsip/sip_types.h>

#include <pjsua.h>
#include <pjsua-lib/pjsua_internal.h>

#include <pjnath/pj-nat64.h>
#include <pjnat64/pj-nat64.h>

#define THIS_FILE "pj_nat64.c"

#define MODULE_VERSION "$Id: 497af2bf5811a519a87deb9821451887ec3200e6 $"

/**
* Use algorithmic map
*
* @see https://datatracker.ietf.org/doc/html/rfc6052#section-2.1
*/
#ifndef USE_RFC6052
# define USE_RFC6052 0
#endif

/* Interface */

static void patch_sdp_attr(pj_pool_t *pool, pjmedia_sdp_media *media, pjmedia_sdp_attr *attr, pj_str_t addr_type, pj_str_t addr);
Expand Down Expand Up @@ -389,35 +401,52 @@ static void map_ipv4_with_ipv6(pj_pool_t *pool, pj_str_t *dst, pj_str_t *src)
{
pj_sockaddr src_addr;
pj_sockaddr dst_addr;
char prefix[4] = { 0x00, 0x64, 0xff, 0x9b }; // IPv6 map "64:ff96::/96"
pj_status_t status;
// IPv6 Well Known address - "64:ff96::/96"
// 00 64: ff 9b : 00 00 : 00 00 : 00 00 : 00 00 : 00 00 : 00 00
// 8 8 8 8
char prefix[16] = { 0x00, 0x64, 0xff, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

if (0 == pj_strcmp2(src, "127.0.0.1")) {
pj_strdup2(pool, dst, "[::1]");
} else {

/* Step 1. Parse source IP address */
// TODO - ...
unsigned options = 0;
status = pj_sockaddr_parse(PJ_AF_INET, options, (const pj_str_t *)src, &src_addr);
if (status != PJ_SUCCESS) {
PJ_LOG(1, (THIS_FILE, "Error parse address '%.*s'",
(int)src->slen, src->ptr
));
return;
}

if (src_addr.addr.sa_family == pj_AF_INET()) {
/* Step 2. */
if (src_addr.addr.sa_family == PJ_AF_INET) {

/* Step 1. Initialize result */
dst_addr.addr.sa_family = pj_AF_INET6();
dst_addr.ipv6.sin6_family = pj_AF_INET6();
dst_addr.ipv6.sin6_port = src_addr->ipv4.sin_port;
dst_addr.addr.sa_family = PJ_AF_INET6;
dst_addr.ipv6.sin6_family = PJ_AF_INET6;
dst_addr.ipv6.sin6_port = src_addr.ipv4.sin_port;
dst_addr.ipv6.sin6_flowinfo = 0;
dst_addr.ipv6.sin6_scope_id = 0;

/* Step 2. Map address with "::/96" subnet */
memset(&dst_addr.ipv6.sin6_addr, 0, sizeof(dst_addr.ipv6.sin6_addr));
memcpy(&dst_addr.ipv6.sin6_addr, prefix, sizeof(prefix));
memcpy(&dst_addr.ipv6.sin6_addr + 10, &src_addr.ipv4.sin_addr, sizeof(src_addr.ipv4.sin_addr));
char *ptr = &dst_addr.ipv6.sin6_addr;
memcpy(ptr, &prefix[0], sizeof(prefix));
memcpy(ptr + 12, &src_addr.ipv4.sin_addr, sizeof(src_addr.ipv4.sin_addr));

/* Step 3. Print result */
// TODO - print address at destination...
unsigned flags = 2;
char tmp[128] = { 0 };
pj_sockaddr_print(&dst_addr, tmp, 128, flags);
pj_strdup2(pool, dst, tmp);

} else {
PJ_LOG(4, (THIS_FILE, "Map IPv4 -> IPv6 address: provide IPv6 address: '%.*s'",
(int)src.slen. src.ptr
(int)src->slen, src->ptr
));
return;
}
}

Expand Down Expand Up @@ -465,39 +494,37 @@ static void map_ipv6_with_ipv4(pj_pool_t *pool, pj_str_t *dst, pj_str_t *src)
pj_strdup2(pool, dst, "127.0.0.1");
} else {

int af = pj_AF_INET6();
unsigned options = 0;
status = pj_sockaddr_parse(af, options, (const pj_str_t *)src, &src_addr);
status = pj_sockaddr_parse(PJ_AF_INET6, options, (const pj_str_t *)src, &src_addr);
if (status != PJ_SUCCESS) {
// TODO - What on error? Try resolve?
PJ_LOG(1, (THIS_FILE, "Error parse address '%.*s'",
(int)src->slen, src->ptr
));
return;
}

if (src_addr.addr.sa_family == pj_AF_INET6()) {

// TODO - check `pj_sockaddr_synthesize` ...
if (src_addr.addr.sa_family == PJ_AF_INET6) {

/* Step 1. Initialize result */
dst_addr.addr.sa_family = pj_AF_INET();
// dst_addr.ipv6.sin6_family = pj_AF_INET();
// dst_addr.ipv6.sin6_port = src_addr->ipv6.sin_port;
// dst_addr.ipv6.sin6_flowinfo = 0;
// dst_addr.ipv6.sin6_scope_id = 0;
dst_addr.addr.sa_family = PJ_AF_INET;
dst_addr.ipv4.sin_family = PJ_AF_INET;
dst_addr.ipv4.sin_port = src_addr.ipv6.sin6_port;

/* Step 2. Map address with "::/96" subnet */
// memset(&dst_addr.ipv6.sin6_addr, 0, sizeof(dst_addr.ipv6.sin6_addr));
// memcpy(&dst_addr.ipv6.sin6_addr, prefix, sizeof(prefix));
// memcpy(&dst_addr.ipv6.sin6_addr + 10, &src_addr.ipv4.sin_addr, sizeof(src_addr.ipv4.sin_addr));
char *ptr = &src_addr.ipv6.sin6_addr;
memset(&dst_addr.ipv4.sin_addr, 0, sizeof(dst_addr.ipv4.sin_addr));
memcpy(&dst_addr.ipv4.sin_addr, ptr + 12, sizeof(src_addr.ipv4.sin_addr));

/* Step 3. Print result */
// TODO - print address at destination...
unsigned flags = 2;
pj_sockaddr_print(&dst_addr, tmp, 128, flags);
pj_strdup(pool, dst, tmp);
pj_strdup2(pool, dst, tmp);

} else {
PJ_LOG(4, (THIS_FILE, "AMap IPv6 -> IPv4 address: provide IPv4 address: '%.*s'",
(int)src.slen. src.ptr
(int)src->slen, src->ptr
));
return;
}
}

Expand Down Expand Up @@ -734,16 +761,27 @@ static void patch_r_uri_ipv6_with_ipv4(pjsip_tx_data *tdata, pjsip_msg *msg)

/* Step 1. Patch R-URI on request */
if (msg->type == PJSIP_REQUEST_MSG) {
/* Step 1. Get actual R-URI address */
pjsip_sip_uri *sip_uri = (pjsip_sip_uri *)pjsip_uri_get_uri(msg->line.req.uri);
if (hpbx_in4_addr.slen > 0) {
PJ_LOG(5, (THIS_FILE, "TX patch R-URI at SIP message: '%.*s' -> '%.*s'",
sip_uri->host.slen, sip_uri->host.ptr,
hpbx_in4_addr.slen, hpbx_in4_addr.ptr
pj_str_t map_addr = { .slen = 0, .ptr = 0 };
/* Step 2. Map IPv6 -> IPv4 address */
map_ipv6_with_ipv4(pool, &map_addr, &sip_uri->host);
/* Step 3. No mapping use server address */
if (map_addr.slen == 0) {
PJ_LOG(5, (THIS_FILE, "TX patch R-URI addr use server '%.*s' (failback)",
(int)hpbx_in4_addr.slen, hpbx_in4_addr.ptr
));
sip_uri->host.slen = hpbx_in4_addr.slen;
sip_uri->host.ptr = hpbx_in4_addr.ptr;
} else {
PJ_LOG(5, (THIS_FILE, "TX no patch R-URI at SIP message: no IPv4 addr"));
map_addr.slen = hpbx_in4_addr.slen;
map_addr.ptr = hpbx_in4_addr.ptr;
}
/* Step 4. Mapping routine */
if (map_addr.slen > 0) {
PJ_LOG(5, (THIS_FILE, "TX patch R-URI addr '%.*s' -> '%.*s'",
(int)sip_uri->host.slen, sip_uri->host.ptr,
(int)map_addr.slen, map_addr.ptr
));
sip_uri->host.slen = map_addr.slen;
sip_uri->host.ptr = map_addr.ptr;
}
}

Expand Down Expand Up @@ -979,33 +1017,45 @@ static pjsip_module ipv6_module = {
static void check_network()
{
pj_status_t status;
int dst_af;
pj_sockaddr dst_addr = { 0 };
pj_sockaddr src_addr = { 0 };

/* Step 1. Get Well Know IPv4 network address, example: 8.8.8.8 */
// unsigned options = 0;
// pj_str_t addr = { .slen = 7, .ptr = "8.8.8.8" };
// status = pj_sockaddr_parse(PJ_AF_INET, options, &addr, &src_addr);
// if (status != PJ_SUCCESS) {
// PJ_LOG(5, (THIS_FILE, "Error parse IPv4 address"));
// return;
// }
unsigned options = 0;
pj_str_t src = { .slen = 7, .ptr = "8.8.8.8" };
status = pj_sockaddr_parse(PJ_AF_INET, options, &src, &src_addr);
if (status != PJ_SUCCESS) {
PJ_LOG(4, (THIS_FILE, "Network address synthesize: error parse IPv4 address"));
return;
}

/* Step 2. Create IPv6 addres */
// status = pj_sockaddr_synthesize(dst_af, &dst_addr, &src_addr);
// if (status == PJ_SUCCESS) {
// TODO - print new network address...
// } else {
// TODO - no network additional features...
// }
status = pj_sockaddr_synthesize(PJ_AF_INET6, &dst_addr, &src_addr);
if (status != PJ_SUCCESS) {
PJ_LOG(4, (THIS_FILE, "Network address synthesize: error synthesize"));
return;
}

/* Step 3. Debug convert address */
char buf[128] = { 0 };
pj_sockaddr_print(&dst_addr, buf, 128, 1 | 2);
pj_str_t dst = { .slen = 0, .ptr = buf };
dst.slen = strlen(dst.ptr);
PJ_LOG(4, (THIS_FILE, "Network address synthesize: covert IPv4 -> IPv6: %.*s -> %.*s",
(int)src.slen, src.ptr,
(int)dst.slen, dst.ptr
));

}

pj_status_t pj_nat64_enable_rewrite_module()
{
pjsip_endpoint *endpt = pjsua_get_pjsip_endpt();
pj_status_t result;

/* Step 0. Show module version */
PJ_LOG(4, (THIS_FILE, "Register NAT64 module version %s", MODULE_VERSION));

/* Step 1. Create module memory home */
if (mod_pool == NULL) {
#ifdef MOD_IPV6_ENDPT_MEMORY
Expand Down
Loading

0 comments on commit bdb97c5

Please sign in to comment.