From bdb97c538769c1d3318bae1f4230f626640fb20c Mon Sep 17 00:00:00 2001 From: Dmitriy Shamaev Date: Fri, 22 Mar 2024 13:27:52 +0200 Subject: [PATCH] reworked infrastructure for pjnat64 module --- Makefile | 2 +- ios_framework/build_ios_framework.sh | 1 + pjnat64/build/Makefile | 88 +++++ .../include/pjnat64}/pj-nat64.h | 9 - .../pjnath => pjnat64/src/pjnat64}/pj-nat64.c | 154 +++++--- pjnath/build/Makefile | 53 +-- pjnath/include/pjnath.h | 1 - pjnath/src/pjnath/pj-nat64-compat.c | 340 ------------------ 8 files changed, 199 insertions(+), 449 deletions(-) create mode 100644 pjnat64/build/Makefile rename {pjnath/include/pjnath => pjnat64/include/pjnat64}/pj-nat64.h (85%) rename {pjnath/src/pjnath => pjnat64/src/pjnat64}/pj-nat64.c (88%) delete mode 100644 pjnath/src/pjnath/pj-nat64-compat.c diff --git a/Makefile b/Makefile index 0891744f9d..1fcb542945 100644 --- a/Makefile +++ b/Makefile @@ -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 diff --git a/ios_framework/build_ios_framework.sh b/ios_framework/build_ios_framework.sh index 5840890702..56115d62da 100755 --- a/ios_framework/build_ios_framework.sh +++ b/ios_framework/build_ios_framework.sh @@ -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 diff --git a/pjnat64/build/Makefile b/pjnat64/build/Makefile new file mode 100644 index 0000000000..63599fbc88 --- /dev/null +++ b/pjnat64/build/Makefile @@ -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 $@ diff --git a/pjnath/include/pjnath/pj-nat64.h b/pjnat64/include/pjnat64/pj-nat64.h similarity index 85% rename from pjnath/include/pjnath/pj-nat64.h rename to pjnat64/include/pjnat64/pj-nat64.h index ed77c202b0..686df67a92 100644 --- a/pjnath/include/pjnath/pj-nat64.h +++ b/pjnat64/include/pjnat64/pj-nat64.h @@ -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 /** diff --git a/pjnath/src/pjnath/pj-nat64.c b/pjnat64/src/pjnat64/pj-nat64.c similarity index 88% rename from pjnath/src/pjnath/pj-nat64.c rename to pjnat64/src/pjnat64/pj-nat64.c index b778bfa925..4b1a8d372d 100644 --- a/pjnath/src/pjnath/pj-nat64.c +++ b/pjnat64/src/pjnat64/pj-nat64.c @@ -1,14 +1,26 @@ #include + #include #include + #include -#include -#include +#include #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); @@ -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; } } @@ -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; } } @@ -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; } } @@ -979,26 +1017,34 @@ 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 + )); } @@ -1006,6 +1052,10 @@ 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 diff --git a/pjnath/build/Makefile b/pjnath/build/Makefile index bd2971705c..16efeac209 100644 --- a/pjnath/build/Makefile +++ b/pjnath/build/Makefile @@ -27,8 +27,7 @@ endif # export _CFLAGS := $(CC_CFLAGS) $(OS_CFLAGS) $(HOST_CFLAGS) $(M_CFLAGS) \ $(CFLAGS) $(CC_INC)../include $(CC_INC)../../pjlib/include \ - $(CC_INC)../../pjlib-util/include $(CC_INC)../../pjsip/include \ - $(CC_INC)../../pjmedia/include + $(CC_INC)../../pjlib-util/include export _CXXFLAGS:= $(_CFLAGS) $(CC_CXXFLAGS) $(OS_CXXFLAGS) $(M_CXXFLAGS) \ $(HOST_CXXFLAGS) $(CXXFLAGS) export _LDFLAGS := $(CC_LDFLAGS) $(OS_LDFLAGS) $(M_LDFLAGS) $(HOST_LDFLAGS) \ @@ -39,21 +38,12 @@ export _LDFLAGS := $(CC_LDFLAGS) $(OS_LDFLAGS) $(M_LDFLAGS) $(HOST_LDFLAGS) \ # export PJNATH_SRCDIR = ../src/pjnath export PJNATH_OBJS += $(OS_OBJS) $(M_OBJS) $(CC_OBJS) $(HOST_OBJS) \ - errno.o ice_session.o ice_strans.o nat_detect.o pj-nat64.o stun_auth.o \ + errno.o ice_session.o ice_strans.o nat_detect.o stun_auth.o \ stun_msg.o stun_msg_dump.o stun_session.o stun_sock.o \ stun_transaction.o turn_session.o turn_sock.o upnp.o export PJNATH_CFLAGS += $(_CFLAGS) export PJNATH_CXXFLAGS += $(_CXXFLAGS) -export PJNATH_LDFLAGS += \ - $(PJNATH_LDLIB) \ - $(PJLIB_UTIL_LDLIB) \ - $(PJLIB_LDLIB) \ - $(PJSIP_SIMPLE_LDBLIB) \ - $(PJSIP_LDLIB) \ - $(PJSIP_UA_LDLIB) \ - $(PJSUA_LIB_LDLIB) \ - $(PJMEDIA_LDLIB) \ - $(_LDFLAGS) +export PJNATH_LDFLAGS += $(PJLIB_UTIL_LDLIB) $(PJLIB_LDLIB) $(_LDFLAGS) ############################################################################### # Defines for building test application @@ -63,16 +53,7 @@ export PJNATH_TEST_OBJS += ice_test.o stun.o sess_auth.o server.o concur_test.o stun_sock_test.o turn_sock_test.o test.o export PJNATH_TEST_CFLAGS += $(_CFLAGS) export PJNATH_TEST_CXXFLAGS += $(_CXXFLAGS) -export PJNATH_TEST_LDFLAGS += \ - $(PJNATH_LDLIB) \ - $(PJLIB_UTIL_LDLIB) \ - $(PJLIB_LDLIB) \ - $(PJSIP_SIMPLE_LDBLIB) \ - $(PJSIP_LDLIB) \ - $(PJSIP_UA_LDLIB) \ - $(PJSUA_LIB_LDLIB) \ - $(PJMEDIA_LDLIB) \ - $(_LDFLAGS) +export PJNATH_TEST_LDFLAGS += $(PJNATH_LDLIB) $(PJLIB_UTIL_LDLIB) $(PJLIB_LDLIB) $(_LDFLAGS) ifeq ($(EXCLUDE_APP),0) export PJNATH_TEST_EXE:=pjnath-test-$(TARGET_NAME)$(HOST_EXE) endif @@ -84,16 +65,7 @@ export PJTURN_CLIENT_SRCDIR = ../src/pjturn-client export PJTURN_CLIENT_OBJS += client_main.o export PJTURN_CLIENT_CFLAGS += $(_CFLAGS) export PJTURN_CLIENT_CXXFLAGS += $(_CXXFLAGS) -export PJTURN_CLIENT_LDFLAGS += \ - $(PJNATH_LDLIB) \ - $(PJLIB_UTIL_LDLIB) \ - $(PJLIB_LDLIB) \ - $(PJSIP_SIMPLE_LDBLIB) \ - $(PJSIP_LDLIB) \ - $(PJSIP_UA_LDLIB) \ - $(PJSUA_LIB_LDLIB) \ - $(PJMEDIA_LDLIB) \ - $(_LDFLAGS) +export PJTURN_CLIENT_LDFLAGS += $(PJNATH_LDLIB) $(PJLIB_UTIL_LDLIB) $(PJLIB_LDLIB) $(_LDFLAGS) ifeq ($(EXCLUDE_APP),0) export PJTURN_CLIENT_EXE:=pjturn-client-$(TARGET_NAME)$(HOST_EXE) endif @@ -106,16 +78,7 @@ export PJTURN_SRV_OBJS += allocation.o auth.o listener_udp.o \ listener_tcp.o server.o main.o export PJTURN_SRV_CFLAGS += $(_CFLAGS) export PJTURN_SRV_CXXFLAGS += $(_CXXFLAGS) -export PJTURN_SRV_LDFLAGS += \ - $(PJNATH_LDLIB) \ - $(PJLIB_UTIL_LDLIB) \ - $(PJLIB_LDLIB) \ - $(PJSIP_SIMPLE_LDBLIB) \ - $(PJSIP_LDLIB) \ - $(PJSIP_UA_LDLIB) \ - $(PJSUA_LIB_LDLIB) \ - $(PJMEDIA_LDLIB) \ - $(_LDFLAGS) +export PJTURN_SRV_LDFLAGS += $(PJNATH_LDLIB) $(PJLIB_UTIL_LDLIB) $(PJLIB_LDLIB) $(_LDFLAGS) ifeq ($(EXCLUDE_APP),0) export PJTURN_SRV_EXE:=pjturn-srv-$(TARGET_NAME)$(HOST_EXE) endif @@ -199,6 +162,4 @@ depend: $(MAKE) -f $(RULES_MAK) APP=PJTURN_SRV app=pjturn-srv $@ echo '$(BINDIR)/$(PJNATH_TEST_EXE): $(LIBDIR)/$(PJNATH_LIB) $(PJLIB_UTIL_LIB) $(PJLIB_LIB)' >> .pjnath-test-$(TARGET_NAME).depend echo '$(BINDIR)/$(PJTURN_CLIENT_EXE): $(LIBDIR)/$(PJNATH_LIB) $(PJLIB_UTIL_LIB) $(PJLIB_LIB)' >> .pjturn-client-$(TARGET_NAME).depend - echo '$(BINDIR)/$(PJTURN_SRV_EXE): $(LIBDIR)/$(PJNATH_LIB) $(PJLIB_UTIL_LIB) $(PJLIB_LIB)' >> .pjturn-srv-$(TARGET_NAME).depend - - + echo '$(BINDIR)/$(PJTURN_SRV_EXE): $(LIBDIR)/$(PJNATH_LIB) $(PJLIB_UTIL_LIB) $(PJLIB_LIB)' >> .pjturn-srv-$(TARGET_NAME).depend \ No newline at end of file diff --git a/pjnath/include/pjnath.h b/pjnath/include/pjnath.h index 57babd3e96..5653999ffc 100644 --- a/pjnath/include/pjnath.h +++ b/pjnath/include/pjnath.h @@ -38,7 +38,6 @@ #include #include #include -#include /* UPnP */ #include diff --git a/pjnath/src/pjnath/pj-nat64-compat.c b/pjnath/src/pjnath/pj-nat64-compat.c deleted file mode 100644 index 0b9a5d4912..0000000000 --- a/pjnath/src/pjnath/pj-nat64-compat.c +++ /dev/null @@ -1,340 +0,0 @@ - -static void on_syntax_error(pj_scanner *scanner) -{ - PJ_UNUSED_ARG(scanner); - int pos = pj_scan_get_col(scanner); - PJ_LOG(4, (THIS_FILE, "Scanner syntax error at %d: '%s'", pos, scanner->curptr)); - PJ_THROW(PJ_EINVAL); -} - -//Helper function to find a specific string using the scanner. -//It returns the pointer to where the string is found and the number of chars parsed (i.e. not the length of the string) -void scanner_find_string( pj_scanner *scanner, char* wanted, pj_str_t *result) -{ - pj_scan_state state; - pj_scan_save_state( scanner, &state); - do { - pj_scan_get_until_ch(scanner, wanted[0], result); - if (pj_scan_strcmp(scanner, wanted, (int)strlen(wanted)) == 0) { - //Found wanted string, update real scanner - unsigned steps_to_advance = (unsigned)(scanner->curptr - state.curptr); - pj_scan_restore_state(scanner, &state); - pj_scan_advance_n(scanner, steps_to_advance, PJ_FALSE); - result->ptr = scanner->curptr; - result->slen = steps_to_advance; - break; - } else { - pj_scan_advance_n(scanner, 1, PJ_FALSE); - } - - if (pj_scan_is_eof(scanner)) { - PJ_LOG(4, (THIS_FILE, "Scanner EOF")); - break; - } - - } while (1); -} - -static int calculate_new_content_length(char* buffer) -{ - char* body_delim = "\r\n\r\n"; //Sip message body starts with a newline and final empty line after sdp does not count - char* body_start = strstr(buffer, body_delim); - if (body_start != NULL) { - body_start = body_start + strlen(body_delim); - return (int)strlen(body_start); - } else { - PJ_LOG(1, (THIS_FILE, - "Error: Could not find Content-Length header. The correct length can not be set. This must never happen.")); - return -1; - } -} - - -static int update_content_length(char* buffer, pjsip_msg* msg) -{ -#define CONTENT_LEN_BUF_SIZE 10 - PJ_USE_EXCEPTION; - pj_scanner scanner; - pj_str_t result = {NULL, 0}; - pj_str_t current_content_len; - char* content_length = "Content-Length"; - char new_content_len_buf[CONTENT_LEN_BUF_SIZE]; - int new_content_len = calculate_new_content_length(buffer); - if (new_content_len == -1) { - return -1; - } - - //Step 1: Update the pjsip_msg to reflect the new body size (for incoming messages only) - if (msg != NULL) { - msg->body->len = (int)new_content_len; - } - - //Step 2: Rewrite the buffer so the Content-Length header is correct - pj_scan_init(&scanner, buffer, strlen(buffer), 0, &on_syntax_error); - - pj_ansi_snprintf(new_content_len_buf, CONTENT_LEN_BUF_SIZE, "%d", new_content_len); - - PJ_TRY { - scanner_find_string(&scanner, content_length, &result); - - pj_scan_get_until_chr(&scanner, "0123456789", &result); - - pj_scan_get_until_ch(&scanner, '\r', &result); - pj_strset(¤t_content_len, result.ptr, result.slen); - PJ_LOG(4, (THIS_FILE, "Current Content-Length is: %.*s and new Content-Length is %d .", current_content_len.slen, current_content_len.ptr, new_content_len)); - if (strlen(new_content_len_buf) <= current_content_len.slen) - { - int len_offset = (int)(result.ptr - scanner.begin); - PJ_LOG(4, (THIS_FILE, "Updated content length needs the same or less bytes, no need to do buffer copy")); - //even though scanner and buffer are in different memory locations the content is identical - pj_memset(buffer + len_offset, ' ', result.slen); - pj_memcpy(buffer + len_offset, new_content_len_buf, strlen(new_content_len_buf)); - } else { - PJ_TODO(SUPPORT_GROWING_THE_BUFFER); - PJ_LOG(4, (THIS_FILE, "Updated content length needs more bytes than old one, we must do expand and copy. TODO")); - } - } PJ_CATCH_ANY { - PJ_LOG(4, (THIS_FILE, "Exception thrown when searching for Content-Length, incorrect value will be used. Must never happen.")); - } - PJ_END; - pj_scan_fini(&scanner); - return new_content_len; -} - -/** - * For outgoing INVITE and 200 OK - * -**/ -static void replace_sdp_ipv6_with_ipv4(pjsip_tx_data *tdata) -{ - PJ_USE_EXCEPTION; - pj_scanner scanner; - pj_str_t result = {NULL, 0}; - char* org_buffer = tdata->buf.start; - char new_buffer[PJSIP_MAX_PKT_LEN]; - char* walker_p = new_buffer; - pj_str_t ipv4_str = pj_str("IP4"); - pj_str_t unroutable_host = pj_str("192.168.1.1"); - pj_bzero(new_buffer, PJSIP_MAX_PKT_LEN); - - PJ_LOG(4, (THIS_FILE, "**********Outgoing INVITE or 200 with IPv6 address*************")); - - /* Debug */ -// pjsip_server_addresses addr - PJ_LOG(4, (THIS_FILE, "Transport: addr.count = %u", tdata->dest_info.addr.count)); - for(unsigned idx=0; idx < tdata->dest_info.addr.count; idx++) { - pjsip_server_address_record *e = &tdata->dest_info.addr.entry[idx]; - - char src_rtp_name[1024] = { 0 }; - - int opt = 1 | 2; - pj_sockaddr_print(&e->addr, &src_rtp_name, 1024, opt); - - PJ_LOG(4, (THIS_FILE, "Resolver: num = %u addr = %s", idx, &src_rtp_name)); - - } - - -// PJ_LOG(4, (THIS_FILE, "Transport: addr.count = %u", tdata->tp_info.dst_addr)); -// PJ_LOG(4, (THIS_FILE, "Transport: addr.count = %u", tdata->via_addr)); - - pj_scan_init(&scanner, org_buffer, strlen(org_buffer), 0, &on_syntax_error); - - PJ_TRY { - do { - //Find instance of IP6 - scanner_find_string(&scanner, "IP6", &result); - pj_memcpy(walker_p, (result.ptr - result.slen), result.slen); - walker_p = walker_p + result.slen; - - //Replace with IP6 - pj_memcpy(walker_p, ipv4_str.ptr, ipv4_str.slen); - walker_p = walker_p + ipv4_str.slen; - pj_scan_get_n(&scanner, (int)ipv4_str.slen, &result); - - //Find start of IP address and copy (hopefully only 1 whitespace) - pj_scan_get_until_chr(&scanner, "0123456789abcdef", &result); - pj_memcpy(walker_p, result.ptr, result.slen); - walker_p = walker_p + result.slen; - - // Extract IP address - pj_scan_get_until_ch( &scanner, '\r', &result); - PJ_LOG(4, (THIS_FILE, "Extracted ip6 address as %.*s", result.slen, result.ptr)); - - // Replace with IPv4 address - pj_memcpy(walker_p, unroutable_host.ptr, unroutable_host.slen); - walker_p = walker_p + unroutable_host.slen; - - //In case this is the last occurance in the message, lets append the rest but do not advance walker_p in case there is more - //The scanner string is always null terminated so include the terminating character as well - pj_memcpy(walker_p, scanner.curptr, (scanner.end - scanner.curptr) +1); - } while (!pj_scan_is_eof(&scanner)); - - - } PJ_CATCH_ANY { - if (strlen(new_buffer) > 0) - { - pj_memcpy(org_buffer, new_buffer, strlen(new_buffer)); - org_buffer[strlen(new_buffer)] = '\0'; - update_content_length(tdata->buf.start, NULL); - PJ_LOG(4, (THIS_FILE, - "We have successfully parsed the INVITE/200 OK until EOF. Replace tx buffer. pjsip will now send the modified TX packet.")); - PJ_LOG(4, (THIS_FILE, "**********Modified outgoing INVITE or 200 with IPv6 address*************")); - PJ_LOG(4, (THIS_FILE, "%s", org_buffer)); - PJ_LOG(4, (THIS_FILE, "***************************************************************")); - } else { - PJ_LOG(1, (THIS_FILE, "Error: Parsing of the outgoing INVITE/200 OK failed at %s. Leave incoming buffer as is", scanner.curptr)); - } - pj_scan_fini(&scanner); - return; - } - PJ_END; - pj_scan_fini(&scanner); -} - - -//For incoming INVITE and 200 OK -static void replace_sdp_ipv4_with_ipv6(pjsip_rx_data *rdata) -{ - PJ_USE_EXCEPTION; - pj_scanner scanner; - pj_str_t result = {NULL, 0}; - char* org_buffer = rdata->msg_info.msg_buf; - char new_buffer[PJSIP_MAX_PKT_LEN]; - char* walker_p = new_buffer; - pj_str_t ipv6_str = pj_str("IP6"); - pj_str_t ipv6_example_str = pj_str("::1"); - - pj_bzero(new_buffer, PJSIP_MAX_PKT_LEN); - - PJ_LOG(4, (THIS_FILE, "**********Incoming INVITE or 200 with IPv4 address*************")); - PJ_LOG(4, (THIS_FILE, "%s", org_buffer)); - PJ_LOG(4, (THIS_FILE, "***************************************************************")); - - pj_scan_init(&scanner, org_buffer, strlen(org_buffer), 0, &on_syntax_error); - - PJ_TRY { - do { - //Find instance of IP4 - scanner_find_string(&scanner, "IP4", &result); - pj_memcpy(walker_p, (result.ptr - result.slen), result.slen); - walker_p = walker_p + result.slen; - - //Replace with IP6 - pj_memcpy(walker_p, ipv6_str.ptr, ipv6_str.slen); - walker_p = walker_p + ipv6_str.slen; - pj_scan_get_n(&scanner, (int)ipv6_str.slen, &result); - - //Find start of IP address and copy (hopefully only 1 whitespace) - pj_scan_get_until_chr(&scanner, "0123456789", &result); - pj_memcpy(walker_p, result.ptr, result.slen); - walker_p = walker_p + result.slen; - - //Extract IP address - pj_scan_get_until_ch( &scanner, '\r', &result); - PJ_LOG(4, (THIS_FILE, "Extracted IPv4 address '%.*s'", result.slen, result.ptr)); - - resolve_or_synthesize_ipv4_to_ipv6(&result, walker_p, (PJSIP_MAX_PKT_LEN - (int)strlen(walker_p))); - - //walker_p is now null terminated, reset it to point at the end of the current buffer (without null termination) - walker_p = walker_p + strlen(walker_p); - - //In case this is the last occurance in the message, lets append the rest but do not advance walker_p in case there is more - //The scanner string is always null terminated so include the terminating character as well - pj_memcpy(walker_p, scanner.curptr, (scanner.end - scanner.curptr) + 1); - - } while (!pj_scan_is_eof(&scanner)); - - } PJ_CATCH_ANY { - if (strlen(new_buffer) > 0) - { - pj_memcpy(org_buffer, new_buffer, strlen(new_buffer)); - org_buffer[strlen(new_buffer)] = '\0'; - update_content_length(org_buffer, rdata->msg_info.msg); - PJ_LOG(4, (THIS_FILE, - "We have successfully parsed the INVITE/200 OK until EOF. Replace rx buffer. pjsip will now print the modified rx packet.")); - //Update all internal packet sizes (body->len has already been updated by update_content_length) - rdata->pkt_info.len = strlen(rdata->pkt_info.packet); - rdata->msg_info.len = (int)rdata->pkt_info.len; - rdata->tp_info.transport->last_recv_len = rdata->pkt_info.len; - } else { - PJ_LOG(1, (THIS_FILE, "Error: Parsing of the incoming INVITE/200 OK failed at %s. Leave incoming buffer as is", scanner.curptr)); - } - pj_scan_fini(&scanner); - return; - } - PJ_END; - pj_scan_fini(&scanner); - return; -} - -static void replace_hostname_with_ip(char* proxy_hostname) -{ - pj_str_t hostname = pj_str(proxy_hostname); - unsigned int count = 1; - pj_addrinfo ai[1]; - pj_getaddrinfo(PJ_AF_UNSPEC, &hostname, &count, ai); - - if (count > 0) { - if (ai[0].ai_addr.addr.sa_family == PJ_AF_INET) { - pj_inet_ntop(PJ_AF_INET, &ai[0].ai_addr.ipv4.sin_addr, proxy_hostname, PJ_MAX_HOSTNAME); - } else if (ai[0].ai_addr.addr.sa_family == PJ_AF_INET6) { - proxy_hostname[0] = '['; - pj_inet_ntop(PJ_AF_INET6, &ai[0].ai_addr.ipv6.sin6_addr, proxy_hostname+1, PJ_MAX_HOSTNAME); - strcat(proxy_hostname, "]"); - - } - } -} - -pj_status_t pj_nat64_get_hostname_from_proxy_string(char* proxy, char* hostname_buf) -{ - pj_bool_t proxy_is_static_ip_v6_address = strchr(proxy, ']') != NULL ? PJ_TRUE : PJ_FALSE; - char* addr_start = strchr(proxy, ':'); - char* addr_end = NULL; - - if (addr_start != NULL) { - addr_start++; - if (proxy_is_static_ip_v6_address) { - addr_end = strstr(proxy, "]:"); - } else { - addr_end = strstr(addr_start, ":"); - } - if (addr_end != NULL) { - strncpy(hostname_buf, addr_start, addr_end-addr_start); - hostname_buf[addr_end - addr_start] = '\0'; - return PJ_SUCCESS; - } - } - return PJ_EIGNORED; -} - -pj_status_t pj_nat64_resolve_and_replace_hostname_with_ip_if_possible(char* proxy, char* resolved_proxy_buf) -{ - char hostname_buf[PJ_MAX_HOSTNAME]; - pj_bool_t proxy_is_static_ip_v6_address = strchr(proxy, ']') != NULL ? PJ_TRUE : PJ_FALSE; - char* addr_start = strchr(proxy, ':'); - char* addr_end = NULL; - - if (addr_start != NULL) { - addr_start++; - if (proxy_is_static_ip_v6_address) { - addr_end = strstr(proxy, "]:"); - } else { - addr_end = strstr(addr_start, ":"); - } - if (addr_end != NULL) { - size_t len_sip_sips = addr_start - proxy; - size_t len_port_and_tail = strlen(proxy) - (addr_end - - proxy); - strncpy(hostname_buf, addr_start, addr_end-addr_start); - hostname_buf[addr_end - addr_start] = '\0'; - - replace_hostname_with_ip(hostname_buf); - pj_ansi_snprintf(resolved_proxy_buf, PJ_MAX_HOSTNAME, "%.*s%s%.*s", (int)len_sip_sips, - proxy, hostname_buf, (int)len_port_and_tail, addr_end); - return PJ_SUCCESS; - } - } - return PJ_EIGNORED; -} \ No newline at end of file