summaryrefslogtreecommitdiff
path: root/pjsip/src/pjsua-lib/pjsua_core.c
diff options
context:
space:
mode:
Diffstat (limited to 'pjsip/src/pjsua-lib/pjsua_core.c')
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c129
1 files changed, 117 insertions, 12 deletions
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;
}