summaryrefslogtreecommitdiff
path: root/pjsip
diff options
context:
space:
mode:
Diffstat (limited to 'pjsip')
-rw-r--r--pjsip/build/test_pjsip.dsp4
-rw-r--r--pjsip/include/pjsua-lib/pjsua.h26
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c129
3 files changed, 139 insertions, 20 deletions
diff --git a/pjsip/build/test_pjsip.dsp b/pjsip/build/test_pjsip.dsp
index 27814458..aa7de06a 100644
--- a/pjsip/build/test_pjsip.dsp
+++ b/pjsip/build/test_pjsip.dsp
@@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /Zi /O2 /Ob2 /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "PJ_WIN32" /D "PJ_M_I386" /FR /FD /c
+# ADD CPP /nologo /MD /W3 /Zi /O2 /Ob2 /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../../pjnath/include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "PJ_WIN32" /D "PJ_M_I386" /FR /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
@@ -67,7 +67,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "PJ_WIN32" /D "PJ_M_I386" /FR /FD /GZ /c
+# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /I "../../pjnath/include" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D "PJ_WIN32" /D "PJ_M_I386" /FR /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h
index fcd0549a..fee08d33 100644
--- a/pjsip/include/pjsua-lib/pjsua.h
+++ b/pjsip/include/pjsua-lib/pjsua.h
@@ -903,12 +903,24 @@ typedef struct pjsua_config
pj_str_t outbound_proxy[4];
/**
- * Specify STUN server. This server will be first resolved with DNS SRV
- * to get the actual server address. If DNS SRV resolution failed, or
- * when nameserver is not configured, the server will be resolved using
- * DNS A resolution (i.e. gethostbyname()).
+ * Specify domain name to be resolved with DNS SRV resolution to get the
+ * address of the STUN servers. Alternatively application may specify
+ * \a stun_host and \a stun_relay_host instead.
+ *
+ * If DNS SRV resolution failed for this domain, then DNS A resolution
+ * will be performed only if \a stun_host is specified.
+ */
+ pj_str_t stun_domain;
+
+ /**
+ * Specify STUN server to be used.
+ */
+ pj_str_t stun_host;
+
+ /**
+ * Specify STUN relay server to be used.
*/
- pj_str_t stun_srv;
+ pj_str_t stun_relay_host;
/**
* Number of credentials in the credential array.
@@ -1009,7 +1021,9 @@ PJ_INLINE(void) pjsua_config_dup(pj_pool_t *pool,
}
pj_strdup_with_null(pool, &dst->user_agent, &src->user_agent);
- pj_strdup_with_null(pool, &dst->stun_srv, &src->stun_srv);
+ pj_strdup_with_null(pool, &dst->stun_domain, &src->stun_domain);
+ pj_strdup_with_null(pool, &dst->stun_host, &src->stun_host);
+ pj_strdup_with_null(pool, &dst->stun_relay_host, &src->stun_relay_host);
}
diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c
index fba772b7..d01a02b0 100644
--- a/pjsip/src/pjsua-lib/pjsua_core.c
+++ b/pjsip/src/pjsua-lib/pjsua_core.c
@@ -652,6 +652,75 @@ static void busy_sleep(unsigned msec)
} while (PJ_TIME_VAL_LT(now, timeout));
}
+
+static pj_status_t resolve_stun_server(pj_bool_t use_dns_srv);
+
+/*
+ * Callback function to receive notification from the resolver
+ * when the resolution process completes.
+ */
+static void stun_dns_srv_resolver_cb(void *user_data,
+ pj_status_t status,
+ const pj_dns_srv_record *rec)
+{
+ unsigned i;
+
+ PJ_UNUSED_ARG(user_data);
+
+ pjsua_var.stun_status = status;
+
+ if (status != PJ_SUCCESS) {
+ /* DNS SRV resolution failed. If stun_host is specified, resolve
+ * it with gethostbyname()
+ */
+ if (pjsua_var.ua_cfg.stun_host.slen) {
+ pj_hostent he;
+
+ pjsua_var.stun_status = pj_gethostbyname(&pjsua_var.ua_cfg.stun_host, &he);
+
+ if (pjsua_var.stun_status == PJ_SUCCESS) {
+ pj_sockaddr_in_init(&pjsua_var.stun_srv.ipv4, NULL, 0);
+ pjsua_var.stun_srv.ipv4.sin_addr = *(pj_in_addr*)he.h_addr;
+ pjsua_var.stun_srv.ipv4.sin_port = pj_htons((pj_uint16_t)3478);
+
+ PJ_LOG(3,(THIS_FILE,
+ "STUN server %.*s resolved, address is %s:%d",
+ (int)pjsua_var.ua_cfg.stun_host.slen,
+ pjsua_var.ua_cfg.stun_host.ptr,
+ pj_inet_ntoa(pjsua_var.stun_srv.ipv4.sin_addr),
+ (int)pj_ntohs(pjsua_var.stun_srv.ipv4.sin_port)));
+ }
+ } else {
+ char errmsg[PJ_ERR_MSG_SIZE];
+
+ pj_strerror(status, errmsg, sizeof(errmsg));
+ PJ_LOG(1,(THIS_FILE,
+ "DNS SRV resolution failed for STUN server %.*s: %s",
+ (int)pjsua_var.ua_cfg.stun_domain.slen,
+ pjsua_var.ua_cfg.stun_domain.ptr,
+ errmsg));
+ }
+ return;
+ }
+
+ pj_memcpy(&pjsua_var.stun_srv, &rec->entry[0].addr,
+ rec->entry[0].addr_len);
+
+ PJ_LOG(3,(THIS_FILE, "_stun._udp.%.*s resolved, found %d entry(s):",
+ (int)pjsua_var.ua_cfg.stun_domain.slen,
+ pjsua_var.ua_cfg.stun_domain.ptr,
+ rec->count));
+
+ for (i=0; i<rec->count; ++i) {
+ PJ_LOG(3,(THIS_FILE,
+ " %d: prio=%d, weight=%d %s:%d",
+ i, rec->entry[i].priority, rec->entry[i].weight,
+ pj_inet_ntoa(rec->entry[i].addr.ipv4.sin_addr),
+ (int)pj_ntohs(rec->entry[i].addr.ipv4.sin_port)));
+ }
+
+}
+
/*
* Resolve STUN server.
*/
@@ -664,37 +733,73 @@ pj_status_t pjsua_resolve_stun_server(pj_bool_t wait)
pjsip_endpt_get_timer_heap(pjsua_var.endpt));
/* Start STUN server resolution */
- /* For now just do DNS A resolution */
+
+ pjsua_var.stun_status = PJ_EPENDING;
- if (pjsua_var.ua_cfg.stun_srv.slen == 0) {
- pjsua_var.stun_status = PJ_SUCCESS;
- } else {
+ /* If stun_domain is specified, resolve STUN servers with DNS
+ * SRV resolution.
+ */
+ if (pjsua_var.ua_cfg.stun_domain.slen) {
+ pj_str_t res_type;
+
+ /* Fail if resolver is not configured */
+ if (pjsua_var.resolver == NULL) {
+ PJ_LOG(1,(THIS_FILE, "Nameserver must be configured when "
+ "stun_domain is specified"));
+ pjsua_var.stun_status = PJLIB_UTIL_EDNSNONS;
+ return PJLIB_UTIL_EDNSNONS;
+ }
+ res_type = pj_str("_stun._udp");
+ pjsua_var.stun_status =
+ pj_dns_srv_resolve(&pjsua_var.ua_cfg.stun_domain, &res_type,
+ 3478, pjsua_var.pool, pjsua_var.resolver,
+ 0, NULL, stun_dns_srv_resolver_cb);
+ if (pjsua_var.stun_status != PJ_SUCCESS) {
+ pjsua_perror(THIS_FILE, "Error starting DNS SRV resolution",
+ pjsua_var.stun_status);
+ return pjsua_var.stun_status;
+ }
+ }
+ /* Otherwise if stun_host is specified, resolve STUN server with
+ * gethostbyname().
+ */
+ else if (pjsua_var.ua_cfg.stun_host.slen) {
pj_hostent he;
- pjsua_var.stun_status =
- pj_gethostbyname(&pjsua_var.ua_cfg.stun_srv, &he);
+ pjsua_var.stun_status = pj_gethostbyname(&pjsua_var.ua_cfg.stun_host, &he);
if (pjsua_var.stun_status == PJ_SUCCESS) {
pj_sockaddr_in_init(&pjsua_var.stun_srv.ipv4, NULL, 0);
pjsua_var.stun_srv.ipv4.sin_addr = *(pj_in_addr*)he.h_addr;
pjsua_var.stun_srv.ipv4.sin_port = pj_htons((pj_uint16_t)3478);
- PJ_LOG(4,(THIS_FILE,
+ PJ_LOG(3,(THIS_FILE,
"STUN server %.*s resolved, address is %s:%d",
- (int)pjsua_var.ua_cfg.stun_srv.slen,
- pjsua_var.ua_cfg.stun_srv.ptr,
+ (int)pjsua_var.ua_cfg.stun_host.slen,
+ pjsua_var.ua_cfg.stun_host.ptr,
pj_inet_ntoa(pjsua_var.stun_srv.ipv4.sin_addr),
(int)pj_ntohs(pjsua_var.stun_srv.ipv4.sin_port)));
}
+
}
+ /* Otherwise disable STUN. */
+ else {
+ pjsua_var.stun_status = PJ_SUCCESS;
+ }
+
+
return pjsua_var.stun_status;
} else if (pjsua_var.stun_status == PJ_EPENDING) {
/* STUN server resolution has been started, wait for the
* result.
*/
- pj_assert(!"Should not happen");
- return PJ_EBUG;
+ if (wait) {
+ while (pjsua_var.stun_status == PJ_EPENDING)
+ pjsua_handle_events(10);
+ }
+
+ return pjsua_var.stun_status;
} else {
/* STUN server has been resolved, return the status */
@@ -946,7 +1051,7 @@ static pj_status_t create_sip_udp_sock(pj_in_addr bound_addr,
&stun_srv, 3478,
p_pub_addr);
if (status != PJ_SUCCESS) {
- pjsua_perror(THIS_FILE, "Error resolving with STUN", status);
+ pjsua_perror(THIS_FILE, "Error contacting STUN server", status);
pj_sock_close(sock);
return status;
}