Skip to content
Snippets Groups Projects
Commit 163d72fc authored by Andreas Traczyk's avatar Andreas Traczyk Committed by Sébastien Blin
Browse files

ice: filter local deprecated and tentative ipv6 addresses


As described in RFC 2462, an ipv6 address can have several states and
some should be ignored when initializing an ICE session:

In fact DEPRECATED address SHOULD NOT be used in new communications.
Also, a TENTATIVE address is not ready to be used too. So, this
patch ignores this kind of addresses when initializing a new connection.

Change-Id: I95637286eb68451352fd7289a49ddc3cdf5ac383
Gitlab: #29
Reviewed-by: default avatarAndreas Traczyk <andreas.traczyk@savoirfairelinux.com>
parent a2108540
No related branches found
No related tags found
No related merge requests found
...@@ -362,7 +362,7 @@ UNPACK = $(RM) -R $@ \ ...@@ -362,7 +362,7 @@ UNPACK = $(RM) -R $@ \
$(foreach f,$(filter %.tar.xz,$^), && tar xJf $(f) $(if ${BATCH_MODE},,-v)) \ $(foreach f,$(filter %.tar.xz,$^), && tar xJf $(f) $(if ${BATCH_MODE},,-v)) \
$(foreach f,$(filter %.zip,$^), && unzip $(if ${BATCH_MODE},-q) $(f)) $(foreach f,$(filter %.zip,$^), && unzip $(if ${BATCH_MODE},-q) $(f))
UNPACK_DIR = $(basename $(basename $(notdir $<))) UNPACK_DIR = $(basename $(basename $(notdir $<)))
APPLY = (cd $(UNPACK_DIR) && patch -fp1) < APPLY = (cd $(UNPACK_DIR) && patch -flp1) <
APPLY_BIN = (cd $(UNPACK_DIR) && patch --binary -flp1) < APPLY_BIN = (cd $(UNPACK_DIR) && patch --binary -flp1) <
pkg_static = (cd $(UNPACK_DIR) && ../../../contrib/src/pkg-static.sh $(1)) pkg_static = (cd $(UNPACK_DIR) && ../../../contrib/src/pkg-static.sh $(1))
MOVE = mv $(UNPACK_DIR) $@ && touch $@ MOVE = mv $(UNPACK_DIR) $@ && touch $@
......
...@@ -42,5 +42,5 @@ Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com> ...@@ -42,5 +42,5 @@ Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
@@ -325,3 +325,3 @@ @@ -325,3 +325,3 @@
#ifndef PJ_ICE_MAX_CHECKS #ifndef PJ_ICE_MAX_CHECKS
-# define PJ_ICE_MAX_CHECKS 32 -# define PJ_ICE_MAX_CHECKS 32
+# define PJ_ICE_MAX_CHECKS 150 +# define PJ_ICE_MAX_CHECKS 1024
#endif #endif
From 2c4a267fbd68f394630acbab0a0e358d0c905464 Mon Sep 17 00:00:00 2001
From: Sebastien Blin <sebastien.blin@savoirfairelinux.com>
Date: Wed, 18 Jul 2018 12:12:04 -0400
Subject: [PATCH 1/1] RFC 2466: ignore deprecated candidates for new ICE
candidates
---
pjnath/src/pjnath/ice_session.c | 162 ++++++++++++++++++++++++++++++++
1 file changed, 162 insertions(+)
diff --git a/pjnath/src/pjnath/ice_session.c b/pjnath/src/pjnath/ice_session.c
index 63a0d1c9..6cae6b2e 100644
--- a/pjnath/src/pjnath/ice_session.c
+++ b/pjnath/src/pjnath/ice_session.c
@@ -29,6 +29,21 @@
#include <pj/rand.h>
#include <pj/string.h>
+#if defined(_WIN32) || defined(__APPLE__)
+/* TODO(sblin): find an alternative for these paltforms */
+#else
+/* The following headers are used to get DEPRECATED addresses
+ * as specified in RFC 2462 Section 5.5.4
+ * https://tools.ietf.org/html/rfc2462#section-5.5.4
+ */
+#include <arpa/inet.h>
+#include <asm/types.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#endif
+
/* String names for candidate types */
static const char *cand_type_names[] =
{
@@ -701,6 +716,128 @@ static pj_uint32_t CALC_CAND_PRIO(pj_ice_sess *ice,
#endif
}
+/* retrieve invalid addresses and store it in a string */
+static PJ_DEF(void) get_invalid_addresses(char** addresses, size_t* size)
+{
+#if defined(_WIN32) || defined(__APPLE__)
+ /* TODO(sblin): find an alternative for these paltforms */
+#else
+ struct {
+ struct nlmsghdr nlmsg_info;
+ struct ifaddrmsg ifaddrmsg_info;
+ } netlink_req;
+
+ int fd;
+
+ long pagesize = sysconf(_SC_PAGESIZE);
+
+ if (!pagesize)
+ pagesize = 4096; /* Assume pagesize is 4096 if sysconf() failed */
+
+ fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+ if(fd < 0) {
+ perror("socket initialization error: abort");
+ return;
+ }
+
+ int rtn;
+
+ bzero(&netlink_req, sizeof(netlink_req));
+
+ netlink_req.nlmsg_info.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
+ netlink_req.nlmsg_info.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
+ netlink_req.nlmsg_info.nlmsg_type = RTM_GETADDR;
+ netlink_req.nlmsg_info.nlmsg_pid = getpid();
+
+ netlink_req.ifaddrmsg_info.ifa_family = AF_INET6;
+
+ rtn = send(fd, &netlink_req, netlink_req.nlmsg_info.nlmsg_len, 0);
+ if(rtn < 0) {
+ perror("send error: abort");
+ return;
+ }
+
+ char read_buffer[pagesize];
+ struct nlmsghdr *nlmsg_ptr;
+ int nlmsg_len;
+
+ size_t idx = 0;
+ // Will store all deprecated addresses into a string
+ char* deprecatedAddrs = malloc(256*sizeof(char)*PJ_INET6_ADDRSTRLEN);
+ if (!deprecatedAddrs) {
+ perror("malloc error: abort");
+ return;
+ }
+
+ while(1) {
+ int rtn;
+
+ bzero(read_buffer, pagesize);
+ rtn = recv(fd, read_buffer, pagesize, 0);
+ if(rtn < 0) {
+ perror ("recv(): ");
+ return;
+ }
+
+ nlmsg_ptr = (struct nlmsghdr *) read_buffer;
+ nlmsg_len = rtn;
+
+ if (nlmsg_len < sizeof (struct nlmsghdr)) {
+ perror ("Received an uncomplete netlink packet");
+ return;
+ }
+
+ if (nlmsg_ptr->nlmsg_type == NLMSG_DONE)
+ break;
+
+ for(; NLMSG_OK(nlmsg_ptr, nlmsg_len); nlmsg_ptr = NLMSG_NEXT(nlmsg_ptr, nlmsg_len)) {
+ struct ifaddrmsg *ifaddrmsg_ptr;
+ struct rtattr *rtattr_ptr;
+ int ifaddrmsg_len;
+
+ ifaddrmsg_ptr = (struct ifaddrmsg *) NLMSG_DATA(nlmsg_ptr);
+
+ if (ifaddrmsg_ptr->ifa_flags & IFA_F_DEPRECATED || ifaddrmsg_ptr->ifa_flags & IFA_F_TENTATIVE) {
+ rtattr_ptr = (struct rtattr *) IFA_RTA(ifaddrmsg_ptr);
+ ifaddrmsg_len = IFA_PAYLOAD(nlmsg_ptr);
+
+ for(;RTA_OK(rtattr_ptr, ifaddrmsg_len); rtattr_ptr = RTA_NEXT(rtattr_ptr, ifaddrmsg_len)) {
+ switch(rtattr_ptr->rta_type) {
+ case IFA_ADDRESS:
+ // Any 256 obsolete ips (should not happen), resize the array.
+ if (idx > 0 && idx % 256 == 0) {
+ char* newDeprecated = realloc(deprecatedAddrs, (idx + 256)*sizeof(char)*PJ_INET6_ADDRSTRLEN);
+ if (!newDeprecated) {
+ perror("realloc error: abort");
+ return;
+ }
+ deprecatedAddrs = newDeprecated;
+ }
+ // Store deprecated IP
+ inet_ntop(ifaddrmsg_ptr->ifa_family, RTA_DATA(rtattr_ptr), &deprecatedAddrs[idx*PJ_INET6_ADDRSTRLEN], sizeof(char)*PJ_INET6_ADDRSTRLEN);
+ ++idx;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ close(fd);
+ *size = idx;
+ char *final = realloc(deprecatedAddrs, idx*sizeof(char)*PJ_INET6_ADDRSTRLEN);
+ if (!final) {
+ perror("realloc error: abort");
+ return;
+ } else {
+ *addresses = final;
+ }
+#endif
+}
+
+
/*
* Add ICE candidate
@@ -717,6 +854,31 @@ PJ_DEF(pj_status_t) pj_ice_sess_add_cand(pj_ice_sess *ice,
int addr_len,
unsigned *p_cand_id)
{
+
+
+ /**
+ * RFC 2466: an ip address can have the status DEPRECATED and SHOULD NOT
+ * be used by new by applications unless they already use it.
+ * So, we should ignore these addresses.
+ * Also, ips with the TENTATIVE state are not ready and SHOULD NOT be
+ * used for now. Ignore these addresses too.
+ */
+ char* deprecatedAddrs = NULL;
+ size_t size = 0;
+ get_invalid_addresses(&deprecatedAddrs, &size);
+ if (deprecatedAddrs != NULL) {
+ char tmpAddrStr[PJ_INET6_ADDRSTRLEN];
+ pj_sockaddr_print(addr, tmpAddrStr, sizeof(tmpAddrStr), 0);
+ for (int i = 0; i < size * PJ_INET6_ADDRSTRLEN; i += PJ_INET6_ADDRSTRLEN) {
+ if (strncmp(tmpAddrStr, &deprecatedAddrs[i], PJ_INET6_ADDRSTRLEN) == 0) {
+ free(deprecatedAddrs);
+ // This address is considered as deprecated so, we can ignore this one.
+ return PJ_SUCCESS;
+ }
+ }
+ free(deprecatedAddrs);
+ }
+
pj_ice_sess_cand *lcand;
pj_status_t status = PJ_SUCCESS;
char address[PJ_INET6_ADDRSTRLEN];
--
2.17.1
...@@ -34,8 +34,8 @@ ifdef HAVE_IOS ...@@ -34,8 +34,8 @@ ifdef HAVE_IOS
PJPROJECT_OPTIONS += --with-ssl=$(PREFIX) PJPROJECT_OPTIONS += --with-ssl=$(PREFIX)
endif endif
PJPROJECT_EXTRA_CFLAGS = -g -DPJ_ENABLE_EXTRA_CHECK=1 -DPJ_ICE_MAX_CAND=256 -DPJ_ICE_MAX_CHECKS=150 -DPJ_ICE_COMP_BITS=2 -DPJ_ICE_MAX_STUN=3 -DPJSIP_MAX_PKT_LEN=8000 -DPJ_ICE_ST_MAX_CAND=32 PJPROJECT_EXTRA_CFLAGS = -g -DPJ_ENABLE_EXTRA_CHECK=1 -DPJ_ICE_MAX_CAND=256 -DPJ_ICE_MAX_CHECKS=1024 -DPJ_ICE_COMP_BITS=2 -DPJ_ICE_MAX_STUN=3 -DPJSIP_MAX_PKT_LEN=8000 -DPJ_ICE_ST_MAX_CAND=32
PJPROJECT_EXTRA_CXXFLAGS = -g -DPJ_ENABLE_EXTRA_CHECK=1 -DPJ_ICE_MAX_CAND=256 -DPJ_ICE_MAX_CHECKS=150 -DPJ_ICE_COMP_BITS=2 -DPJ_ICE_MAX_STUN=3 -DPJSIP_MAX_PKT_LEN=8000 -DPJ_ICE_ST_MAX_CAND=32 -std=gnu++11 PJPROJECT_EXTRA_CXXFLAGS = -g -DPJ_ENABLE_EXTRA_CHECK=1 -DPJ_ICE_MAX_CAND=256 -DPJ_ICE_MAX_CHECKS=1024 -DPJ_ICE_COMP_BITS=2 -DPJ_ICE_MAX_STUN=3 -DPJSIP_MAX_PKT_LEN=8000 -DPJ_ICE_ST_MAX_CAND=32 -std=gnu++11
ifdef HAVE_WIN64 ifdef HAVE_WIN64
PJPROJECT_EXTRA_CFLAGS += -DPJ_WIN64=1 PJPROJECT_EXTRA_CFLAGS += -DPJ_WIN64=1
...@@ -69,6 +69,7 @@ endif ...@@ -69,6 +69,7 @@ endif
ifdef HAVE_ANDROID ifdef HAVE_ANDROID
$(APPLY) $(SRC)/pjproject/android.patch $(APPLY) $(SRC)/pjproject/android.patch
endif endif
$(APPLY) $(SRC)/pjproject/rfc2466.patch
$(APPLY) $(SRC)/pjproject/ipv6.patch $(APPLY) $(SRC)/pjproject/ipv6.patch
$(APPLY) $(SRC)/pjproject/ice_config.patch $(APPLY) $(SRC)/pjproject/ice_config.patch
$(APPLY) $(SRC)/pjproject/multiple_listeners.patch $(APPLY) $(SRC)/pjproject/multiple_listeners.patch
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment