- Timestamp:
- Mar 2, 2007 7:06:05 PM (18 years ago)
- Location:
- pjproject/trunk/pjlib-util
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib-util/include/pjlib-util/stun_endpoint.h
r996 r1034 46 46 typedef struct pj_stun_endpoint 47 47 { 48 /** 49 * Pool factory to be used by the STUN endpoint and all objects created 50 * that use this STUN endpoint. 51 */ 48 52 pj_pool_factory *pf; 53 54 /** 55 * Ioqueue used by this endpoint. 56 */ 49 57 pj_ioqueue_t *ioqueue; 58 59 /** 60 * Timer heap instance used by this endpoint. 61 */ 50 62 pj_timer_heap_t *timer_heap; 63 64 /** 65 * Internal pool used by this endpoint. This shouldn't be used by 66 * application. 67 */ 68 pj_pool_t *pool; 69 70 /** 71 * Options. 72 */ 51 73 unsigned options; 52 74 75 /** 76 * The default initial STUN round-trip time estimation in msecs. 77 * The value normally is PJ_STUN_RTO_VALUE. 78 */ 53 79 unsigned rto_msec; 54 80 55 pj_pool_t *pool; 81 /** 82 * The interval to cache outgoing STUN response in the STUN session, 83 * in miliseconds. 84 * 85 * Default 10000 (10 seconds). 86 */ 87 unsigned res_cache_msec; 56 88 57 89 } pj_stun_endpoint; -
pjproject/trunk/pjlib-util/include/pjlib-util/stun_session.h
r1021 r1034 24 24 #include <pjlib-util/stun_transaction.h> 25 25 #include <pj/list.h> 26 #include <pj/timer.h> 26 27 27 28 PJ_BEGIN_DECL … … 140 141 141 142 pj_stun_client_tsx *client_tsx; /**< Client STUN transaction. */ 142 pj_uint8_t client_key[12];/**< Client transaction key. */ 143 pj_uint32_t msg_magic; /**< Message magic. */ 144 pj_uint8_t msg_key[12]; /**< Message/transaction key. */ 143 145 144 146 void *pkt; /**< The STUN packet. */ … … 146 148 unsigned pkt_size; /**< The actual length of STUN pkt. */ 147 149 150 unsigned options; /**< Options specified when sending */ 148 151 unsigned addr_len; /**< Length of destination address. */ 149 152 const pj_sockaddr_t *dst_addr; /**< Destination address. */ 153 154 pj_timer_entry res_timer; /**< Response cache timer. */ 150 155 }; 151 156 … … 155 160 * messages. These options may be specified as bitmask. 156 161 */ 157 enum pj_stun_session_ option162 enum pj_stun_session_send_option 158 163 { 159 164 /** … … 172 177 * Add STUN fingerprint to the message. 173 178 */ 174 PJ_STUN_USE_FINGERPRINT = 4 179 PJ_STUN_USE_FINGERPRINT = 4, 180 181 /** 182 * Instruct the session to cache outgoing response. This can only be 183 * used when sending outgoing response message, and when it's specified, 184 * the session will use \a res_cache_msec settings in pj_stun_endpoint 185 * as the duration of the cache. 186 */ 187 PJ_STUN_CACHE_RESPONSE = 8 175 188 }; 176 189 … … 258 271 const pj_str_t *user, 259 272 const pj_str_t *passwd); 273 260 274 261 275 /** … … 396 410 * 397 411 * @param sess The STUN session instance. 398 * @param options Optional flags, from pj_stun_session_ option.412 * @param options Optional flags, from pj_stun_session_send_option. 399 413 * @param dst_addr The destination socket address. 400 414 * @param addr_len Length of destination address. -
pjproject/trunk/pjlib-util/src/pjlib-util/stun_endpoint.c
r996 r1034 48 48 endpt->timer_heap = timer_heap; 49 49 endpt->rto_msec = PJ_STUN_RTO_VALUE; 50 endpt->res_cache_msec = 10000; 50 51 51 52 *p_endpt = endpt; -
pjproject/trunk/pjlib-util/src/pjlib-util/stun_session.c
r1030 r1034 38 38 39 39 pj_stun_tx_data pending_request_list; 40 pj_stun_tx_data cached_response_list; 40 41 }; 41 42 … … 104 105 tdata = sess->pending_request_list.next; 105 106 while (tdata != &sess->pending_request_list) { 106 pj_assert(sizeof(tdata->client_key)==sizeof(msg->hdr.tsx_id)); 107 if (pj_memcmp(tdata->client_key, msg->hdr.tsx_id, 107 pj_assert(sizeof(tdata->msg_key)==sizeof(msg->hdr.tsx_id)); 108 if (tdata->msg_magic == msg->hdr.magic && 109 pj_memcmp(tdata->msg_key, msg->hdr.tsx_id, 108 110 sizeof(msg->hdr.tsx_id))==0) 109 111 { … … 159 161 160 162 /* copy the request's transaction ID as the transaction key. */ 161 pj_assert(sizeof(tdata->client_key)==sizeof(tdata->msg->hdr.tsx_id)); 162 pj_memcpy(tdata->client_key, tdata->msg->hdr.tsx_id, 163 pj_assert(sizeof(tdata->msg_key)==sizeof(tdata->msg->hdr.tsx_id)); 164 tdata->msg_magic = tdata->msg->hdr.magic; 165 pj_memcpy(tdata->msg_key, tdata->msg->hdr.tsx_id, 163 166 sizeof(tdata->msg->hdr.tsx_id)); 164 167 … … 175 178 tdata->client_tsx = NULL; 176 179 } 177 180 if (tdata->res_timer.id != PJ_FALSE) { 181 pj_timer_heap_cancel(tdata->sess->endpt->timer_heap, 182 &tdata->res_timer); 183 tdata->res_timer.id = PJ_FALSE; 184 } 178 185 pj_pool_release(tdata->pool); 179 186 } … … 187 194 PJ_UNUSED_ARG(sess); 188 195 destroy_tdata(tdata); 196 } 197 198 199 /* Timer callback to be called when it's time to destroy response cache */ 200 static void on_cache_timeout(pj_timer_heap_t *timer_heap, 201 struct pj_timer_entry *entry) 202 { 203 pj_stun_tx_data *tdata; 204 205 PJ_UNUSED_ARG(timer_heap); 206 207 entry->id = PJ_FALSE; 208 tdata = (pj_stun_tx_data*) entry->user_data; 209 210 PJ_LOG(5,(SNAME(tdata->sess), "Response cache deleted")); 211 212 pj_list_erase(tdata); 213 pj_stun_msg_destroy_tdata(tdata->sess, tdata); 189 214 } 190 215 … … 329 354 330 355 pj_list_init(&sess->pending_request_list); 356 pj_list_init(&sess->cached_response_list); 331 357 332 358 status = pj_mutex_create_recursive(pool, name, &sess->mutex); … … 500 526 501 527 /* copy the request's transaction ID as the transaction key. */ 502 pj_assert(sizeof(tdata->client_key)==sizeof(req->hdr.tsx_id)); 503 pj_memcpy(tdata->client_key, req->hdr.tsx_id, sizeof(req->hdr.tsx_id)); 528 pj_assert(sizeof(tdata->msg_key)==sizeof(req->hdr.tsx_id)); 529 tdata->msg_magic = req->hdr.magic; 530 pj_memcpy(tdata->msg_key, req->hdr.tsx_id, sizeof(req->hdr.tsx_id)); 504 531 505 532 *p_tdata = tdata; … … 553 580 PJ_ASSERT_RETURN(sess && addr_len && server && tdata, PJ_EINVAL); 554 581 582 tdata->options = options; 583 555 584 /* Allocate packet */ 556 585 tdata->max_len = PJ_STUN_MAX_PKT_LEN; … … 612 641 613 642 } else { 643 if ((options & PJ_STUN_CACHE_RESPONSE) && 644 (PJ_STUN_IS_RESPONSE(tdata->msg->hdr.type) || 645 PJ_STUN_IS_ERROR_RESPONSE(tdata->msg->hdr.type))) 646 { 647 /* Requested to keep the response in the cache */ 648 pj_time_val timeout; 649 650 pj_memset(&tdata->res_timer, 0, sizeof(tdata->res_timer)); 651 pj_timer_entry_init(&tdata->res_timer, PJ_TRUE, tdata, 652 &on_cache_timeout); 653 654 timeout.sec = sess->endpt->res_cache_msec / 1000; 655 timeout.msec = sess->endpt->res_cache_msec % 1000; 656 657 status = pj_timer_heap_schedule(sess->endpt->timer_heap, 658 &tdata->res_timer, 659 &timeout); 660 if (status != PJ_SUCCESS) { 661 pj_stun_msg_destroy_tdata(sess, tdata); 662 pj_mutex_unlock(sess->mutex); 663 LOG_ERR_(sess, "Error scheduling response timer", status); 664 return status; 665 } 666 667 pj_list_push_back(&sess->cached_response_list, tdata); 668 } 669 614 670 /* Otherwise for non-request message, send directly to transport. */ 615 671 status = sess->cb.on_send_msg(sess, tdata->pkt, tdata->pkt_size, … … 620 676 } 621 677 622 /* Destroy */ 623 pj_stun_msg_destroy_tdata(sess, tdata); 678 /* Destroy only when response is not cached*/ 679 if (tdata->res_timer.id == 0) { 680 pj_stun_msg_destroy_tdata(sess, tdata); 681 } 624 682 } 625 683 … … 640 698 tdata = tsx_lookup(sess, msg); 641 699 if (tdata == NULL) { 642 LOG_ERR_(sess, "STUN error finding transaction", PJ_ENOTFOUND); 643 return PJ_ENOTFOUND; 700 PJ_LOG(4,(SNAME(sess), 701 "Transaction not found, response silently discarded")); 702 return PJ_SUCCESS; 644 703 } 645 704 … … 708 767 unsigned src_addr_len) 709 768 { 769 pj_stun_tx_data *t; 710 770 pj_status_t status; 771 772 /* First lookup response in response cache */ 773 t = sess->cached_response_list.next; 774 while (t != &sess->cached_response_list) { 775 if (t->msg_magic == msg->hdr.magic && 776 pj_memcmp(t->msg_key, msg->hdr.tsx_id, 777 sizeof(msg->hdr.tsx_id))==0) 778 { 779 break; 780 } 781 t = t->next; 782 } 783 784 if (t != &sess->cached_response_list) { 785 /* Found response in the cache */ 786 unsigned options; 787 788 PJ_LOG(5,(SNAME(sess), 789 "Request retransmission, sending cached response")); 790 791 options = t->options; 792 options &= ~PJ_STUN_CACHE_RESPONSE; 793 pj_stun_session_send_msg(sess, options, src_addr, src_addr_len, t); 794 return PJ_SUCCESS; 795 } 711 796 712 797 /* Distribute to handler, or respond with Bad Request */ … … 726 811 } 727 812 728 return status; 813 return status; 729 814 } 730 815 -
pjproject/trunk/pjlib-util/src/pjstun-srv-test/server_main.c
r1030 r1034 157 157 158 158 /* Send */ 159 status = pj_stun_session_send_msg(sess, 0, src_addr, src_addr_len, tdata); 159 status = pj_stun_session_send_msg(sess, PJ_STUN_CACHE_RESPONSE, 160 src_addr, src_addr_len, tdata); 160 161 return status; 161 162 }
Note: See TracChangeset
for help on using the changeset viewer.