Changeset 1988 for pjproject/trunk/pjnath/src/pjnath/turn_session.c
- Timestamp:
- Jun 6, 2008 2:47:10 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjnath/src/pjnath/turn_session.c
r1929 r1988 30 30 #include <pj/sock.h> 31 31 32 #define MAX_SRV_CNT 4 33 #define REFRESH_SEC_BEFORE 60 32 #define PJ_TURN_CHANNEL_MIN 0x4000 33 #define PJ_TURN_CHANNEL_MAX 0xFFFE /* inclusive */ 34 #define PJ_TURN_PEER_HTABLE_SIZE 8 34 35 35 36 static const char *state_names[] = … … 67 68 pj_turn_session_cb cb; 68 69 void *user_data; 70 pj_stun_config stun_cfg; 69 71 70 72 pj_lock_t *lock; … … 72 74 73 75 pj_turn_state_t state; 76 pj_status_t last_status; 74 77 pj_bool_t pending_destroy; 75 78 pj_bool_t destroy_notified; … … 88 91 89 92 pj_uint16_t af; 90 pj_turn_tp_type tp_type;93 pj_turn_tp_type conn_type; 91 94 pj_uint16_t srv_addr_cnt; 92 95 pj_sockaddr *srv_addr_list; … … 96 99 pj_turn_alloc_param alloc_param; 97 100 101 pj_sockaddr mapped_addr; 98 102 pj_sockaddr relay_addr; 99 103 … … 177 181 * Create TURN client session. 178 182 */ 179 PJ_DEF(pj_status_t) pj_turn_session_create( pj_stun_config *cfg,183 PJ_DEF(pj_status_t) pj_turn_session_create( const pj_stun_config *cfg, 180 184 const char *name, 181 185 int af, 182 pj_turn_tp_type tp_type,186 pj_turn_tp_type conn_type, 183 187 const pj_turn_session_cb *cb, 188 unsigned options, 184 189 void *user_data, 185 unsigned options,186 190 pj_turn_session **p_sess) 187 191 { … … 207 211 sess->timer_heap = cfg->timer_heap; 208 212 sess->af = (pj_uint16_t)af; 209 sess-> tp_type = tp_type;213 sess->conn_type = conn_type; 210 214 sess->ka_interval = PJ_TURN_KEEP_ALIVE_SEC; 211 215 sess->user_data = user_data; 212 216 sess->next_ch = PJ_TURN_CHANNEL_MIN; 217 218 /* Copy STUN session */ 219 pj_memcpy(&sess->stun_cfg, cfg, sizeof(pj_stun_config)); 213 220 214 221 /* Copy callback */ … … 234 241 stun_cb.on_request_complete = &stun_on_request_complete; 235 242 stun_cb.on_rx_indication = &stun_on_rx_indication; 236 status = pj_stun_session_create( cfg, sess->obj_name, &stun_cb, PJ_FALSE,237 &sess->stun);243 status = pj_stun_session_create(&sess->stun_cfg, sess->obj_name, &stun_cb, 244 PJ_FALSE, &sess->stun); 238 245 if (status != PJ_SUCCESS) { 239 246 do_destroy(sess); … … 334 341 break; 335 342 case PJ_TURN_STATE_RESOLVING: 336 pj_assert(sess->dns_async != NULL); 337 pj_dns_resolver_cancel_query(sess->dns_async, PJ_FALSE); 338 sess->dns_async = NULL; 343 if (sess->dns_async != NULL) { 344 pj_dns_resolver_cancel_query(sess->dns_async, PJ_FALSE); 345 sess->dns_async = NULL; 346 } 339 347 break; 340 348 case PJ_TURN_STATE_RESOLVED: … … 366 374 pj_time_val delay = {0, 0}; 367 375 376 set_state(sess, PJ_TURN_STATE_DESTROYING); 377 368 378 if (sess->timer.id != TIMER_NONE) { 369 379 pj_timer_heap_cancel(sess->timer_heap, &sess->timer); … … 371 381 } 372 382 373 set_state(sess, PJ_TURN_STATE_DESTROYING);374 375 383 sess->timer.id = TIMER_DESTROY; 376 384 pj_timer_heap_schedule(sess->timer_heap, &sess->timer, &delay); … … 401 409 PJ_DEF(pj_status_t) pj_turn_session_destroy( pj_turn_session *sess) 402 410 { 411 PJ_ASSERT_RETURN(sess, PJ_EINVAL); 412 403 413 set_state(sess, PJ_TURN_STATE_DEALLOCATED); 404 414 sess_shutdown(sess, PJ_SUCCESS); … … 420 430 421 431 info->state = sess->state; 422 info-> tp_type = sess->tp_type;432 info->conn_type = sess->conn_type; 423 433 info->lifetime = sess->expiry.sec - now.sec; 434 info->last_status = sess->last_status; 424 435 425 436 if (sess->srv_addr) … … 428 439 pj_bzero(&info->server, sizeof(info->server)); 429 440 430 pj_memcpy(&info->relay_addr, &sess->relay_addr, sizeof(sess->relay_addr)); 441 pj_memcpy(&info->mapped_addr, &sess->mapped_addr, 442 sizeof(sess->mapped_addr)); 443 pj_memcpy(&info->relay_addr, &sess->relay_addr, 444 sizeof(sess->relay_addr)); 431 445 432 446 return PJ_SUCCESS; … … 451 465 { 452 466 return sess->user_data; 467 } 468 469 470 /* 471 * Configure message logging. By default all flags are enabled. 472 * 473 * @param sess The TURN client session. 474 * @param flags Bitmask combination of #pj_stun_sess_msg_log_flag 475 */ 476 PJ_DEF(void) pj_turn_session_set_log( pj_turn_session *sess, 477 unsigned flags) 478 { 479 pj_stun_session_set_log(sess->stun, flags); 453 480 } 454 481 … … 462 489 pj_dns_resolver *resolver) 463 490 { 491 pj_sockaddr tmp_addr; 492 pj_bool_t is_ip_addr; 464 493 pj_status_t status; 465 494 … … 469 498 pj_lock_acquire(sess->lock); 470 499 471 if (resolver) { 500 /* See if "domain" contains just IP address */ 501 tmp_addr.addr.sa_family = sess->af; 502 status = pj_inet_pton(sess->af, domain, 503 pj_sockaddr_get_addr(&tmp_addr)); 504 is_ip_addr = (status == PJ_SUCCESS); 505 506 if (!is_ip_addr && resolver) { 472 507 /* Resolve with DNS SRV resolution, and fallback to DNS A resolution 473 508 * if default_port is specified. … … 476 511 pj_str_t res_name; 477 512 478 switch (sess-> tp_type) {513 switch (sess->conn_type) { 479 514 case PJ_TURN_TP_UDP: 480 515 res_name = pj_str("_turn._udp."); … … 502 537 set_state(sess, PJ_TURN_STATE_RESOLVING); 503 538 539 /* User may have destroyed us in the callback */ 540 if (sess->state != PJ_TURN_STATE_RESOLVING) { 541 status = PJ_ECANCELLED; 542 goto on_return; 543 } 544 504 545 status = pj_dns_srv_resolve(domain, &res_name, default_port, 505 546 sess->pool, resolver, opt, sess, … … 521 562 sess->default_port = (pj_uint16_t)default_port; 522 563 523 cnt = MAX_SRV_CNT;564 cnt = PJ_TURN_MAX_DNS_SRV_CNT; 524 565 ai = (pj_addrinfo*) 525 566 pj_pool_calloc(sess->pool, cnt, sizeof(pj_addrinfo)); … … 527 568 PJ_LOG(5,(sess->obj_name, "Resolving %.*s with DNS A", 528 569 (int)domain->slen, domain->ptr)); 570 set_state(sess, PJ_TURN_STATE_RESOLVING); 571 572 /* User may have destroyed us in the callback */ 573 if (sess->state != PJ_TURN_STATE_RESOLVING) { 574 status = PJ_ECANCELLED; 575 goto on_return; 576 } 529 577 530 578 status = pj_getaddrinfo(sess->af, domain, &cnt, ai); … … 637 685 /* Send request */ 638 686 set_state(sess, PJ_TURN_STATE_ALLOCATING); 639 retransmit = (sess-> tp_type == PJ_TURN_TP_UDP);687 retransmit = (sess->conn_type == PJ_TURN_TP_UDP); 640 688 status = pj_stun_session_send_msg(sess->stun, NULL, PJ_FALSE, 641 689 retransmit, sess->srv_addr, … … 682 730 683 731 status = pj_stun_session_send_msg(sess->stun, NULL, PJ_FALSE, 684 (sess-> tp_type==PJ_TURN_TP_UDP),732 (sess->conn_type==PJ_TURN_TP_UDP), 685 733 sess->srv_addr, 686 734 pj_sockaddr_get_len(sess->srv_addr), … … 834 882 */ 835 883 status = pj_stun_session_send_msg(sess->stun, peer, PJ_FALSE, 836 (sess-> tp_type==PJ_TURN_TP_UDP),884 (sess->conn_type==PJ_TURN_TP_UDP), 837 885 sess->srv_addr, 838 886 pj_sockaddr_get_len(sess->srv_addr), … … 850 898 */ 851 899 PJ_DEF(pj_status_t) pj_turn_session_on_rx_pkt(pj_turn_session *sess, 852 const pj_uint8_t *pkt, 853 unsigned pkt_len, 854 pj_bool_t is_datagram) 900 void *pkt, 901 unsigned pkt_len) 855 902 { 856 903 pj_bool_t is_stun; 857 904 pj_status_t status; 905 pj_bool_t is_datagram; 858 906 859 907 /* Packet could be ChannelData or STUN message (response or … … 864 912 pj_lock_acquire(sess->lock); 865 913 914 is_datagram = (sess->conn_type==PJ_TURN_TP_UDP); 915 866 916 /* Quickly check if this is STUN message */ 867 is_stun = (( pkt[0] & 0xC0) == 0);917 is_stun = ((((pj_uint8_t*)pkt)[0] & 0xC0) == 0); 868 918 869 919 if (is_stun) { … … 871 921 unsigned options; 872 922 873 options = PJ_STUN_CHECK_PACKET ;923 options = PJ_STUN_CHECK_PACKET | PJ_STUN_NO_FINGERPRINT_CHECK; 874 924 if (is_datagram) 875 925 options |= PJ_STUN_IS_DATAGRAM; … … 906 956 907 957 /* Notify application */ 908 (*sess->cb.on_rx_data)(sess, pkt+sizeof(cd), cd.length,909 &peer->addr,958 (*sess->cb.on_rx_data)(sess, ((pj_uint8_t*)pkt)+sizeof(cd), 959 cd.length, &peer->addr, 910 960 pj_sockaddr_get_len(&peer->addr)); 911 961 … … 954 1004 const pj_str_t *reason) 955 1005 { 1006 sess->last_status = status; 1007 956 1008 do { 957 1009 pj_str_t reason1; … … 1011 1063 const pj_stun_lifetime_attr *lf_attr; 1012 1064 const pj_stun_relay_addr_attr *raddr_attr; 1065 const pj_stun_sockaddr_attr *mapped_attr; 1013 1066 pj_str_t s; 1014 1067 pj_time_val timeout; … … 1070 1123 " address family is not supported " 1071 1124 "for now")); 1125 return; 1126 } 1127 if (raddr_attr && !pj_sockaddr_has_addr(&raddr_attr->sockaddr)) { 1128 on_session_fail(sess, method, PJNATH_EINSTUNMSG, 1129 pj_cstr(&s, "Error: Invalid IP address in " 1130 "RELAY-ADDRESS attribute")); 1072 1131 return; 1073 1132 } … … 1092 1151 } 1093 1152 1153 /* Get mapped address */ 1154 mapped_attr = (const pj_stun_sockaddr_attr*) 1155 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_XOR_MAPPED_ADDR, 0); 1156 if (mapped_attr) { 1157 pj_memcpy(&sess->mapped_addr, &mapped_attr->sockaddr, 1158 sizeof(mapped_attr->sockaddr)); 1159 } 1160 1094 1161 /* Success */ 1095 1162 … … 1133 1200 1134 1201 if (method == PJ_STUN_ALLOCATE_METHOD) { 1202 1203 /* Destroy if we have pending destroy request */ 1204 if (sess->pending_destroy) { 1205 if (status == PJ_SUCCESS) 1206 sess->state = PJ_TURN_STATE_READY; 1207 else 1208 sess->state = PJ_TURN_STATE_DEALLOCATED; 1209 sess_shutdown(sess, PJ_SUCCESS); 1210 return; 1211 } 1212 1135 1213 /* Handle ALLOCATE response */ 1136 1214 if (status==PJ_SUCCESS && … … 1299 1377 { 1300 1378 pj_turn_session *sess = (pj_turn_session*) user_data; 1301 unsigned i, cnt ;1379 unsigned i, cnt, tot_cnt; 1302 1380 1303 1381 /* Clear async resolver */ … … 1310 1388 } 1311 1389 1390 /* Calculate total number of server entries in the response */ 1391 tot_cnt = 0; 1392 for (i=0; i<rec->count; ++i) { 1393 tot_cnt += rec->entry[i].server.addr_count; 1394 } 1395 1396 if (tot_cnt > PJ_TURN_MAX_DNS_SRV_CNT) 1397 tot_cnt = PJ_TURN_MAX_DNS_SRV_CNT; 1398 1399 /* Allocate server entries */ 1400 sess->srv_addr_list = (pj_sockaddr*) 1401 pj_pool_calloc(sess->pool, tot_cnt, 1402 sizeof(pj_sockaddr)); 1403 1312 1404 /* Copy results to server entries */ 1313 for (i=0, cnt=0; i<rec->count && cnt< MAX_SRV_CNT; ++i) {1405 for (i=0, cnt=0; i<rec->count && cnt<PJ_TURN_MAX_DNS_SRV_CNT; ++i) { 1314 1406 unsigned j; 1315 1407 1316 for (j=0; j<rec->entry[i].server.addr_count && cnt<MAX_SRV_CNT; ++j) { 1408 for (j=0; j<rec->entry[i].server.addr_count && 1409 cnt<PJ_TURN_MAX_DNS_SRV_CNT; ++j) 1410 { 1317 1411 pj_sockaddr_in *addr = &sess->srv_addr_list[cnt].ipv4; 1318 1412
Note: See TracChangeset
for help on using the changeset viewer.