- Timestamp:
- Sep 12, 2019 8:46:05 AM (5 years ago)
- Location:
- pjproject/trunk/pjnath
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjnath/include/pjnath/stun_session.h
r4606 r6069 349 349 pj_uint32_t msg_magic; /**< Message magic. */ 350 350 pj_uint8_t msg_key[12]; /**< Message/transaction key. */ 351 352 pj_grp_lock_t *grp_lock; /**< Group lock (for resp cache). */ 351 353 352 354 pj_stun_req_cred_info auth_info; /**< Credential info */ -
pjproject/trunk/pjnath/src/pjnath/stun_session.c
r5983 r6069 77 77 static void stun_tsx_on_destroy(pj_stun_client_tsx *tsx); 78 78 static void stun_sess_on_destroy(void *comp); 79 static void destroy_tdata(pj_stun_tx_data *tdata, pj_bool_t force); 79 80 80 81 static pj_stun_tsx_cb tsx_cb = … … 154 155 pj_grp_lock_acquire(sess->grp_lock); 155 156 tsx_erase(sess, tdata); 156 pj_pool_release(tdata->pool);157 destroy_tdata(tdata, PJ_TRUE); 157 158 pj_grp_lock_release(sess->grp_lock); 158 159 } … … 161 162 162 163 TRACE_((THIS_FILE, "STUN transaction %p destroyed", tsx)); 164 } 165 166 static void tdata_on_destroy(void *arg) 167 { 168 pj_stun_tx_data *tdata = (pj_stun_tx_data*)arg; 169 170 pj_pool_safe_release(&tdata->pool); 163 171 } 164 172 … … 168 176 force, tdata->client_tsx)); 169 177 178 /* STUN session may have been destroyed, except when tdata is cached. */ 179 170 180 if (tdata->res_timer.id != PJ_FALSE) { 171 181 pj_timer_heap_cancel_if_active(tdata->sess->cfg->timer_heap, 172 &tdata->res_timer, PJ_FALSE); 173 pj_list_erase(tdata); 182 &tdata->res_timer, PJ_FALSE); 174 183 } 175 184 … … 180 189 pj_stun_client_tsx_set_data(tdata->client_tsx, NULL); 181 190 } 182 pj_pool_release(tdata->pool); 191 if (tdata->grp_lock) { 192 pj_grp_lock_dec_ref(tdata->sess->grp_lock); 193 pj_grp_lock_dec_ref(tdata->grp_lock); 194 } else { 195 tdata_on_destroy(tdata); 196 } 183 197 184 198 } else { … … 189 203 190 204 } else { 191 pj_pool_release(tdata->pool); 205 pj_list_erase(tdata); 206 if (tdata->grp_lock) { 207 pj_grp_lock_dec_ref(tdata->sess->grp_lock); 208 pj_grp_lock_dec_ref(tdata->grp_lock); 209 } else { 210 tdata_on_destroy(tdata); 211 } 192 212 } 193 213 } … … 226 246 PJ_LOG(5,(SNAME(tdata->sess), "Response cache deleted")); 227 247 228 pj_list_erase(tdata);248 destroy_tdata(tdata, PJ_FALSE); 229 249 pj_grp_lock_release(sess->grp_lock); 230 250 231 destroy_tdata(tdata, PJ_FALSE);232 251 } 233 252 … … 565 584 } 566 585 567 while (!pj_list_empty(&sess->cached_response_list)) { 568 pj_stun_tx_data *tdata = sess->cached_response_list.next; 569 destroy_tdata(tdata, PJ_TRUE); 570 } 571 572 if (sess->rx_pool) { 573 pj_pool_release(sess->rx_pool); 574 sess->rx_pool = NULL; 575 } 576 577 pj_pool_release(sess->pool); 586 pj_pool_safe_release(&sess->rx_pool); 587 pj_pool_safe_release(&sess->pool); 578 588 579 589 TRACE_((THIS_FILE, "STUN session %p destroyed", sess)); … … 599 609 sess->is_destroying = PJ_TRUE; 600 610 601 /* We need to stop transactions and cached responsebecause they are611 /* We need to stop transactions because they are 602 612 * holding the group lock's reference counter while retransmitting. 603 613 */ … … 609 619 } 610 620 611 tdata = sess->cached_response_list.next; 612 while (tdata != &sess->cached_response_list) { 613 pj_timer_heap_cancel_if_active(tdata->sess->cfg->timer_heap, 614 &tdata->res_timer, PJ_FALSE); 615 tdata = tdata->next; 621 /* Destroy cached response within session lock protection to avoid 622 * race scenario with on_cache_timeout(). 623 */ 624 while (!pj_list_empty(&sess->cached_response_list)) { 625 pj_stun_tx_data *tdata = sess->cached_response_list.next; 626 destroy_tdata(tdata, PJ_TRUE); 616 627 } 617 628 … … 805 816 on_error: 806 817 if (tdata) 807 pj_pool_ release(tdata->pool);818 pj_pool_safe_release(&tdata->pool); 808 819 pj_grp_lock_release(sess->grp_lock); 809 820 return status; … … 836 847 NULL, &tdata->msg); 837 848 if (status != PJ_SUCCESS) { 838 pj_pool_ release(tdata->pool);849 pj_pool_safe_release(&tdata->pool); 839 850 pj_grp_lock_release(sess->grp_lock); 840 851 return status; … … 875 886 err_code, err_msg, &tdata->msg); 876 887 if (status != PJ_SUCCESS) { 877 pj_pool_ release(tdata->pool);888 pj_pool_safe_release(&tdata->pool); 878 889 pj_grp_lock_release(sess->grp_lock); 879 890 return status; … … 1008 1019 1009 1020 } else { 1021 /* Otherwise for non-request message, send directly to transport. */ 1010 1022 if (cache_res && 1011 1023 (PJ_STUN_IS_SUCCESS_RESPONSE(tdata->msg->hdr.type) || … … 1014 1026 /* Requested to keep the response in the cache */ 1015 1027 pj_time_val timeout; 1028 1029 status = pj_grp_lock_create(tdata->pool, NULL, &tdata->grp_lock); 1030 if (status != PJ_SUCCESS) { 1031 pj_stun_msg_destroy_tdata(sess, tdata); 1032 LOG_ERR_(sess, "Error creating group lock", status); 1033 goto on_return; 1034 } 1035 pj_grp_lock_add_ref(tdata->grp_lock); 1036 pj_grp_lock_add_handler(tdata->grp_lock, tdata->pool, tdata, 1037 &tdata_on_destroy); 1038 1039 /* Also add ref session group lock to make sure that the session 1040 * is still valid when cache timeout callback is called. 1041 */ 1042 pj_grp_lock_add_ref(sess->grp_lock); 1016 1043 1017 1044 pj_memset(&tdata->res_timer, 0, sizeof(tdata->res_timer)); … … 1025 1052 &tdata->res_timer, 1026 1053 &timeout, PJ_TRUE, 1027 sess->grp_lock);1054 tdata->grp_lock); 1028 1055 if (status != PJ_SUCCESS) { 1029 1056 pj_stun_msg_destroy_tdata(sess, tdata); … … 1034 1061 pj_list_push_back(&sess->cached_response_list, tdata); 1035 1062 } 1036 1037 /* Otherwise for non-request message, send directly to transport. */1063 1064 /* Send to transport directly. */ 1038 1065 status = sess->cb.on_send_msg(sess, token, tdata->pkt, 1039 1066 tdata->pkt_size, server, addr_len);
Note: See TracChangeset
for help on using the changeset viewer.