Changeset 2864 for pjproject/trunk
- Timestamp:
- Aug 12, 2009 11:03:23 AM (15 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app.c
r2862 r2864 191 191 puts (" --publish Send presence PUBLISH for this account"); 192 192 puts (" --use-100rel Require reliable provisional response (100rel)"); 193 puts (" --use-timer Require session timers");193 puts (" --use-timer Require SIP session timers"); 194 194 puts (" --timer-se Session timers expiration period, in secs (def:1800)"); 195 195 puts (" --timer-min-se Session timers minimum expiration period, in secs (def:90)"); … … 217 217 puts (" --outbound=url Set the URL of global outbound proxy server"); 218 218 puts (" May be specified multiple times"); 219 puts (" --stun-srv=name Set STUN server host or domain"); 219 puts (" --stun-srv=FORMAT Set STUN server host or domain. This option may be"); 220 puts (" specified more than once. FORMAT is hostdom[:PORT]"); 220 221 puts (""); 221 222 puts ("TLS Options:"); … … 478 479 OPT_BOUND_ADDR, OPT_CONTACT_PARAMS, OPT_CONTACT_URI_PARAMS, 479 480 OPT_100REL, OPT_USE_IMS, OPT_REALM, OPT_USERNAME, OPT_PASSWORD, 480 OPT_NAMESERVER, OPT_STUN_ DOMAIN, OPT_STUN_SRV,481 OPT_NAMESERVER, OPT_STUN_SRV, 481 482 OPT_ADD_BUDDY, OPT_OFFER_X_MS_MSG, OPT_NO_PRESENCE, 482 483 OPT_AUTO_ANSWER, OPT_AUTO_PLAY, OPT_AUTO_PLAY_HANGUP, OPT_AUTO_LOOP, … … 544 545 { "password", 1, 0, OPT_PASSWORD}, 545 546 { "nameserver", 1, 0, OPT_NAMESERVER}, 546 { "stun-domain",1, 0, OPT_STUN_DOMAIN},547 547 { "stun-srv", 1, 0, OPT_STUN_SRV}, 548 548 { "add-buddy", 1, 0, OPT_ADD_BUDDY}, … … 960 960 break; 961 961 962 case OPT_STUN_DOMAIN: /* STUN domain */963 cfg->cfg.stun_domain = pj_str(pj_optarg);964 break;965 966 962 case OPT_STUN_SRV: /* STUN server */ 967 963 cfg->cfg.stun_host = pj_str(pj_optarg); 964 if (cfg->cfg.stun_srv_cnt==PJ_ARRAY_SIZE(cfg->cfg.stun_srv)) { 965 PJ_LOG(1,(THIS_FILE, "Error: too many STUN servers")); 966 return PJ_ETOOMANY; 967 } 968 cfg->cfg.stun_srv[cfg->cfg.stun_srv_cnt++] = pj_str(pj_optarg); 968 969 break; 969 970 … … 1616 1617 1617 1618 /* STUN */ 1618 if (config->cfg.stun_domain.slen) { 1619 pj_ansi_sprintf(line, "--stun-domain %.*s\n", 1620 (int)config->cfg.stun_domain.slen, 1621 config->cfg.stun_domain.ptr); 1622 pj_strcat2(&cfg, line); 1623 } 1624 if (config->cfg.stun_host.slen) { 1619 for (i=0; i<config->cfg.stun_srv_cnt; ++i) { 1625 1620 pj_ansi_sprintf(line, "--stun-srv %.*s\n", 1626 (int)config->cfg.stun_ host.slen,1627 config->cfg.stun_ host.ptr);1621 (int)config->cfg.stun_srv[i].slen, 1622 config->cfg.stun_srv[i].ptr); 1628 1623 pj_strcat2(&cfg, line); 1629 1624 } -
pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
r2859 r2864 892 892 893 893 /** 894 * Warning: deprecated, please use \a stun_srv field instead. To maintain 895 * backward compatibility, if \a stun_srv_cnt is zero then the value of 896 * this field will be copied to \a stun_srv field, if present. 897 * 894 898 * Specify domain name to be resolved with DNS SRV resolution to get the 895 899 * address of the STUN server. Alternatively application may specify … … 902 906 903 907 /** 908 * Warning: deprecated, please use \a stun_srv field instead. To maintain 909 * backward compatibility, if \a stun_srv_cnt is zero then the value of 910 * this field will be copied to \a stun_srv field, if present. 911 * 904 912 * Specify STUN server to be used, in "HOST[:PORT]" format. If port is 905 913 * not specified, default port 3478 will be used. 906 914 */ 907 915 pj_str_t stun_host; 916 917 /** 918 * Number of STUN server entries in \a stun_srv array. 919 */ 920 unsigned stun_srv_cnt; 921 922 /** 923 * Array of STUN servers to try. The library will try to resolve and 924 * contact each of the STUN server entry until it finds one that is 925 * usable. Each entry may be a domain name, host name, IP address, and 926 * it may contain an optional port number. For example: 927 * - "pjsip.org" (domain name) 928 * - "sip.pjsip.org" (host name) 929 * - "pjsip.org:33478" (domain name and a non-standard port number) 930 * - "10.0.0.1:3478" (IP address and port number) 931 * 932 * When nameserver is configured in the \a pjsua_config.nameserver field, 933 * if entry is not an IP address, it will be resolved with DNS SRV 934 * resolution first, and it will fallback to use DNS A resolution if this 935 * fails. Port number may be specified even if the entry is a domain name, 936 * in case the DNS SRV resolution should fallback to a non-standard port. 937 * 938 * When nameserver is not configured, entries will be resolved with 939 * #pj_gethostbyname() if it's not an IP address. Port number may be 940 * specified if the server is not listening in standard STUN port. 941 */ 942 pj_str_t stun_srv[8]; 943 944 /** 945 * This specifies if the library startup should ignore failure with the 946 * STUN servers. If this is set to PJ_FALSE, the library will refuse to 947 * start if it fails to resolve or contact any of the STUN servers. 948 * 949 * Default: PJ_TRUE 950 */ 951 pj_bool_t stun_ignore_failure; 908 952 909 953 /** … … 1214 1258 * 1215 1259 */ 1260 1261 /** 1262 * This structure is used to represent the result of the STUN server 1263 * resolution and testing, the #pjsua_resolve_stun_servers() function. 1264 * This structure will be passed in #pj_stun_resolve_cb callback. 1265 */ 1266 typedef struct pj_stun_resolve_result 1267 { 1268 /** 1269 * Arbitrary data that was passed to #pjsua_resolve_stun_servers() 1270 * function. 1271 */ 1272 void *token; 1273 1274 /** 1275 * This will contain PJ_SUCCESS if at least one usable STUN server 1276 * is found, otherwise it will contain the last error code during 1277 * the operation. 1278 */ 1279 pj_status_t status; 1280 1281 /** 1282 * The server name that yields successful result. This will only 1283 * contain value if status is successful. 1284 */ 1285 pj_str_t name; 1286 1287 /** 1288 * The server IP address. This will only contain value if status 1289 * is successful. 1290 */ 1291 pj_sockaddr addr; 1292 1293 } pj_stun_resolve_result; 1294 1295 1296 /** 1297 * Typedef of callback to be registered to #pjsua_resolve_stun_servers(). 1298 */ 1299 typedef void (*pj_stun_resolve_cb)(const pj_stun_resolve_result *result); 1216 1300 1217 1301 /** … … 1251 1335 */ 1252 1336 PJ_DECL(pj_status_t) pjsua_get_nat_type(pj_stun_nat_type *type); 1337 1338 1339 /** 1340 * Auxiliary function to resolve and contact each of the STUN server 1341 * entries (sequentially) to find which is usable. The #pjsua_init() must 1342 * have been called before calling this function. 1343 * 1344 * @param count Number of STUN server entries to try. 1345 * @param srv Array of STUN server entries to try. Please see 1346 * the \a stun_srv field in the #pjsua_config 1347 * documentation about the format of this entry. 1348 * @param wait Specify non-zero to make the function block until 1349 * it gets the result. In this case, the function 1350 * will block while the resolution is being done, 1351 * and the callback will be called before this function 1352 * returns. 1353 * @param token Arbitrary token to be passed back to application 1354 * in the callback. 1355 * @param cb Callback to be called to notify the result of 1356 * the function. 1357 * 1358 * @return If \a wait parameter is non-zero, this will return 1359 * PJ_SUCCESS if one usable STUN server is found. 1360 * Otherwise it will always return PJ_SUCCESS, and 1361 * application will be notified about the result in 1362 * the callback. 1363 */ 1364 PJ_DECL(pj_status_t) pjsua_resolve_stun_servers(unsigned count, 1365 pj_str_t srv[], 1366 pj_bool_t wait, 1367 void *token, 1368 pj_stun_resolve_cb cb); 1369 1370 /** 1371 * Cancel pending STUN resolution which match the specified token. 1372 * 1373 * @param token The token to match. This token was given to 1374 * #pjsua_resolve_stun_servers() 1375 * @param notify_cb Boolean to control whether the callback should 1376 * be called for cancelled resolutions. When the 1377 * callback is called, the status in the result 1378 * will be set as PJ_ECANCELLED. 1379 * 1380 * @return PJ_SUCCESS if there is at least one pending STUN 1381 * resolution cancelled, or PJ_ENOTFOUND if there is 1382 * no matching one, or other error. 1383 */ 1384 PJ_DECL(pj_status_t) pjsua_cancel_stun_resolution(void *token, 1385 pj_bool_t notify_cb); 1253 1386 1254 1387 -
pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h
r2855 r2864 213 213 } pjsua_conf_setting; 214 214 215 typedef struct pjsua_stun_resolve 216 { 217 PJ_DECL_LIST_MEMBER(struct pjsua_stun_resolve); 218 219 pj_pool_t *pool; /**< Pool */ 220 unsigned count; /**< # of entries */ 221 pj_str_t *srv; /**< Array of entries */ 222 unsigned idx; /**< Current index */ 223 void *token; /**< App token */ 224 pj_stun_resolve_cb cb; /**< App callback */ 225 pj_bool_t blocking; /**< Blocking? */ 226 pj_status_t status; /**< Session status */ 227 pj_sockaddr addr; /**< Result */ 228 pj_stun_sock *stun_sock; /**< Testing STUN sock */ 229 } pjsua_stun_resolve; 230 215 231 216 232 /** … … 242 258 pj_sockaddr stun_srv; /**< Resolved STUN server address */ 243 259 pj_status_t stun_status; /**< STUN server status. */ 260 pjsua_stun_resolve stun_res; /**< List of pending STUN resolution*/ 244 261 pj_dns_resolver *resolver; /**< DNS resolver. */ 245 262 … … 351 368 #endif 352 369 370 /****** 371 * STUN resolution 372 */ 373 /* Resolve the STUN server */ 374 pj_status_t resolve_stun_server(pj_bool_t wait); 375 353 376 /** 354 377 * Normalize route URI (check for ";lr" and append one if it doesn't … … 356 379 */ 357 380 pj_status_t normalize_route_uri(pj_pool_t *pool, pj_str_t *uri); 358 359 /**360 * Resolve STUN server.361 */362 pj_status_t pjsua_resolve_stun_server(pj_bool_t wait);363 381 364 382 /** -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c
r2859 r2864 25 25 26 26 27 /* Internal prototypes */ 28 static void resolve_stun_entry(pjsua_stun_resolve *sess); 29 30 27 31 /* PJSUA application instance. */ 28 32 struct pjsua_data pjsua_var; … … 60 64 pjsua_var.stun_status = PJ_EUNKNOWN; 61 65 pjsua_var.nat_status = PJ_EPENDING; 66 pj_list_init(&pjsua_var.stun_res); 62 67 } 63 68 … … 93 98 cfg->thread_cnt = 1; 94 99 cfg->nat_type_in_sdp = 1; 100 cfg->stun_ignore_failure = PJ_TRUE; 95 101 cfg->force_lr = PJ_TRUE; 96 102 #if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) … … 123 129 pj_strdup_with_null(pool, &dst->stun_domain, &src->stun_domain); 124 130 pj_strdup_with_null(pool, &dst->stun_host, &src->stun_host); 131 132 for (i=0; i<src->stun_srv_cnt; ++i) { 133 pj_strdup_with_null(pool, &dst->stun_srv[i], &src->stun_srv[i]); 134 } 125 135 } 126 136 … … 762 772 goto on_error; 763 773 774 /* Convert deprecated STUN settings */ 775 if (pjsua_var.ua_cfg.stun_srv_cnt==0) { 776 if (pjsua_var.ua_cfg.stun_domain.slen) { 777 pjsua_var.ua_cfg.stun_srv[pjsua_var.ua_cfg.stun_srv_cnt++] = 778 pjsua_var.ua_cfg.stun_domain; 779 } 780 if (pjsua_var.ua_cfg.stun_host.slen) { 781 pjsua_var.ua_cfg.stun_srv[pjsua_var.ua_cfg.stun_srv_cnt++] = 782 pjsua_var.ua_cfg.stun_host; 783 } 784 } 764 785 765 786 /* Start resolving STUN server */ 766 767 status = pjsua_resolve_stun_server(PJ_FALSE); 787 status = resolve_stun_server(PJ_FALSE); 768 788 if (status != PJ_SUCCESS && status != PJ_EPENDING) { 769 789 pjsua_perror(THIS_FILE, "Error resolving STUN server", status); … … 860 880 } 861 881 862 863 /* 864 * Callback function to receive notification from the resolver 865 * when the resolution process completes. 866 */ 867 static void stun_dns_srv_resolver_cb(void *user_data, 868 pj_status_t status, 869 const pj_dns_srv_record *rec) 870 { 882 /* Internal function to destroy STUN resolution session 883 * (pj_stun_resolve). 884 */ 885 static void destroy_stun_resolve(pjsua_stun_resolve *sess) 886 { 887 PJSUA_LOCK(); 888 pj_list_erase(sess); 889 PJSUA_UNLOCK(); 890 891 pj_assert(sess->stun_sock==NULL); 892 pj_pool_release(sess->pool); 893 } 894 895 /* This is the internal function to be called when STUN resolution 896 * session (pj_stun_resolve) has completed. 897 */ 898 static void stun_resolve_complete(pjsua_stun_resolve *sess) 899 { 900 pj_stun_resolve_result result; 901 902 pj_bzero(&result, sizeof(result)); 903 result.token = sess->token; 904 result.status = sess->status; 905 result.name = sess->srv[sess->idx]; 906 pj_memcpy(&result.addr, &sess->addr, sizeof(result.addr)); 907 908 if (result.status == PJ_SUCCESS) { 909 char addr[PJ_INET6_ADDRSTRLEN+10]; 910 pj_sockaddr_print(&result.addr, addr, sizeof(addr), 3); 911 PJ_LOG(4,(THIS_FILE, 912 "STUN resolution success, using %.*s, address is %s", 913 (int)sess->srv[sess->idx].slen, 914 sess->srv[sess->idx].ptr, 915 addr)); 916 } else { 917 char errmsg[PJ_ERR_MSG_SIZE]; 918 pj_strerror(result.status, errmsg, sizeof(errmsg)); 919 PJ_LOG(1,(THIS_FILE, "STUN resolution failed: %s", errmsg)); 920 } 921 922 sess->cb(&result); 923 924 if (!sess->blocking) { 925 destroy_stun_resolve(sess); 926 } 927 } 928 929 /* This is the callback called by the STUN socket (pj_stun_sock) 930 * to report it's state. We use this as part of testing the 931 * STUN server. 932 */ 933 static pj_bool_t test_stun_on_status(pj_stun_sock *stun_sock, 934 pj_stun_sock_op op, 935 pj_status_t status) 936 { 937 pjsua_stun_resolve *sess; 938 939 sess = pj_stun_sock_get_user_data(stun_sock); 940 pj_assert(stun_sock == sess->stun_sock); 941 942 if (status != PJ_SUCCESS) { 943 char errmsg[PJ_ERR_MSG_SIZE]; 944 pj_strerror(status, errmsg, sizeof(errmsg)); 945 946 PJ_LOG(4,(THIS_FILE, "STUN resolution for %.*s failed: %s", 947 (int)sess->srv[sess->idx].slen, 948 sess->srv[sess->idx].ptr, errmsg)); 949 950 sess->status = status; 951 952 pj_stun_sock_destroy(stun_sock); 953 sess->stun_sock = NULL; 954 955 ++sess->idx; 956 resolve_stun_entry(sess); 957 958 return PJ_FALSE; 959 960 } else if (op == PJ_STUN_SOCK_BINDING_OP) { 961 pj_stun_sock_info ssi; 962 963 pj_stun_sock_get_info(stun_sock, &ssi); 964 pj_memcpy(&sess->addr, &ssi.srv_addr, sizeof(sess->addr)); 965 966 sess->status = PJ_SUCCESS; 967 pj_stun_sock_destroy(stun_sock); 968 sess->stun_sock = NULL; 969 970 stun_resolve_complete(sess); 971 972 return PJ_FALSE; 973 974 } else 975 return PJ_TRUE; 976 977 } 978 979 /* This is an internal function to resolve and test current 980 * server entry in pj_stun_resolve session. It is called by 981 * pjsua_resolve_stun_servers() and test_stun_on_status() above 982 */ 983 static void resolve_stun_entry(pjsua_stun_resolve *sess) 984 { 985 /* Loop while we have entry to try */ 986 for (; sess->idx < sess->count; ++sess->idx) { 987 const int af = pj_AF_INET(); 988 pj_str_t hostpart; 989 pj_uint16_t port; 990 pj_stun_sock_cb stun_sock_cb; 991 992 pj_assert(sess->idx < sess->count); 993 994 /* Parse the server entry into host:port */ 995 sess->status = pj_sockaddr_parse2(af, 0, &sess->srv[sess->idx], 996 &hostpart, &port, NULL); 997 if (sess->status != PJ_SUCCESS) { 998 PJ_LOG(2,(THIS_FILE, "Invalid STUN server entry %.*s", 999 (int)sess->srv[sess->idx].slen, 1000 sess->srv[sess->idx].ptr)); 1001 continue; 1002 } 1003 1004 /* Use default port if not specified */ 1005 if (port == 0) 1006 port = PJ_STUN_PORT; 1007 1008 pj_assert(sess->stun_sock == NULL); 1009 1010 PJ_LOG(4,(THIS_FILE, "Trying STUN server %.*s (%d of %d)..", 1011 (int)sess->srv[sess->idx].slen, 1012 sess->srv[sess->idx].ptr, 1013 sess->idx+1, sess->count)); 1014 1015 /* Use STUN_sock to test this entry */ 1016 pj_bzero(&stun_sock_cb, sizeof(stun_sock_cb)); 1017 stun_sock_cb.on_status = &test_stun_on_status; 1018 sess->status = pj_stun_sock_create(&pjsua_var.stun_cfg, "stunresolve", 1019 pj_AF_INET(), &stun_sock_cb, 1020 NULL, sess, &sess->stun_sock); 1021 if (sess->status != PJ_SUCCESS) { 1022 char errmsg[PJ_ERR_MSG_SIZE]; 1023 pj_strerror(sess->status, errmsg, sizeof(errmsg)); 1024 PJ_LOG(4,(THIS_FILE, 1025 "Error creating STUN socket for %.*s: %s", 1026 (int)sess->srv[sess->idx].slen, 1027 sess->srv[sess->idx].ptr, errmsg)); 1028 1029 continue; 1030 } 1031 1032 sess->status = pj_stun_sock_start(sess->stun_sock, &hostpart, 1033 port, pjsua_var.resolver); 1034 if (sess->status != PJ_SUCCESS) { 1035 char errmsg[PJ_ERR_MSG_SIZE]; 1036 pj_strerror(sess->status, errmsg, sizeof(errmsg)); 1037 PJ_LOG(4,(THIS_FILE, 1038 "Error starting STUN socket for %.*s: %s", 1039 (int)sess->srv[sess->idx].slen, 1040 sess->srv[sess->idx].ptr, errmsg)); 1041 1042 pj_stun_sock_destroy(sess->stun_sock); 1043 sess->stun_sock = NULL; 1044 continue; 1045 } 1046 1047 /* Done for now, testing will resume/complete asynchronously in 1048 * stun_sock_cb() 1049 */ 1050 return; 1051 } 1052 1053 if (sess->idx >= sess->count) { 1054 /* No more entries to try */ 1055 PJ_ASSERT_ON_FAIL(sess->status != PJ_SUCCESS, 1056 sess->status = PJ_EUNKNOWN); 1057 stun_resolve_complete(sess); 1058 } 1059 } 1060 1061 1062 /* 1063 * Resolve STUN server. 1064 */ 1065 PJ_DEF(pj_status_t) pjsua_resolve_stun_servers( unsigned count, 1066 pj_str_t srv[], 1067 pj_bool_t wait, 1068 void *token, 1069 pj_stun_resolve_cb cb) 1070 { 1071 pj_pool_t *pool; 1072 pjsua_stun_resolve *sess; 1073 pj_status_t status; 871 1074 unsigned i; 872 1075 873 PJ_UNUSED_ARG(user_data); 874 875 pjsua_var.stun_status = status; 876 877 if (status != PJ_SUCCESS) { 878 /* DNS SRV resolution failed. If stun_host is specified, resolve 879 * it with gethostbyname() 880 */ 881 if (pjsua_var.ua_cfg.stun_host.slen) { 882 pjsua_var.stun_status = 883 pj_sockaddr_parse(pj_AF_INET(), 0, 884 &pjsua_var.ua_cfg.stun_host, 885 &pjsua_var.stun_srv); 886 if (pjsua_var.stun_status != PJ_SUCCESS) { 887 pjsua_perror(THIS_FILE, "Invalid STUN server", 888 pjsua_var.stun_status); 889 } else { 890 if (pj_sockaddr_get_port(&pjsua_var.stun_srv)==0) 891 pj_sockaddr_set_port(&pjsua_var.stun_srv, 3478); 892 893 PJ_LOG(3,(THIS_FILE, 894 "STUN server %.*s resolved, address is %s:%d", 895 (int)pjsua_var.ua_cfg.stun_host.slen, 896 pjsua_var.ua_cfg.stun_host.ptr, 897 pj_inet_ntoa(pjsua_var.stun_srv.ipv4.sin_addr), 898 (int)pj_ntohs(pjsua_var.stun_srv.ipv4.sin_port))); 1076 PJ_ASSERT_RETURN(count && srv && cb, PJ_EINVAL); 1077 1078 pool = pjsua_pool_create("stunres", 256, 256); 1079 if (!pool) 1080 return PJ_ENOMEM; 1081 1082 sess = PJ_POOL_ZALLOC_T(pool, pjsua_stun_resolve); 1083 sess->pool = pool; 1084 sess->token = token; 1085 sess->cb = cb; 1086 sess->count = count; 1087 sess->blocking = wait; 1088 sess->status = PJ_EPENDING; 1089 sess->srv = (pj_str_t*) pj_pool_calloc(pool, count, sizeof(pj_str_t)); 1090 for (i=0; i<count; ++i) { 1091 pj_strdup(pool, &sess->srv[i], &srv[i]); 1092 } 1093 1094 PJSUA_LOCK(); 1095 pj_list_push_back(&pjsua_var.stun_res, sess); 1096 PJSUA_UNLOCK(); 1097 1098 resolve_stun_entry(sess); 1099 1100 if (!wait) 1101 return PJ_SUCCESS; 1102 1103 while (sess->status == PJ_EPENDING) { 1104 pjsua_handle_events(50); 1105 } 1106 1107 status = sess->status; 1108 destroy_stun_resolve(sess); 1109 1110 return status; 1111 } 1112 1113 /* 1114 * Cancel pending STUN resolution. 1115 */ 1116 PJ_DEF(pj_status_t) pjsua_cancel_stun_resolution( void *token, 1117 pj_bool_t notify_cb) 1118 { 1119 pjsua_stun_resolve *sess; 1120 unsigned cancelled_count = 0; 1121 1122 PJSUA_LOCK(); 1123 sess = pjsua_var.stun_res.next; 1124 while (sess != &pjsua_var.stun_res) { 1125 pjsua_stun_resolve *next = sess->next; 1126 1127 if (sess->token == token) { 1128 if (notify_cb) { 1129 pj_stun_resolve_result result; 1130 1131 pj_bzero(&result, sizeof(result)); 1132 result.token = token; 1133 result.status = PJ_ECANCELLED; 1134 1135 sess->cb(&result); 899 1136 } 900 } else { 901 char errmsg[PJ_ERR_MSG_SIZE]; 902 903 pj_strerror(status, errmsg, sizeof(errmsg)); 904 PJ_LOG(1,(THIS_FILE, 905 "DNS SRV resolution failed for STUN server %.*s: %s", 906 (int)pjsua_var.ua_cfg.stun_domain.slen, 907 pjsua_var.ua_cfg.stun_domain.ptr, 908 errmsg)); 909 } 910 return; 911 } 912 913 pj_assert(rec->count != 0 && rec->entry[0].server.addr_count != 0); 914 pj_sockaddr_in_init(&pjsua_var.stun_srv.ipv4, NULL, 915 rec->entry[0].port); 916 pjsua_var.stun_srv.ipv4.sin_addr.s_addr = 917 rec->entry[0].server.addr[0].s_addr; 918 919 PJ_LOG(3,(THIS_FILE, "_stun._udp.%.*s resolved, found %d entry(s):", 920 (int)pjsua_var.ua_cfg.stun_domain.slen, 921 pjsua_var.ua_cfg.stun_domain.ptr, 922 rec->count)); 923 924 for (i=0; i<rec->count; ++i) { 925 PJ_LOG(3,(THIS_FILE, 926 " %d: prio=%d, weight=%d %s:%d", 927 i, rec->entry[i].priority, rec->entry[i].weight, 928 pj_inet_ntoa(rec->entry[i].server.addr[0]), 929 (int)rec->entry[i].port)); 930 } 931 1137 1138 destroy_stun_resolve(sess); 1139 ++cancelled_count; 1140 } 1141 1142 sess = next; 1143 } 1144 PJSUA_UNLOCK(); 1145 1146 return cancelled_count ? PJ_SUCCESS : PJ_ENOTFOUND; 1147 } 1148 1149 static void internal_stun_resolve_cb(const pj_stun_resolve_result *result) 1150 { 1151 pjsua_var.stun_status = result->status; 1152 if (result->status == PJ_SUCCESS) { 1153 pj_memcpy(&pjsua_var.stun_srv, &result->addr, sizeof(result->addr)); 1154 } 932 1155 } 933 1156 … … 935 1158 * Resolve STUN server. 936 1159 */ 937 pj_status_t pjsua_resolve_stun_server(pj_bool_t wait)1160 pj_status_t resolve_stun_server(pj_bool_t wait) 938 1161 { 939 1162 if (pjsua_var.stun_status == PJ_EUNKNOWN) { 1163 pj_status_t status; 1164 940 1165 /* Initialize STUN configuration */ 941 1166 pj_stun_config_init(&pjsua_var.stun_cfg, &pjsua_var.cp.factory, 0, … … 944 1169 945 1170 /* Start STUN server resolution */ 946 947 pjsua_var.stun_status = PJ_EPENDING; 948 949 /* If stun_domain is specified, resolve STUN servers with DNS 950 * SRV resolution. 951 */ 952 if (pjsua_var.ua_cfg.stun_domain.slen) { 953 pj_str_t res_type; 954 pj_status_t status; 955 956 /* Fail if resolver is not configured */ 957 if (pjsua_var.resolver == NULL) { 958 PJ_LOG(1,(THIS_FILE, "Nameserver must be configured when " 959 "stun_domain is specified")); 960 pjsua_var.stun_status = PJLIB_UTIL_EDNSNONS; 961 return PJLIB_UTIL_EDNSNONS; 1171 if (pjsua_var.ua_cfg.stun_srv_cnt) { 1172 pjsua_var.stun_status = PJ_EPENDING; 1173 status = pjsua_resolve_stun_servers(pjsua_var.ua_cfg.stun_srv_cnt, 1174 pjsua_var.ua_cfg.stun_srv, 1175 wait, NULL, 1176 &internal_stun_resolve_cb); 1177 if (wait || status != PJ_SUCCESS) { 1178 pjsua_var.stun_status = status; 962 1179 } 963 res_type = pj_str("_stun._udp"); 964 status = 965 pj_dns_srv_resolve(&pjsua_var.ua_cfg.stun_domain, &res_type, 966 3478, pjsua_var.pool, pjsua_var.resolver, 967 0, NULL, &stun_dns_srv_resolver_cb, NULL); 968 if (status != PJ_SUCCESS) { 969 pjsua_perror(THIS_FILE, "Error starting DNS SRV resolution", 970 pjsua_var.stun_status); 971 pjsua_var.stun_status = status; 972 return pjsua_var.stun_status; 973 } else { 974 pjsua_var.stun_status = PJ_EPENDING; 975 } 976 } 977 /* Otherwise if stun_host is specified, resolve STUN server with 978 * gethostbyname(). 979 */ 980 else if (pjsua_var.ua_cfg.stun_host.slen) { 981 pjsua_var.stun_status = 982 pj_sockaddr_parse(pj_AF_INET(), 0, 983 &pjsua_var.ua_cfg.stun_host, 984 &pjsua_var.stun_srv); 985 if (pjsua_var.stun_status != PJ_SUCCESS) { 986 pjsua_perror(THIS_FILE, "Invalid STUN server", 987 pjsua_var.stun_status); 988 return pjsua_var.stun_status; 989 } 990 991 if (pj_sockaddr_get_port(&pjsua_var.stun_srv)==0) 992 pj_sockaddr_set_port(&pjsua_var.stun_srv, 3478); 993 994 PJ_LOG(3,(THIS_FILE, 995 "STUN server %.*s resolved, address is %s:%d", 996 (int)pjsua_var.ua_cfg.stun_host.slen, 997 pjsua_var.ua_cfg.stun_host.ptr, 998 pj_inet_ntoa(pjsua_var.stun_srv.ipv4.sin_addr), 999 (int)pj_ntohs(pjsua_var.stun_srv.ipv4.sin_port))); 1000 1001 } 1002 /* Otherwise disable STUN. */ 1003 else { 1180 } else { 1004 1181 pjsua_var.stun_status = PJ_SUCCESS; 1005 1182 } 1006 1007 1008 return pjsua_var.stun_status;1009 1183 1010 1184 } else if (pjsua_var.stun_status == PJ_EPENDING) { … … 1016 1190 pjsua_handle_events(10); 1017 1191 } 1018 1019 return pjsua_var.stun_status; 1020 1021 } else { 1022 /* STUN server has been resolved, return the status */ 1023 return pjsua_var.stun_status; 1024 } 1192 } 1193 1194 if (pjsua_var.stun_status != PJ_EPENDING && 1195 pjsua_var.stun_status != PJ_SUCCESS && 1196 pjsua_var.ua_cfg.stun_ignore_failure) 1197 { 1198 PJ_LOG(2,(THIS_FILE, 1199 "Ignoring STUN resolution failure (by setting)")); 1200 pjsua_var.stun_status = PJ_SUCCESS; 1201 } 1202 1203 return pjsua_var.stun_status; 1025 1204 } 1026 1205 … … 1075 1254 /* Destroy endpoint. */ 1076 1255 if (pjsua_var.endpt) { 1256 1257 /* Terminate any pending STUN resolution */ 1258 if (!pj_list_empty(&pjsua_var.stun_res)) { 1259 pjsua_stun_resolve *sess = pjsua_var.stun_res.next; 1260 while (sess != &pjsua_var.stun_res) { 1261 pjsua_stun_resolve *next = sess->next; 1262 destroy_stun_resolve(sess); 1263 sess = next; 1264 } 1265 } 1266 1077 1267 /* Wait for some time to allow unregistration and ICE/TURN 1078 1268 * transports shutdown to complete: … … 1271 1461 1272 1462 /* Make sure STUN server resolution has completed */ 1273 status = pjsua_resolve_stun_server(PJ_TRUE);1463 status = resolve_stun_server(PJ_TRUE); 1274 1464 if (status != PJ_SUCCESS) { 1275 1465 pjsua_perror(THIS_FILE, "Error resolving STUN server", status); … … 1983 2173 1984 2174 /* Make sure STUN server resolution has completed */ 1985 status = pjsua_resolve_stun_server(PJ_TRUE);2175 status = resolve_stun_server(PJ_TRUE); 1986 2176 if (status != PJ_SUCCESS) { 1987 2177 pjsua_var.nat_status = status; -
pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c
r2837 r2864 360 360 361 361 /* Make sure STUN server resolution has completed */ 362 status = pjsua_resolve_stun_server(PJ_TRUE);362 status = resolve_stun_server(PJ_TRUE); 363 363 if (status != PJ_SUCCESS) { 364 364 pjsua_perror(THIS_FILE, "Error resolving STUN server", status); … … 861 861 862 862 /* Make sure STUN server resolution has completed */ 863 status = pjsua_resolve_stun_server(PJ_TRUE);863 status = resolve_stun_server(PJ_TRUE); 864 864 if (status != PJ_SUCCESS) { 865 865 pjsua_perror(THIS_FILE, "Error resolving STUN server", status);
Note: See TracChangeset
for help on using the changeset viewer.