Changeset 1913 for pjproject/trunk/pjnath/src/pjturn-srv/server.c
- Timestamp:
- Apr 9, 2008 9:38:12 AM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjnath/src/pjturn-srv/server.c
r1879 r1913 29 29 #define MAX_LISTENERS 16 30 30 #define MAX_THREADS 2 31 #define MAX_NET_EVENTS 10 31 #define MAX_NET_EVENTS 1000 32 32 33 33 /* Prototypes */ 34 34 static int server_thread_proc(void *arg); 35 35 static pj_status_t on_tx_stun_msg( pj_stun_session *sess, 36 void *token, 36 37 const void *pkt, 37 38 pj_size_t pkt_size, … … 42 43 unsigned pkt_len, 43 44 const pj_stun_rx_data *rdata, 45 void *user_data, 44 46 const pj_sockaddr_t *src_addr, 45 47 unsigned src_addr_len); … … 78 80 { 79 81 pj_pool_t *pool; 82 pj_stun_session_cb sess_cb; 80 83 pj_turn_srv *srv; 81 84 unsigned i; … … 125 128 sizeof(srv->core.listener[0])); 126 129 127 /* Array of STUN sessions, one for each listener */128 srv->core.stun_sess = (pj_stun_session**)129 pj_pool_calloc(pool, MAX_LISTENERS,130 (sizeof(srv->core.stun_sess[0])));131 132 130 /* Create hash tables */ 133 131 srv->tables.alloc = pj_hash_create(pool, MAX_CLIENTS); … … 150 148 srv->core.cred.data.dyn_cred.get_password = &pj_turn_get_password; 151 149 srv->core.cred.data.dyn_cred.verify_nonce = &pj_turn_verify_nonce; 150 151 /* Create STUN session to handle new allocation */ 152 pj_bzero(&sess_cb, sizeof(sess_cb)); 153 sess_cb.on_rx_request = &on_rx_stun_request; 154 sess_cb.on_send_msg = &on_tx_stun_msg; 155 156 status = pj_stun_session_create(&srv->core.stun_cfg, srv->obj_name, 157 &sess_cb, PJ_FALSE, &srv->core.stun_sess); 158 if (status != PJ_SUCCESS) { 159 goto on_error; 160 } 161 162 pj_stun_session_set_user_data(srv->core.stun_sess, srv); 163 pj_stun_session_set_credential(srv->core.stun_sess, PJ_STUN_AUTH_LONG_TERM, 164 &srv->core.cred); 165 152 166 153 167 /* Array of worker threads */ … … 241 255 242 256 while (!srv->core.quit) { 243 pj_time_val timeout_max = {0, 500};257 pj_time_val timeout_max = {0, 100}; 244 258 srv_handle_events(srv, &timeout_max); 245 259 } … … 278 292 } 279 293 280 /* Destroy all listeners and STUN sessions associated with them. */294 /* Destroy all listeners. */ 281 295 for (i=0; i<srv->core.lis_cnt; ++i) { 282 296 if (srv->core.listener[i]) { … … 284 298 srv->core.listener[i] = NULL; 285 299 } 286 if (srv->core.stun_sess[i]) { 287 pj_stun_session_destroy(srv->core.stun_sess[i]); 288 srv->core.stun_sess[i] = NULL; 289 } 300 } 301 302 /* Destroy STUN session */ 303 if (srv->core.stun_sess) { 304 pj_stun_session_destroy(srv->core.stun_sess); 305 srv->core.stun_sess = NULL; 290 306 } 291 307 … … 342 358 pj_turn_listener *lis) 343 359 { 344 pj_stun_session_cb sess_cb;345 360 unsigned index; 346 pj_stun_session *sess;347 pj_status_t status;348 361 349 362 PJ_ASSERT_RETURN(srv && lis, PJ_EINVAL); … … 354 367 srv->core.listener[index] = lis; 355 368 lis->server = srv; 356 357 /* Create STUN session to handle new allocation */358 pj_bzero(&sess_cb, sizeof(sess_cb));359 sess_cb.on_rx_request = &on_rx_stun_request;360 sess_cb.on_send_msg = &on_tx_stun_msg;361 362 status = pj_stun_session_create(&srv->core.stun_cfg, lis->obj_name,363 &sess_cb, PJ_FALSE, &sess);364 if (status != PJ_SUCCESS) {365 srv->core.listener[index] = NULL;366 return status;367 }368 369 pj_stun_session_set_user_data(sess, lis);370 pj_stun_session_set_credential(sess, PJ_STUN_AUTH_LONG_TERM,371 &srv->core.cred);372 373 srv->core.stun_sess[index] = sess;374 369 lis->id = index; 375 370 srv->core.lis_cnt++; … … 379 374 380 375 return PJ_SUCCESS; 381 }382 383 384 /*385 * Send packet with this listener.386 */387 PJ_DEF(pj_status_t) pj_turn_listener_sendto(pj_turn_listener *listener,388 const void *packet,389 pj_size_t size,390 unsigned flag,391 const pj_sockaddr_t *addr,392 int addr_len)393 {394 pj_assert(listener->id != PJ_TURN_INVALID_LIS_ID);395 return listener->sendto(listener, packet, size, flag, addr, addr_len);396 376 } 397 377 … … 412 392 srv->core.lis_cnt--; 413 393 listener->id = PJ_TURN_INVALID_LIS_ID; 414 if (srv->core.stun_sess[i]) {415 pj_stun_session_destroy(srv->core.stun_sess[i]);416 srv->core.stun_sess[i] = NULL;417 }418 394 break; 419 395 } … … 423 399 /* Destroy */ 424 400 return listener->destroy(listener); 401 } 402 403 404 /** 405 * Add a reference to a transport. 406 */ 407 PJ_DEF(void) pj_turn_transport_add_ref( pj_turn_transport *transport, 408 pj_turn_allocation *alloc) 409 { 410 transport->add_ref(transport, alloc); 411 } 412 413 414 /** 415 * Decrement transport reference counter. 416 */ 417 PJ_DEF(void) pj_turn_transport_dec_ref( pj_turn_transport *transport, 418 pj_turn_allocation *alloc) 419 { 420 transport->dec_ref(transport, alloc); 425 421 } 426 422 … … 467 463 */ 468 464 static pj_status_t on_tx_stun_msg( pj_stun_session *sess, 469 const void *pkt, 470 pj_size_t pkt_size, 465 void *token, 466 const void *pdu, 467 pj_size_t pdu_size, 471 468 const pj_sockaddr_t *dst_addr, 472 469 unsigned addr_len) 473 470 { 474 pj_turn_ listener *listener;471 pj_turn_transport *transport = (pj_turn_transport*) token; 475 472 476 listener = (pj_turn_listener*) pj_stun_session_get_user_data(sess);477 478 PJ_ ASSERT_RETURN(listener!=NULL, PJ_EINVALIDOP);479 480 return pj_turn_listener_sendto(listener, pkt, pkt_size, 0,481 473 PJ_ASSERT_RETURN(transport!=NULL, PJ_EINVALIDOP); 474 475 PJ_UNUSED_ARG(sess); 476 477 return transport->sendto(transport, pdu, pdu_size, 0, 478 dst_addr, addr_len); 482 479 } 483 480 … … 485 482 /* Respond to STUN request */ 486 483 static pj_status_t stun_respond(pj_stun_session *sess, 484 pj_turn_transport *transport, 487 485 const pj_stun_rx_data *rdata, 488 486 unsigned code, … … 504 502 505 503 /* Send the response */ 506 return pj_stun_session_send_msg(sess, cache, dst_addr, addr_len, tdata); 504 return pj_stun_session_send_msg(sess, transport, cache, PJ_FALSE, 505 dst_addr, addr_len, tdata); 507 506 } 508 507 … … 510 509 /* Callback from our own STUN session when incoming request arrives. 511 510 * This function is triggered by pj_stun_session_on_rx_pkt() call in 512 511 * pj_turn_srv_on_rx_pkt() function below. 513 512 */ 514 513 static pj_status_t on_rx_stun_request(pj_stun_session *sess, 515 const pj_uint8_t *p kt,516 unsigned p kt_len,514 const pj_uint8_t *pdu, 515 unsigned pdu_len, 517 516 const pj_stun_rx_data *rdata, 517 void *token, 518 518 const pj_sockaddr_t *src_addr, 519 519 unsigned src_addr_len) 520 520 { 521 pj_turn_ listener *listener;521 pj_turn_transport *transport; 522 522 const pj_stun_msg *msg = rdata->msg; 523 523 pj_turn_srv *srv; … … 525 525 pj_status_t status; 526 526 527 PJ_UNUSED_ARG(p kt);528 PJ_UNUSED_ARG(p kt_len);529 530 listener = (pj_turn_listener*) pj_stun_session_get_user_data(sess);531 srv = listener->server;527 PJ_UNUSED_ARG(pdu); 528 PJ_UNUSED_ARG(pdu_len); 529 530 transport = (pj_turn_transport*) token; 531 srv = transport->listener->server; 532 532 533 533 /* Respond any requests other than ALLOCATE with 437 response */ 534 534 if (msg->hdr.type != PJ_STUN_ALLOCATE_REQUEST) { 535 stun_respond(sess, rdata, PJ_STUN_SC_ALLOCATION_MISMATCH,535 stun_respond(sess, transport, rdata, PJ_STUN_SC_ALLOCATION_MISMATCH, 536 536 NULL, PJ_FALSE, src_addr, src_addr_len); 537 537 return PJ_SUCCESS; … … 541 541 * in this function. 542 542 */ 543 status = pj_turn_allocation_create( listener, src_addr, src_addr_len,543 status = pj_turn_allocation_create(transport, src_addr, src_addr_len, 544 544 rdata, sess, &alloc); 545 545 if (status != PJ_SUCCESS) { … … 577 577 } else { 578 578 /* Otherwise this is a new client */ 579 unsigned options, lis_id; 579 unsigned options; 580 unsigned parsed_len; 580 581 pj_status_t status; 581 582 582 583 /* Check that this is a STUN message */ 583 584 options = PJ_STUN_CHECK_PACKET; 584 if (pkt-> listener->tp_type == PJ_TURN_TP_UDP)585 if (pkt->transport->listener->tp_type == PJ_TURN_TP_UDP) 585 586 options |= PJ_STUN_IS_DATAGRAM; 586 587 587 588 status = pj_stun_msg_check(pkt->pkt, pkt->len, options); 588 589 if (status != PJ_SUCCESS) { 589 char errmsg[PJ_ERR_MSG_SIZE]; 590 char ip[PJ_INET6_ADDRSTRLEN+10]; 591 592 pj_strerror(status, errmsg, sizeof(errmsg)); 593 PJ_LOG(5,(srv->obj_name, 594 "Non STUN packet from %s is dropped: %s", 595 pj_sockaddr_print(&pkt->src.clt_addr, ip, sizeof(ip), 3), 596 errmsg)); 590 /* If the first byte are not STUN, drop the packet. First byte 591 * of STUN message is always 0x00 or 0x01. Otherwise wait for 592 * more data as the data might have come from TCP. 593 * 594 * Also drop packet if it's unreasonably too big, as this might 595 * indicate invalid data that's building up in the buffer. 596 * 597 * Or if packet is a datagram. 598 */ 599 if ((*pkt->pkt != 0x00 && *pkt->pkt != 0x01) || 600 pkt->len > 1600 || 601 (options & PJ_STUN_IS_DATAGRAM)) 602 { 603 char errmsg[PJ_ERR_MSG_SIZE]; 604 char ip[PJ_INET6_ADDRSTRLEN+10]; 605 606 pkt->len = 0; 607 608 pj_strerror(status, errmsg, sizeof(errmsg)); 609 PJ_LOG(5,(srv->obj_name, 610 "Non-STUN packet from %s is dropped: %s", 611 pj_sockaddr_print(&pkt->src.clt_addr, ip, sizeof(ip), 3), 612 errmsg)); 613 } 597 614 return; 598 615 } 599 600 lis_id = pkt->listener->id;601 616 602 617 /* Hand over processing to STUN session. This will trigger … … 605 620 */ 606 621 options &= ~PJ_STUN_CHECK_PACKET; 607 status = pj_stun_session_on_rx_pkt(srv->core.stun_sess[lis_id], 608 pkt->pkt, pkt->len, options, NULL, 609 &pkt->src.clt_addr, 622 parsed_len = 0; 623 status = pj_stun_session_on_rx_pkt(srv->core.stun_sess, pkt->pkt, 624 pkt->len, options, pkt->transport, 625 &parsed_len, &pkt->src.clt_addr, 610 626 pkt->src_addr_len); 611 627 if (status != PJ_SUCCESS) { … … 618 634 pj_sockaddr_print(&pkt->src.clt_addr, ip, sizeof(ip), 3), 619 635 errmsg)); 620 return; 621 } 622 } 623 } 624 625 636 } 637 638 if (pkt->transport->listener->tp_type == PJ_TURN_TP_UDP) { 639 pkt->len = 0; 640 } else if (parsed_len > 0) { 641 if (parsed_len == pkt->len) { 642 pkt->len = 0; 643 } else { 644 pj_memmove(pkt->pkt, pkt->pkt+parsed_len, 645 pkt->len - parsed_len); 646 pkt->len -= parsed_len; 647 } 648 } 649 } 650 } 651 652
Note: See TracChangeset
for help on using the changeset viewer.