Ticket #1563: ticket_1563.patch
File ticket_1563.patch, 4.8 KB (added by bennylp, 12 years ago) |
---|
-
pjsip/include/pjsua-lib/pjsua_internal.h
249 249 PJ_DECL_LIST_MEMBER(struct pjsua_stun_resolve); 250 250 251 251 pj_pool_t *pool; /**< Pool */ 252 int ref_cnt; /**< Reference count */ 253 pj_bool_t destroy_flag; /**< To be destroyed */ 254 pj_bool_t has_result; 252 255 unsigned count; /**< # of entries */ 253 256 pj_str_t *srv; /**< Array of entries */ 254 257 unsigned idx; /**< Current index */ -
pjsip/src/pjsua-lib/pjsua_core.c
956 956 } while (PJ_TIME_VAL_LT(now, timeout)); 957 957 } 958 958 959 /* Internal function to destroy STUN resolution session 960 * (pj_stun_resolve). 961 */ 959 static void stun_resolve_add_ref(pjsua_stun_resolve *sess) 960 { 961 ++sess->ref_cnt; 962 } 963 962 964 static void destroy_stun_resolve(pjsua_stun_resolve *sess) 963 965 { 966 sess->destroy_flag = PJ_TRUE; 967 if (sess->ref_cnt > 0) 968 return; 969 964 970 PJSUA_LOCK(); 965 971 pj_list_erase(sess); 966 972 PJSUA_UNLOCK(); … … 969 975 pj_pool_release(sess->pool); 970 976 } 971 977 978 static void stun_resolve_dec_ref(pjsua_stun_resolve *sess) 979 { 980 --sess->ref_cnt; 981 if (sess->ref_cnt <= 0 && sess->destroy_flag) 982 destroy_stun_resolve(sess); 983 } 984 985 972 986 /* This is the internal function to be called when STUN resolution 973 987 * session (pj_stun_resolve) has completed. 974 988 */ … … 976 990 { 977 991 pj_stun_resolve_result result; 978 992 993 if (sess->has_result) 994 goto on_return; 995 979 996 pj_bzero(&result, sizeof(result)); 980 997 result.token = sess->token; 981 998 result.status = sess->status; 982 999 result.name = sess->srv[sess->idx]; 983 1000 pj_memcpy(&result.addr, &sess->addr, sizeof(result.addr)); 1001 sess->has_result = PJ_TRUE; 984 1002 985 1003 if (result.status == PJ_SUCCESS) { 986 1004 char addr[PJ_INET6_ADDRSTRLEN+10]; … … 996 1014 PJ_LOG(1,(THIS_FILE, "STUN resolution failed: %s", errmsg)); 997 1015 } 998 1016 1017 stun_resolve_add_ref(sess); 999 1018 sess->cb(&result); 1019 stun_resolve_dec_ref(sess); 1000 1020 1021 on_return: 1001 1022 if (!sess->blocking) { 1002 1023 destroy_stun_resolve(sess); 1003 1024 } … … 1059 1080 */ 1060 1081 static void resolve_stun_entry(pjsua_stun_resolve *sess) 1061 1082 { 1083 stun_resolve_add_ref(sess); 1084 1062 1085 /* Loop while we have entry to try */ 1063 1086 for (; sess->idx < sess->count; ++sess->idx) { 1064 1087 const int af = pj_AF_INET(); 1088 char target[64]; 1065 1089 pj_str_t hostpart; 1066 1090 pj_uint16_t port; 1067 1091 pj_stun_sock_cb stun_sock_cb; 1068 1092 1069 1093 pj_assert(sess->idx < sess->count); 1070 1094 1095 pj_ansi_snprintf(target, sizeof(target), "%.*s", 1096 (int)sess->srv[sess->idx].slen, 1097 sess->srv[sess->idx].ptr); 1098 1071 1099 /* Parse the server entry into host:port */ 1072 1100 sess->status = pj_sockaddr_parse2(af, 0, &sess->srv[sess->idx], 1073 1101 &hostpart, &port, NULL); 1074 1102 if (sess->status != PJ_SUCCESS) { 1075 PJ_LOG(2,(THIS_FILE, "Invalid STUN server entry %.*s", 1076 (int)sess->srv[sess->idx].slen, 1077 sess->srv[sess->idx].ptr)); 1103 PJ_LOG(2,(THIS_FILE, "Invalid STUN server entry %s", target)); 1078 1104 continue; 1079 1105 } 1080 1106 … … 1084 1110 1085 1111 pj_assert(sess->stun_sock == NULL); 1086 1112 1087 PJ_LOG(4,(THIS_FILE, "Trying STUN server %.*s (%d of %d)..", 1088 (int)sess->srv[sess->idx].slen, 1089 sess->srv[sess->idx].ptr, 1090 sess->idx+1, sess->count)); 1113 PJ_LOG(4,(THIS_FILE, "Trying STUN server %s (%d of %d)..", 1114 target, sess->idx+1, sess->count)); 1091 1115 1092 1116 /* Use STUN_sock to test this entry */ 1093 1117 pj_bzero(&stun_sock_cb, sizeof(stun_sock_cb)); … … 1099 1123 char errmsg[PJ_ERR_MSG_SIZE]; 1100 1124 pj_strerror(sess->status, errmsg, sizeof(errmsg)); 1101 1125 PJ_LOG(4,(THIS_FILE, 1102 "Error creating STUN socket for %.*s: %s", 1103 (int)sess->srv[sess->idx].slen, 1104 sess->srv[sess->idx].ptr, errmsg)); 1126 "Error creating STUN socket for %s: %s", 1127 target, errmsg)); 1105 1128 1106 1129 continue; 1107 1130 } … … 1112 1135 char errmsg[PJ_ERR_MSG_SIZE]; 1113 1136 pj_strerror(sess->status, errmsg, sizeof(errmsg)); 1114 1137 PJ_LOG(4,(THIS_FILE, 1115 "Error starting STUN socket for %.*s: %s", 1116 (int)sess->srv[sess->idx].slen, 1117 sess->srv[sess->idx].ptr, errmsg)); 1138 "Error starting STUN socket for %s: %s", 1139 target, errmsg)); 1118 1140 1119 pj_stun_sock_destroy(sess->stun_sock); 1120 sess->stun_sock = NULL; 1141 if (sess->stun_sock) { 1142 pj_stun_sock_destroy(sess->stun_sock); 1143 sess->stun_sock = NULL; 1144 } 1121 1145 continue; 1122 1146 } 1123 1147 1124 1148 /* Done for now, testing will resume/complete asynchronously in 1125 1149 * stun_sock_cb() 1126 1150 */ 1127 return;1151 goto on_return; 1128 1152 } 1129 1153 1130 1154 if (sess->idx >= sess->count) { … … 1133 1157 sess->status = PJ_EUNKNOWN); 1134 1158 stun_resolve_complete(sess); 1135 1159 } 1160 1161 on_return: 1162 stun_resolve_dec_ref(sess); 1136 1163 } 1137 1164 1138 1165