summaryrefslogtreecommitdiff
path: root/pjlib
diff options
context:
space:
mode:
authorNanang Izzuddin <nanang@teluu.com>2013-02-07 09:35:34 +0000
committerNanang Izzuddin <nanang@teluu.com>2013-02-07 09:35:34 +0000
commitcdb0f86fac81b206ee8e260d2b344e36cb3ac0aa (patch)
treea9d4aa8d94fc7e0ccfce07ff99d4e078008bb14d /pjlib
parent7b7c7c8b42a8c25b30b07a8cd524cccbb60173b3 (diff)
Close #1602: configurable local port range for ICE transport.
git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4343 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjlib')
-rw-r--r--pjlib/include/pj/sock.h18
-rw-r--r--pjlib/src/pj/sock_common.c39
2 files changed, 57 insertions, 0 deletions
diff --git a/pjlib/include/pj/sock.h b/pjlib/include/pj/sock.h
index 83d35db9..4011f21a 100644
--- a/pjlib/include/pj/sock.h
+++ b/pjlib/include/pj/sock.h
@@ -1166,6 +1166,24 @@ PJ_DECL(pj_status_t) pj_sock_bind_in( pj_sock_t sockfd,
pj_uint32_t addr,
pj_uint16_t port);
+/**
+ * Bind the IP socket sockfd to the given address and a random port in the
+ * specified range.
+ *
+ * @param sockfd The socket desriptor.
+ * @param addr The local address and port to bind the socket to.
+ * @param port_range The port range, relative the to start port number
+ * specified in port field in #addr. Note that if the
+ * port is zero, this param will be ignored.
+ * @param max_try Maximum retries.
+ *
+ * @return Zero on success.
+ */
+PJ_DECL(pj_status_t) pj_sock_bind_random( pj_sock_t sockfd,
+ const pj_sockaddr_t *addr,
+ pj_uint16_t port_range,
+ pj_uint16_t max_try);
+
#if PJ_HAS_TCP
/**
* Listen for incoming connection. This function only applies to connection
diff --git a/pjlib/src/pj/sock_common.c b/pjlib/src/pj/sock_common.c
index 7aaf6689..eb338e73 100644
--- a/pjlib/src/pj/sock_common.c
+++ b/pjlib/src/pj/sock_common.c
@@ -24,6 +24,7 @@
#include <pj/ip_helper.h>
#include <pj/os.h>
#include <pj/addr_resolv.h>
+#include <pj/rand.h>
#include <pj/string.h>
#include <pj/compat/socket.h>
@@ -1040,6 +1041,44 @@ PJ_DEF(pj_status_t) pj_getdefaultipinterface(int af, pj_sockaddr *addr)
}
+/*
+ * Bind socket at random port.
+ */
+PJ_DEF(pj_status_t) pj_sock_bind_random( pj_sock_t sockfd,
+ const pj_sockaddr_t *addr,
+ pj_uint16_t port_range,
+ pj_uint16_t max_try)
+{
+ pj_sockaddr bind_addr;
+ int addr_len;
+ pj_uint16_t base_port;
+ pj_status_t status = PJ_SUCCESS;
+
+ PJ_CHECK_STACK();
+
+ PJ_ASSERT_RETURN(addr, PJ_EINVAL);
+
+ pj_sockaddr_cp(&bind_addr, addr);
+ addr_len = pj_sockaddr_get_len(addr);
+ base_port = pj_sockaddr_get_port(addr);
+
+ if (base_port == 0 || port_range == 0) {
+ return pj_sock_bind(sockfd, &bind_addr, addr_len);
+ }
+
+ for (; max_try; --max_try) {
+ pj_uint16_t port;
+ port = (pj_uint16_t)(base_port + pj_rand() % (port_range + 1));
+ pj_sockaddr_set_port(&bind_addr, port);
+ status = pj_sock_bind(sockfd, &bind_addr, addr_len);
+ if (status == PJ_SUCCESS)
+ break;
+ }
+
+ return status;
+}
+
+
/* Only need to implement these in DLL build */
#if defined(PJ_DLL)