Changeset 1114 for pjproject/trunk
- Timestamp:
- Mar 29, 2007 9:54:21 PM (18 years ago)
- Location:
- pjproject/trunk
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjmedia/include/pjmedia/rtp.h
r974 r1114 78 78 79 79 /** 80 * RTP packet header. 80 * RTP packet header. Note that all RTP functions here will work with this 81 * header in network byte order. 81 82 */ 82 83 #pragma pack(1) … … 230 231 * @param ses The session. 231 232 * @param default_pt Default payload type. 232 * @param sender_ssrc SSRC used for outgoing packets .233 * @param sender_ssrc SSRC used for outgoing packets, in host byte order. 233 234 * 234 235 * @return PJ_SUCCESS if successfull. … … 263 264 * position regardless of any options present in the RTP packet. 264 265 * 266 * Note that this function does not modify the returned RTP header to 267 * host byte order. 268 * 265 269 * @param ses The session. 266 270 * @param pkt The received RTP packet. 267 271 * @param pkt_len The length of the packet. 268 * @param hdr Upon return will point to the location of the RTP header 269 * inside the packet. 272 * @param hdr Upon return will point to the location of the RTP 273 * header inside the packet. Note that the RTP header 274 * will be given back as is, meaning that the fields 275 * will be in network byte order. 270 276 * @param payload Upon return will point to the location of the 271 277 * payload inside the packet. … … 286 292 * 287 293 * @param ses The session. 288 * @param hdr The RTP header of the incoming packet. 294 * @param hdr The RTP header of the incoming packet. The header must 295 * be given with fields in network byte order. 289 296 * @param seq_st Optional structure to receive the status of the RTP packet 290 297 * processing. -
pjproject/trunk/pjmedia/src/pjmedia/transport_ice.c
r1112 r1114 25 25 { 26 26 pjmedia_transport base; 27 pj_ice_strans 27 pj_ice_strans *ice_st; 28 28 29 29 pj_time_val start_ice; … … 409 409 pj_ice_sess_cand cand[PJ_ICE_MAX_CAND]; 410 410 const pjmedia_sdp_media *sdp_med; 411 pj_bool_t remote_is_lite = PJ_FALSE; 412 const pj_str_t STR_CANDIDATE = {"candidate", 9}; 413 const pj_str_t STR_ICE_LITE = {"ice-lite", 8}; 411 414 pj_str_t uname, pass; 412 415 pj_status_t status; … … 445 448 pass = attr->value; 446 449 447 /* Get all candidates */450 /* Get all candidates in the media */ 448 451 cand_cnt = 0; 449 452 for (i=0; i<sdp_med->attr_count; ++i) { … … 451 454 452 455 attr = sdp_med->attr[i]; 453 if (pj_strcmp2(&attr->name, "candidate")!=0) 456 457 if (pj_strcmp(&attr->name, &STR_ICE_LITE)==0) 458 remote_is_lite = PJ_TRUE; 459 460 if (pj_strcmp(&attr->name, &STR_CANDIDATE)!=0) 454 461 continue; 455 462 … … 463 470 /* Mark start time */ 464 471 pj_gettimeofday(&tp_ice->start_ice); 472 473 /* If our role was controlled but it turns out that remote is 474 * a lite implementation, change our role to controlling. 475 */ 476 if (remote_is_lite && 477 tp_ice->ice_st->ice->role == PJ_ICE_SESS_ROLE_CONTROLLED) 478 { 479 pj_ice_sess_change_role(tp_ice->ice_st->ice, 480 PJ_ICE_SESS_ROLE_CONTROLLING); 481 } 465 482 466 483 /* Start ICE */ … … 553 570 struct transport_ice *tp_ice = (struct transport_ice*)tp; 554 571 return pj_ice_strans_sendto(tp_ice->ice_st, 1, 555 pkt, size, &tp_ice->remote_rtp,556 572 pkt, size, &tp_ice->remote_rtp, 573 sizeof(pj_sockaddr_in)); 557 574 } 558 575 … … 565 582 if (tp_ice->ice_st->comp_cnt > 1) { 566 583 return pj_ice_strans_sendto(tp_ice->ice_st, 2, 567 pkt, size, &tp_ice->remote_rtp,568 sizeof(pj_sockaddr_in));584 pkt, size, &tp_ice->remote_rtp, 585 sizeof(pj_sockaddr_in)); 569 586 } else { 570 587 return PJ_SUCCESS; -
pjproject/trunk/pjnath/include/pjnath/ice_session.h
r1111 r1114 445 445 pj_mutex_t *mutex; /**< Mutex. */ 446 446 pj_ice_sess_role role; /**< ICE role. */ 447 pj_timestamp tie_breaker; /**< Tie breaker value */ 447 448 pj_bool_t is_complete; /**< Complete? */ 448 449 pj_status_t ice_status; /**< Error status. */ … … 551 552 552 553 /** 554 * Change session role. This happens for example when ICE session was 555 * created with controlled role when receiving an offer, but it turns out 556 * that the offer contains "a=ice-lite" attribute when the SDP gets 557 * inspected. 558 * 559 * @param ice The ICE session. 560 * @param new_role The new role to be set. 561 * 562 * @return PJ_SUCCESS on success, or the appropriate error. 563 */ 564 PJ_DECL(pj_status_t) pj_ice_sess_change_role(pj_ice_sess *ice, 565 pj_ice_sess_role new_role); 566 567 568 /** 553 569 * Add a candidate to this ICE session. Application must add candidates for 554 570 * each components ID before it can start pairing the candidates and -
pjproject/trunk/pjnath/include/pjnath/ice_strans.h
r1111 r1114 28 28 #include <pjlib-util/resolver.h> 29 29 #include <pj/ioqueue.h> 30 #include <pj/timer.h> 30 31 31 32 … … 315 316 pj_sockaddr_in stun_srv; /**< STUN server address. */ 316 317 pj_sockaddr_in turn_srv; /**< TURN server address. */ 318 319 pj_timer_entry ka_timer; /**< STUN keep-alive timer. */ 317 320 }; 318 321 -
pjproject/trunk/pjnath/include/pjnath/stun_msg.h
r1111 r1114 311 311 PJ_STUN_ATTR_REFRESH_INTERVAL = 0x8024,/**< REFRESH-INTERVAL. */ 312 312 PJ_STUN_ATTR_FINGERPRINT = 0x8028,/**< FINGERPRINT attribute. */ 313 PJ_STUN_ATTR_ICE_CONTROLLED = 0x8029,/**< ICE-CCONTROLLED attribute.*/ 314 PJ_STUN_ATTR_ICE_CONTROLLING = 0x802a,/**< ICE-CCONTROLLING attribute*/ 313 315 314 316 PJ_STUN_ATTR_END_EXTENDED_ATTR … … 345 347 PJ_STUN_SC_ALLOCATION_QUOTA_REACHED = 486, /**< Allocation Quota Reached 346 348 (TURN) */ 349 PJ_STUN_SC_ROLE_CONFLICT = 487, /**< Role Conflict */ 347 350 PJ_STUN_SC_SERVER_ERROR = 500, /**< Server Error */ 348 351 PJ_STUN_SC_INSUFFICIENT_CAPACITY = 507, /**< Insufficient Capacity … … 419 422 | Type | Length | 420 423 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 421 | Value .... |422 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+423 424 424 425 \endverbatim … … 534 535 535 536 /** 536 * The 32bit value .537 * The 32bit value, in host byte order. 537 538 */ 538 539 pj_uint32_t value; 539 540 540 541 } pj_stun_uint_attr; 542 543 544 /** 545 * This structure represents a generic STUN attributes with 64bit (unsigned) 546 * integer value, such as ICE-CONTROLLED and ICE-CONTROLLING attributes. 547 */ 548 typedef struct pj_stun_uint64_attr 549 { 550 /** 551 * Standard STUN attribute header. 552 */ 553 pj_stun_attr_hdr hdr; 554 555 /** 556 * The 64bit value, in host byte order, represented with pj_timestamp. 557 */ 558 pj_timestamp value; 559 560 } pj_stun_uint64_attr; 541 561 542 562 … … 622 642 623 643 /** 624 * The value must be zero. 625 */ 626 pj_uint16_t zero; 627 628 /** 629 * Error class (1-6). 630 */ 631 pj_uint8_t err_class; 632 633 /** 634 * Error number is the error number modulo 100. 635 */ 636 pj_uint8_t number; 644 * STUN error code. 645 */ 646 int err_code; 637 647 638 648 /** … … 1350 1360 1351 1361 /** 1362 * Create a STUN generic 64bit value attribute. 1363 * 1364 * @param pool Pool to allocate memory from. 1365 * @param attr_type Attribute type, from #pj_stun_attr_type. 1366 * @param value Optional value to be assigned. 1367 * @param p_attr Pointer to receive the attribute. 1368 * 1369 * @return PJ_SUCCESS on success or the appropriate error code. 1370 */ 1371 PJ_DEF(pj_status_t) pj_stun_uint64_attr_create(pj_pool_t *pool, 1372 int attr_type, 1373 const pj_timestamp *value, 1374 pj_stun_uint64_attr **p_attr); 1375 1376 1377 /** 1378 * Create and add STUN generic 64bit value attribute to the message. 1379 * 1380 * @param pool The pool to allocate memory from. 1381 * @param msg The STUN message 1382 * @param attr_type Attribute type, from #pj_stun_attr_type. 1383 * @param value The 64bit value to be assigned to the attribute. 1384 * 1385 * @return PJ_SUCCESS on success or the appropriate error code. 1386 */ 1387 PJ_DECL(pj_status_t) pj_stun_msg_add_uint64_attr(pj_pool_t *pool, 1388 pj_stun_msg *msg, 1389 int attr_type, 1390 const pj_timestamp *value); 1391 1392 /** 1352 1393 * Create a STUN MESSAGE-INTEGRITY attribute. 1353 1394 * -
pjproject/trunk/pjnath/include/pjnath/types.h
r1111 r1114 52 52 53 53 /** 54 * @mainpage PJNATH - Open Source STUN, TURN, and ICELibrary54 * @mainpage PJNATH - Open Source ICE, STUN, and TURN Library 55 55 * 56 56 * \n 57 57 * This is the documentation of PJNATH, an Open Source library providing 58 * NAT traversal helper functionalities by using standard based protocols 59 * such as: 60 * - <b>STUN</b> (Session Traversal Utilities), 61 * - <b>TURN</b> (Obtaining Relay Addresses from STUN) 62 * - <b>ICE</b> (Interactive Connectivity Establishment). 63 * 64 * The following sections will give a short overview about the protocols 65 * supported by this library, and how they are implemented in PJNATH. 58 * NAT traversal helper functionalities by using standard based protocols. 66 59 * 67 60 * \n … … 71 64 * Session Traversal Utilities (STUN, or previously known as Simple 72 65 * Traversal of User Datagram Protocol (UDP) Through Network Address 73 * Translators (NAT)s), was previously released as IETF standard 74 * <A HREF="http://www.ietf.org/rfc/rfc3489.txt">RFC 3489</A>, but since 75 * then it has been revised into the following: 76 * - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-rfc3489bis-06.txt"> 77 * <B>draft-ietf-behave-rfc3489bis-06</b></A> for the main STUN 78 * specification, 79 * - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-turn-03.txt"> 80 * <B>draft-ietf-behave-turn-03</B></A> for TURN usage of STUN, 81 * - and several other drafts explaining other STUN usages. 66 * Translators (NAT)s), is a lightweight protocol that serves as a tool for 67 * application protocols in dealing with NAT traversal. It allows a client 68 * to determine the IP address and port allocated to them by a NAT and to 69 * keep NAT bindings open. 82 70 * 83 71 * The PJNATH library provides facilities to support both the core … … 134 122 * components with callback to send outgoing messages. 135 123 * 124 * 125 * \subsection PJNATH_STUN_REF STUN Reference 126 * 127 * References for STUN: 128 * 129 * - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-rfc3489bis-06.txt"> 130 * <B>draft-ietf-behave-rfc3489bis-06</b></A>: Session Traversal 131 * Utilities for (NAT) (STUN), 132 * - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-behave-turn-03.txt"> 133 * <B>draft-ietf-behave-turn-03</B></A>: Obtaining Relay Addresses 134 * from Simple Traversal Underneath NAT (STUN) 135 * - Obsoleted: <A HREF="http://www.ietf.org/rfc/rfc3489.txt">RFC 3489</A>. 136 * 136 137 * \n 137 138 * … … 171 172 * ICE stream transport and provides SDP translations to be used 172 173 * for SIP offer/answer exchanges. 174 * 175 * \subsection PJNATH_ICE_REF Reference 176 * 177 * References for ICE: 178 * - <A HREF="http://www.ietf.org/internet-drafts/draft-ietf-mmusic-ice-15.txt"> 179 * <B>draft-ietf-mmusic-ice-15.txt</B></A>: Interactive Connectivity 180 * Establishment (ICE): A Methodology for Network Address Translator 181 * (NAT) Traversal for Offer/Answer Protocols 173 182 */ 174 183 -
pjproject/trunk/pjnath/src/pjnath/ice_session.c
r1113 r1114 57 57 }; 58 58 59 static const char *role_names[] = 60 { 61 "Controlled", 62 "Controlling" 63 }; 64 59 65 #define CHECK_NAME_LEN 128 60 66 #define LOG4(expr) PJ_LOG(4,expr) … … 197 203 ice->pool = pool; 198 204 ice->role = role; 205 ice->tie_breaker.u32.hi = pj_rand(); 206 ice->tie_breaker.u32.lo = pj_rand(); 199 207 200 208 pj_ansi_snprintf(ice->obj_name, sizeof(ice->obj_name), … … 238 246 LOG4((ice->obj_name, 239 247 "ICE session created, comp_cnt=%d, role is %s agent", 240 comp_cnt, 241 (ice->role==PJ_ICE_SESS_ROLE_CONTROLLING ? 242 "controlling":"controlled"))); 248 comp_cnt, role_names[ice->role])); 243 249 244 250 return PJ_SUCCESS; … … 290 296 PJ_ASSERT_RETURN(ice, PJ_EINVAL); 291 297 destroy_ice(ice, PJ_SUCCESS); 298 return PJ_SUCCESS; 299 } 300 301 302 /* 303 * Change session role. 304 */ 305 PJ_DEF(pj_status_t) pj_ice_sess_change_role(pj_ice_sess *ice, 306 pj_ice_sess_role new_role) 307 { 308 PJ_ASSERT_RETURN(ice, PJ_EINVAL); 309 310 if (new_role != ice->role) { 311 ice->role = new_role; 312 LOG4((ice->obj_name, "Role changed to %s", role_names[new_role])); 313 } 314 292 315 return PJ_SUCCESS; 293 316 } -
pjproject/trunk/pjnath/src/pjnath/ice_strans.c
r1111 r1114 61 61 const pj_stun_msg *response); 62 62 63 /* Keep-alive timer */ 64 static void start_ka_timer(pj_ice_strans *ice_st); 65 static void stop_ka_timer(pj_ice_strans *ice_st); 66 63 67 /* Utility: print error */ 64 68 #if PJ_LOG_MAX_LEVEL >= 3 … … 126 130 } 127 131 132 /* Kill keep-alive timer, if any */ 133 stop_ka_timer(ice_st); 134 128 135 /* Destroy ICE if we have ICE */ 129 136 if (ice_st->ice) { … … 197 204 return PJ_SUCCESS; 198 205 } 199 200 206 201 207 /* Add new candidate */ … … 506 512 507 513 514 /* STUN keep-alive timer callback */ 515 static void ka_timer_cb(pj_timer_heap_t *th, pj_timer_entry *te) 516 { 517 pj_ice_strans *ice_st = (pj_ice_strans*)te->user_data; 518 unsigned i; 519 pj_status_t status; 520 521 PJ_UNUSED_ARG(th); 522 523 ice_st->ka_timer.id = PJ_FALSE; 524 525 for (i=0; i<ice_st->comp_cnt; ++i) { 526 pj_ice_strans_comp *comp = ice_st->comp[i]; 527 pj_stun_tx_data *tdata; 528 unsigned j; 529 530 /* Does this component have STUN server reflexive candidate? */ 531 for (j=0; j<comp->cand_cnt; ++j) { 532 if (comp->cand_list[j].type == PJ_ICE_CAND_TYPE_SRFLX) 533 break; 534 } 535 if (j == comp->cand_cnt) 536 continue; 537 538 /* Create STUN binding request */ 539 status = pj_stun_session_create_req(comp->stun_sess, 540 PJ_STUN_BINDING_REQUEST, &tdata); 541 if (status != PJ_SUCCESS) 542 continue; 543 544 /* tdata->user_data is NULL for keep-alive */ 545 tdata->user_data = NULL; 546 547 /* Send STUN binding request */ 548 PJ_LOG(5,(ice_st->obj_name, "Sending STUN keep-alive")); 549 status = pj_stun_session_send_msg(comp->stun_sess, PJ_FALSE, 550 &ice_st->stun_srv, 551 sizeof(pj_sockaddr_in), tdata); 552 } 553 554 /* Start next timer */ 555 start_ka_timer(ice_st); 556 } 557 558 /* Start STUN keep-alive timer */ 559 static void start_ka_timer(pj_ice_strans *ice_st) 560 { 561 pj_time_val delay; 562 563 /* Skip if timer is already running */ 564 if (ice_st->ka_timer.id != PJ_FALSE) 565 return; 566 567 delay.sec = 20; 568 delay.msec = 0; 569 570 ice_st->ka_timer.cb = &ka_timer_cb; 571 ice_st->ka_timer.user_data = ice_st; 572 573 if (pj_timer_heap_schedule(ice_st->stun_cfg.timer_heap, 574 &ice_st->ka_timer, &delay)==PJ_SUCCESS) 575 { 576 ice_st->ka_timer.id = PJ_TRUE; 577 } 578 } 579 580 581 /* Stop STUN keep-alive timer */ 582 static void stop_ka_timer(pj_ice_strans *ice_st) 583 { 584 /* Skip if timer is already stop */ 585 if (ice_st->ka_timer.id == PJ_FALSE) 586 return; 587 588 pj_timer_heap_cancel(ice_st->stun_cfg.timer_heap, &ice_st->ka_timer); 589 ice_st->ka_timer.id = PJ_FALSE; 590 } 591 508 592 509 593 /* … … 831 915 } 832 916 833 #if 1 834 PJ_UNUSED_ARG(pkt_size); 835 PJ_UNUSED_ARG(status); 836 837 /* Otherwise return error */ 838 return PJNATH_EICEINPROGRESS; 839 #else 840 /* Otherwise send direcly with the socket */ 917 /* Otherwise send direcly with the socket. This is for compatibility 918 * with remote that doesn't support ICE. 919 */ 841 920 pkt_size = data_len; 842 921 status = pj_ioqueue_sendto(comp->key, &comp->write_op, … … 845 924 846 925 return (status==PJ_SUCCESS||status==PJ_EPENDING) ? PJ_SUCCESS : status; 847 #endif848 926 } 849 927 … … 943 1021 comp = (pj_ice_strans_comp*) pj_stun_session_get_user_data(sess); 944 1022 cand = (pj_ice_strans_cand*) tdata->user_data; 1023 1024 if (cand == NULL) { 1025 /* This is keep-alive */ 1026 return; 1027 } 945 1028 946 1029 /* Decrement pending count for this component */ … … 981 1064 comp->default_cand = (cand - comp->cand_list); 982 1065 comp->last_status = PJ_SUCCESS; 983 } 984 1066 1067 /* We have STUN, so we must start the keep-alive timer */ 1068 start_ka_timer(comp->ice_st); 1069 } 1070 -
pjproject/trunk/pjnath/src/pjnath/stun_msg.c
r1111 r1114 72 72 { PJ_STUN_SC_CONNECTION_TIMEOUT, "Connection Timeout"}, 73 73 { PJ_STUN_SC_ALLOCATION_QUOTA_REACHED, "Allocation Quota Reached"}, 74 { PJ_STUN_SC_ROLE_CONFLICT, "Role Conflict"}, 74 75 { PJ_STUN_SC_SERVER_ERROR, "Server Error"}, 75 76 { PJ_STUN_SC_INSUFFICIENT_CAPACITY, "Insufficient Capacity"}, … … 86 87 pj_status_t (*encode_attr)(const void *a, pj_uint8_t *buf, 87 88 unsigned len, unsigned *printed); 88 89 89 }; 90 90 … … 123 123 static pj_status_t encode_uint_attr(const void *a, pj_uint8_t *buf, 124 124 unsigned len, unsigned *printed); 125 static pj_status_t decode_uint64_attr(pj_pool_t *pool, 126 const pj_uint8_t *buf, 127 void **p_attr); 128 static pj_status_t encode_uint64_attr(const void *a, pj_uint8_t *buf, 129 unsigned len, unsigned *printed); 125 130 static pj_status_t decode_binary_attr(pj_pool_t *pool, 126 131 const pj_uint8_t *buf, … … 430 435 &decode_uint_attr, 431 436 &encode_uint_attr 437 }, 438 { 439 /* PJ_STUN_ATTR_ICE_CONTROLLED, */ 440 "ICE-CCONTROLLED", 441 &decode_uint64_attr, 442 &encode_uint64_attr 443 }, 444 { 445 /* PJ_STUN_ATTR_ICE_CONTROLLING, */ 446 "ICE-CCONTROLLING", 447 &decode_uint64_attr, 448 &encode_uint64_attr 432 449 } 433 450 }; … … 552 569 553 570 571 ////////////////////////////////////////////////////////////////////////////// 572 554 573 555 574 #define INIT_ATTR(a,t,l) (a)->hdr.type=(pj_uint16_t)(t), \ … … 557 576 #define ATTR_HDR_LEN 4 558 577 559 #define getval16(p, pos) (pj_uint16_t)(((p)[(pos)] << 8) | \ 560 ((p)[(pos) + 1] << 0)) 561 578 static pj_uint16_t GETVAL16H(const pj_uint8_t *buf, unsigned pos) 579 { 580 return (pj_uint16_t) ((buf[pos + 0] << 8) | \ 581 (buf[pos + 1] << 0)); 582 } 583 584 static pj_uint16_t GETVAL16N(const pj_uint8_t *buf, unsigned pos) 585 { 586 return pj_htons(GETVAL16H(buf,pos)); 587 } 588 589 static void PUTVAL16H(pj_uint8_t *buf, unsigned pos, pj_uint16_t hval) 590 { 591 buf[pos+0] = (pj_uint8_t) ((hval & 0xFF00) >> 8); 592 buf[pos+1] = (pj_uint8_t) ((hval & 0x00FF) >> 0); 593 } 594 595 static pj_uint32_t GETVAL32H(const pj_uint8_t *buf, unsigned pos) 596 { 597 return (pj_uint32_t) ((buf[pos + 0] << 24UL) | \ 598 (buf[pos + 1] << 16UL) | \ 599 (buf[pos + 2] << 8UL) | \ 600 (buf[pos + 3] << 0UL)); 601 } 602 603 static pj_uint32_t GETVAL32N(const pj_uint8_t *buf, unsigned pos) 604 { 605 return pj_htonl(GETVAL32H(buf,pos)); 606 } 607 608 static void PUTVAL32H(pj_uint8_t *buf, unsigned pos, pj_uint32_t hval) 609 { 610 buf[pos+0] = (pj_uint8_t) ((hval & 0xFF000000UL) >> 24); 611 buf[pos+1] = (pj_uint8_t) ((hval & 0x00FF0000UL) >> 16); 612 buf[pos+2] = (pj_uint8_t) ((hval & 0x0000FF00UL) >> 8); 613 buf[pos+3] = (pj_uint8_t) ((hval & 0x000000FFUL) >> 0); 614 } 615 616 static void GETVAL64H(const pj_uint8_t *buf, unsigned pos, pj_timestamp *ts) 617 { 618 ts->u32.hi = GETVAL32H(buf, pos); 619 ts->u32.lo = GETVAL32H(buf, pos+4); 620 } 621 622 static void PUTVAL64H(pj_uint8_t *buf, unsigned pos, const pj_timestamp *ts) 623 { 624 PUTVAL32H(buf, pos, ts->u32.hi); 625 PUTVAL32H(buf, pos+4, ts->u32.lo); 626 } 627 628 629 static void GETATTRHDR(const pj_uint8_t *buf, pj_stun_attr_hdr *hdr) 630 { 631 hdr->type = GETVAL16H(buf, 0); 632 hdr->length = GETVAL16H(buf, 2); 633 } 562 634 563 635 ////////////////////////////////////////////////////////////////////////////// … … 627 699 /* Create the attribute */ 628 700 attr = PJ_POOL_ZALLOC_T(pool, pj_stun_sockaddr_attr); 629 pj_memcpy(attr, buf, ATTR_HDR_LEN); 630 631 /* Convert to host byte order */ 632 attr->hdr.type = pj_ntohs(attr->hdr.type); 633 attr->hdr.length = pj_ntohs(attr->hdr.length); 701 GETATTRHDR(buf, &attr->hdr); 634 702 635 703 /* Check that the attribute length is valid */ … … 646 714 /* Get port and address */ 647 715 pj_sockaddr_in_init(&attr->sockaddr.ipv4, NULL, 0); 648 pj_memcpy(&attr->sockaddr.ipv4.sin_port, buf+ATTR_HDR_LEN+2,2);649 pj_memcpy(&attr->sockaddr.ipv4.sin_addr, buf+ATTR_HDR_LEN+4,4);716 attr->sockaddr.ipv4.sin_port = GETVAL16N(buf, ATTR_HDR_LEN+2); 717 attr->sockaddr.ipv4.sin_addr.s_addr = GETVAL32N(buf, ATTR_HDR_LEN+4); 650 718 651 719 /* Done */ … … 661 729 { 662 730 pj_stun_sockaddr_attr *attr; 663 pj_uint32_t val; 664 665 /* Create the attribute */ 666 attr = PJ_POOL_ZALLOC_T(pool, pj_stun_sockaddr_attr); 667 pj_memcpy(attr, buf, ATTR_HDR_LEN); 668 669 /* Convert to host byte order */ 670 attr->hdr.type = pj_ntohs(attr->hdr.type); 671 attr->hdr.length = pj_ntohs(attr->hdr.length); 672 673 /* Check that the attribute length is valid */ 674 if (attr->hdr.length != STUN_GENERIC_IP_ADDR_LEN) 675 return PJNATH_ESTUNINATTRLEN; 676 677 /* Check address family */ 678 val = *(pj_uint8_t*)(buf + ATTR_HDR_LEN + 1); 679 680 /* Check address family is valid (only supports ipv4 for now) */ 681 if (val != 1) 682 return PJNATH_ESTUNIPV6NOTSUPP; 683 684 /* Get port and address */ 685 pj_sockaddr_in_init(&attr->sockaddr.ipv4, NULL, 0); 686 pj_memcpy(&attr->sockaddr.ipv4.sin_port, buf+ATTR_HDR_LEN+2, 2); 687 pj_memcpy(&attr->sockaddr.ipv4.sin_addr, buf+ATTR_HDR_LEN+4, 4); 688 731 pj_status_t status; 732 733 status = decode_sockaddr_attr(pool, buf, &attr); 734 if (status != PJ_SUCCESS) 735 return status; 736 737 attr->xor_ed = PJ_TRUE; 689 738 attr->sockaddr.ipv4.sin_port ^= pj_htons(0x2112); 690 739 attr->sockaddr.ipv4.sin_addr.s_addr ^= pj_htonl(0x2112A442); … … 706 755 const pj_stun_sockaddr_attr *ca = 707 756 (const pj_stun_sockaddr_attr *)a; 708 pj_stun_sockaddr_attr *attr;709 757 710 758 if (len < ATTR_LEN) … … 712 760 713 761 /* Copy and convert headers to network byte order */ 714 pj_memcpy(buf, a, ATTR_HDR_LEN); 715 attr = (pj_stun_sockaddr_attr*) buf; 716 attr->hdr.type = pj_htons(attr->hdr.type); 717 attr->hdr.length = pj_htons((pj_uint16_t)STUN_GENERIC_IP_ADDR_LEN); 762 PUTVAL16H(buf, 0, ca->hdr.type); 763 PUTVAL16H(buf, 2, STUN_GENERIC_IP_ADDR_LEN); 718 764 buf += ATTR_HDR_LEN; 719 765 … … 820 866 /* Create the attribute */ 821 867 attr = PJ_POOL_ZALLOC_T(pool, pj_stun_string_attr); 822 823 /* Copy the header */ 824 pj_memcpy(attr, buf, ATTR_HDR_LEN); 825 826 /* Convert to host byte order */ 827 attr->hdr.type = pj_ntohs(attr->hdr.type); 828 attr->hdr.length = pj_ntohs(attr->hdr.length); 868 GETATTRHDR(buf, &attr->hdr); 829 869 830 870 /* Get pointer to the string in the message */ … … 848 888 const pj_stun_string_attr *ca = 849 889 (const pj_stun_string_attr*)a; 850 pj_stun_attr_hdr *attr;851 890 852 891 /* Calculated total attr_len (add padding if necessary) */ … … 857 896 } 858 897 859 /* Copy header */ 860 pj_memcpy(buf, a, ATTR_HDR_LEN); 861 attr = (pj_stun_attr_hdr*)buf; 862 863 /* Set the correct length */ 864 attr->length = (pj_uint16_t) ca->value.slen; 865 866 /* Convert to network byte order */ 867 attr->type = pj_htons(attr->type); 868 attr->length = pj_htons(attr->length); 898 PUTVAL16H(buf, 0, ca->hdr.type); 899 PUTVAL16H(buf, 2, (pj_uint16_t)ca->value.slen); 900 869 901 870 902 /* Copy the string */ … … 930 962 /* Create the attribute */ 931 963 attr = PJ_POOL_ZALLOC_T(pool, pj_stun_empty_attr); 932 pj_memcpy(attr, buf, ATTR_HDR_LEN); 933 934 /* Convert to host byte order */ 935 attr->hdr.type = pj_ntohs(attr->hdr.type); 936 attr->hdr.length = pj_ntohs(attr->hdr.length); 964 GETATTRHDR(buf, &attr->hdr); 937 965 938 966 /* Check that the attribute length is valid */ … … 950 978 unsigned len, unsigned *printed) 951 979 { 952 pj_stun_empty_attr *attr;980 const pj_stun_empty_attr *ca = (pj_stun_empty_attr*)a; 953 981 954 982 if (len < ATTR_HDR_LEN) 955 983 return PJ_ETOOSMALL; 956 984 957 /* Copy and convert attribute to network byte order */ 958 pj_memcpy(buf, a, ATTR_HDR_LEN); 959 attr = (pj_stun_empty_attr*) buf; 960 attr->hdr.type = pj_htons(attr->hdr.type); 961 attr->hdr.length = 0; 985 PUTVAL16H(buf, 0, ca->hdr.type); 986 PUTVAL16H(buf, 2, 0); 962 987 963 988 /* Done */ … … 972 997 * STUN generic 32bit integer attribute. 973 998 */ 974 #define STUN_UINT_LEN 4975 999 976 1000 /* … … 988 1012 989 1013 attr = PJ_POOL_ZALLOC_T(pool, pj_stun_uint_attr); 990 INIT_ATTR(attr, attr_type, STUN_UINT_LEN);1014 INIT_ATTR(attr, attr_type, 4); 991 1015 attr->value = value; 992 1016 … … 1017 1041 void **p_attr) 1018 1042 { 1019 enum1020 {1021 ATTR_LEN = STUN_UINT_LEN + ATTR_HDR_LEN1022 };1023 1043 pj_stun_uint_attr *attr; 1024 1025 /* Check that the struct address is valid */1026 pj_assert(sizeof(pj_stun_uint_attr) == ATTR_LEN);1027 1044 1028 1045 /* Create the attribute */ 1029 1046 attr = PJ_POOL_ZALLOC_T(pool, pj_stun_uint_attr); 1030 pj_memcpy(attr, buf, ATTR_LEN); 1031 1032 /* Convert to host byte order */ 1033 attr->hdr.type = pj_ntohs(attr->hdr.type); 1034 attr->hdr.length = pj_ntohs(attr->hdr.length); 1035 attr->value = pj_ntohl(attr->value); 1047 GETATTRHDR(buf, &attr->hdr); 1048 1049 attr->value = GETVAL32H(buf, 4); 1036 1050 1037 1051 /* Check that the attribute length is valid */ 1038 if (attr->hdr.length != STUN_UINT_LEN)1052 if (attr->hdr.length != 4) 1039 1053 return PJNATH_ESTUNINATTRLEN; 1040 1054 … … 1049 1063 unsigned len, unsigned *printed) 1050 1064 { 1051 enum 1052 { 1053 ATTR_LEN = STUN_UINT_LEN + ATTR_HDR_LEN 1054 }; 1055 pj_stun_uint_attr *attr; 1056 1057 if (len < ATTR_LEN) 1065 const pj_stun_uint_attr *ca = (const pj_stun_uint_attr*)a; 1066 1067 if (len < 8) 1058 1068 return PJ_ETOOSMALL; 1059 1069 1060 /* Copy and convert attribute to network byte order */ 1061 pj_memcpy(buf, a, ATTR_LEN); 1062 attr = (pj_stun_uint_attr*) buf; 1063 attr->hdr.type = pj_htons(attr->hdr.type); 1064 pj_assert(attr->hdr.length == STUN_UINT_LEN); 1065 attr->hdr.length = pj_htons(STUN_UINT_LEN); 1066 attr->value = pj_htonl(attr->value); 1067 1070 PUTVAL16H(buf, 0, ca->hdr.type); 1071 PUTVAL16H(buf, 2, (pj_uint16_t)4); 1072 PUTVAL32H(buf, 4, ca->value); 1073 1068 1074 /* Done */ 1069 *printed = ATTR_LEN;1075 *printed = 8; 1070 1076 1071 1077 return PJ_SUCCESS; … … 1073 1079 1074 1080 ////////////////////////////////////////////////////////////////////////////// 1081 1082 /* 1083 * Create a STUN generic 64bit value attribute. 1084 */ 1085 PJ_DEF(pj_status_t) 1086 pj_stun_uint64_attr_create(pj_pool_t *pool, 1087 int attr_type, 1088 const pj_timestamp *value, 1089 pj_stun_uint64_attr **p_attr) 1090 { 1091 pj_stun_uint64_attr *attr; 1092 1093 PJ_ASSERT_RETURN(pool && p_attr, PJ_EINVAL); 1094 1095 attr = PJ_POOL_ZALLOC_T(pool, pj_stun_uint64_attr); 1096 INIT_ATTR(attr, attr_type, 4); 1097 1098 if (value) { 1099 attr->value.u32.hi = value->u32.hi; 1100 attr->value.u32.lo = value->u32.lo; 1101 } 1102 1103 *p_attr = attr; 1104 1105 return PJ_SUCCESS; 1106 } 1107 1108 /* Create and add STUN generic 64bit value attribute to the message. */ 1109 PJ_DEF(pj_status_t) pj_stun_msg_add_uint64_attr(pj_pool_t *pool, 1110 pj_stun_msg *msg, 1111 int attr_type, 1112 const pj_timestamp *value) 1113 { 1114 pj_stun_uint64_attr *attr = NULL; 1115 pj_status_t status; 1116 1117 status = pj_stun_uint64_attr_create(pool, attr_type, value, &attr); 1118 if (status != PJ_SUCCESS) 1119 return status; 1120 1121 return pj_stun_msg_add_attr(msg, &attr->hdr); 1122 } 1123 1124 static pj_status_t decode_uint64_attr(pj_pool_t *pool, 1125 const pj_uint8_t *buf, 1126 void **p_attr) 1127 { 1128 pj_stun_uint64_attr *attr; 1129 1130 /* Create the attribute */ 1131 attr = PJ_POOL_ZALLOC_T(pool, pj_stun_uint64_attr); 1132 GETATTRHDR(buf, &attr->hdr); 1133 1134 if (attr->hdr.length != 8) 1135 return PJNATH_ESTUNINATTRLEN; 1136 1137 GETVAL64H(buf, 4, &attr->value); 1138 1139 /* Done */ 1140 *p_attr = attr; 1141 1142 return PJ_SUCCESS; 1143 } 1144 1145 1146 static pj_status_t encode_uint64_attr(const void *a, pj_uint8_t *buf, 1147 unsigned len, unsigned *printed) 1148 { 1149 const pj_stun_uint64_attr *ca = (const pj_stun_uint64_attr*)a; 1150 1151 if (len < 12) 1152 return PJ_ETOOSMALL; 1153 1154 PUTVAL16H(buf, 0, ca->hdr.type); 1155 PUTVAL16H(buf, 2, ca->hdr.length); 1156 PUTVAL64H(buf, 4, &ca->value); 1157 1158 /* Done */ 1159 *printed = 12; 1160 1161 return PJ_SUCCESS; 1162 } 1163 1164 1165 ////////////////////////////////////////////////////////////////////////////// 1075 1166 /* 1076 1167 * STUN MESSAGE-INTEGRITY attribute. 1077 1168 */ 1078 1079 #define STUN_MSG_INTEGRITY_LEN 201080 1169 1081 1170 /* … … 1091 1180 1092 1181 attr = PJ_POOL_ZALLOC_T(pool, pj_stun_msgint_attr); 1093 INIT_ATTR(attr, PJ_STUN_ATTR_MESSAGE_INTEGRITY, STUN_MSG_INTEGRITY_LEN);1182 INIT_ATTR(attr, PJ_STUN_ATTR_MESSAGE_INTEGRITY, 20); 1094 1183 1095 1184 *p_attr = attr; … … 1116 1205 void **p_attr) 1117 1206 { 1118 enum1119 {1120 ATTR_LEN = STUN_MSG_INTEGRITY_LEN + ATTR_HDR_LEN1121 };1122 1207 pj_stun_msgint_attr *attr; 1123 1124 /* Check that struct size is valid */1125 pj_assert(sizeof(pj_stun_msgint_attr)==ATTR_LEN);1126 1208 1127 1209 /* Create attribute */ 1128 1210 attr = PJ_POOL_ZALLOC_T(pool, pj_stun_msgint_attr); 1129 pj_memcpy(attr, buf, sizeof(pj_stun_msgint_attr)); 1130 attr->hdr.type = pj_ntohs(attr->hdr.type); 1131 attr->hdr.length = pj_ntohs(attr->hdr.length); 1211 GETATTRHDR(buf, &attr->hdr); 1132 1212 1133 1213 /* Check that the attribute length is valid */ 1134 if (attr->hdr.length != STUN_MSG_INTEGRITY_LEN)1214 if (attr->hdr.length != 20) 1135 1215 return PJNATH_ESTUNINATTRLEN; 1216 1217 /* Copy hmac */ 1218 pj_memcpy(attr->hmac, buf+4, 20); 1136 1219 1137 1220 /* Done */ … … 1144 1227 unsigned len, unsigned *printed) 1145 1228 { 1146 enum 1147 { 1148 ATTR_LEN = STUN_MSG_INTEGRITY_LEN + ATTR_HDR_LEN 1149 }; 1150 pj_stun_msgint_attr *attr; 1151 1152 if (len < ATTR_LEN) 1229 const pj_stun_msgint_attr *ca = (const pj_stun_msgint_attr*)a; 1230 1231 if (len < 24) 1153 1232 return PJ_ETOOSMALL; 1154 1233 1155 1234 /* Copy and convert attribute to network byte order */ 1156 pj_memcpy(buf, a, ATTR_LEN); 1157 attr = (pj_stun_msgint_attr*) buf; 1158 attr->hdr.type = pj_htons(attr->hdr.type); 1159 pj_assert(attr->hdr.length == STUN_MSG_INTEGRITY_LEN); 1160 attr->hdr.length = pj_htons(STUN_MSG_INTEGRITY_LEN); 1235 PUTVAL16H(buf, 0, ca->hdr.type); 1236 PUTVAL16H(buf, 2, ca->hdr.length); 1237 1238 pj_memcpy(buf+4, ca->hmac, 20); 1161 1239 1162 1240 /* Done */ 1163 *printed = ATTR_LEN;1241 *printed = 24; 1164 1242 1165 1243 return PJ_SUCCESS; … … 1198 1276 attr = PJ_POOL_ZALLOC_T(pool, pj_stun_errcode_attr); 1199 1277 INIT_ATTR(attr, PJ_STUN_ATTR_ERROR_CODE, 4+err_reason->slen); 1200 attr->err_class = (pj_uint8_t)(err_code / 100); 1201 attr->number = (pj_uint8_t) (err_code % 100); 1278 attr->err_code = err_code; 1202 1279 pj_strdup(pool, &attr->reason, err_reason); 1203 1280 … … 1233 1310 /* Create the attribute */ 1234 1311 attr = PJ_POOL_ZALLOC_T(pool, pj_stun_errcode_attr); 1235 1236 /* Copy the header */ 1237 pj_memcpy(attr, buf, ATTR_HDR_LEN + 4); 1238 1239 /* Convert to host byte order */ 1240 attr->hdr.type = pj_ntohs(attr->hdr.type); 1241 attr->hdr.length = pj_ntohs(attr->hdr.length); 1312 GETATTRHDR(buf, &attr->hdr); 1313 1314 attr->err_code = buf[6] * 100 + buf[7]; 1242 1315 1243 1316 /* Get pointer to the string in the message */ … … 1260 1333 const pj_stun_errcode_attr *ca = 1261 1334 (const pj_stun_errcode_attr*)a; 1262 pj_stun_errcode_attr *attr;1263 1335 1264 1336 if (len < ATTR_HDR_LEN + 4 + (unsigned)ca->reason.slen) … … 1266 1338 1267 1339 /* Copy and convert attribute to network byte order */ 1268 pj_memcpy(buf, ca, ATTR_HDR_LEN + 4); 1269 1270 /* Update length */ 1271 attr = (pj_stun_errcode_attr*) buf; 1272 attr->hdr.length = (pj_uint16_t)(4 + ca->reason.slen); 1273 1274 /* Convert fiends to network byte order */ 1275 attr->hdr.type = pj_htons(attr->hdr.type); 1276 attr->hdr.length = pj_htons(attr->hdr.length); 1340 PUTVAL16H(buf, 0, ca->hdr.type); 1341 PUTVAL16H(buf, 2, (pj_uint16_t)(4 + ca->reason.slen)); 1342 PUTVAL16H(buf, 4, 0); 1343 buf[6] = (pj_uint8_t)(ca->err_code / 100); 1344 buf[7] = (pj_uint8_t)(ca->err_code % 100); 1277 1345 1278 1346 /* Copy error string */ … … 1356 1424 1357 1425 attr = PJ_POOL_ZALLOC_T(pool, pj_stun_unknown_attr); 1358 pj_memcpy(attr, buf, ATTR_HDR_LEN); 1359 1360 attr->hdr.type = pj_ntohs(attr->hdr.type); 1361 attr->hdr.length = pj_ntohs(attr->hdr.length); 1362 1426 GETATTRHDR(buf, &attr->hdr); 1427 1363 1428 attr->attr_count = (attr->hdr.length >> 1); 1364 1429 if (attr->attr_count > PJ_STUN_MAX_ATTR) … … 1381 1446 { 1382 1447 const pj_stun_unknown_attr *ca = (const pj_stun_unknown_attr*) a; 1383 pj_stun_unknown_attr *attr;1384 1448 pj_uint16_t *dst_unk_attr; 1385 1449 unsigned i; … … 1389 1453 return PJ_ETOOSMALL; 1390 1454 1391 /* Copy to message */ 1392 pj_memcpy(buf, ca, ATTR_HDR_LEN); 1393 1394 /* Set the correct length */ 1395 attr = (pj_stun_unknown_attr *) buf; 1396 attr->hdr.length = (pj_uint16_t)(ca->attr_count << 1); 1397 1398 /* Convert to network byte order */ 1399 attr->hdr.type = pj_htons(attr->hdr.type); 1400 attr->hdr.length = pj_htons(attr->hdr.length); 1455 PUTVAL16H(buf, 0, ca->hdr.type); 1456 PUTVAL16H(buf, 2, (pj_uint16_t)(ca->attr_count << 1)); 1401 1457 1402 1458 /* Copy individual attribute */ 1403 1459 dst_unk_attr = (pj_uint16_t*)(buf + ATTR_HDR_LEN); 1404 1460 for (i=0; i < ca->attr_count; ++i, ++dst_unk_attr) { 1405 *dst_unk_attr = pj_htons( attr->attrs[i]);1461 *dst_unk_attr = pj_htons(ca->attrs[i]); 1406 1462 } 1407 1463 … … 1433 1489 1434 1490 attr = PJ_POOL_ZALLOC_T(pool, pj_stun_binary_attr); 1435 INIT_ATTR(attr, attr_type, sizeof(pj_stun_binary_attr));1491 INIT_ATTR(attr, attr_type, length); 1436 1492 1437 1493 if (data && length) { … … 1475 1531 /* Create the attribute */ 1476 1532 attr = PJ_POOL_ZALLOC_T(pool, pj_stun_binary_attr); 1477 1478 /* Copy the header */ 1479 pj_memcpy(attr, buf, ATTR_HDR_LEN); 1480 1481 /* Convert to host byte order */ 1482 attr->hdr.type = pj_ntohs(attr->hdr.type); 1483 attr->hdr.length = pj_ntohs(attr->hdr.length); 1533 GETATTRHDR(buf, &attr->hdr); 1484 1534 1485 1535 /* Copy the data to the attribute */ … … 1500 1550 { 1501 1551 const pj_stun_binary_attr *ca = (const pj_stun_binary_attr*)a; 1502 pj_stun_attr_hdr *attr;1503 1552 1504 1553 /* Calculated total attr_len (add padding if necessary) */ … … 1507 1556 return PJ_ETOOSMALL; 1508 1557 1509 /* Copy header */ 1510 pj_memcpy(buf, a, ATTR_HDR_LEN); 1511 1512 /* Set the correct length */ 1513 attr = (pj_stun_attr_hdr*)buf; 1514 attr->length = (pj_uint16_t) ca->length; 1515 1516 /* Convert to network byte order */ 1517 attr->type = pj_htons(attr->type); 1518 attr->length = pj_htons(attr->length); 1558 PUTVAL16H(buf, 0, ca->hdr.type); 1559 PUTVAL16H(buf, 2, (pj_uint16_t) ca->length); 1519 1560 1520 1561 /* Copy the data */ … … 1583 1624 1584 1625 1585 PJ_INLINE(pj_uint16_t) GET_VAL16(const pj_uint8_t *pdu, unsigned pos)1586 {1587 return (pj_uint16_t) ((pdu[pos] << 8) + pdu[pos+1]);1588 }1589 1590 PJ_INLINE(pj_uint32_t) GET_VAL32(const pj_uint8_t *pdu, unsigned pos)1591 {1592 return (pdu[pos+0] << 24) +1593 (pdu[pos+1] << 16) +1594 (pdu[pos+2] << 8) +1595 (pdu[pos+3]);1596 }1597 1598 1599 1626 /* 1600 1627 * Check that the PDU is potentially a valid STUN message. … … 1615 1642 1616 1643 /* Check the PDU length */ 1617 msg_len = GET _VAL16(pdu, 2);1644 msg_len = GETVAL16H(pdu, 2); 1618 1645 if ((msg_len + 20 > pdu_len) || 1619 1646 ((options & PJ_STUN_IS_DATAGRAM) && msg_len + 20 != pdu_len)) … … 1625 1652 * a STUN message. 1626 1653 */ 1627 if (GET _VAL32(pdu, 4) == PJ_STUN_MAGIC) {1654 if (GETVAL32H(pdu, 4) == PJ_STUN_MAGIC) { 1628 1655 1629 1656 /* Check if FINGERPRINT attribute is present */ 1630 if (GET _VAL16(pdu, msg_len + 20) == PJ_STUN_ATTR_FINGERPRINT) {1631 pj_uint16_t attr_len = GET _VAL16(pdu, msg_len + 22);1632 pj_uint32_t fingerprint = GET _VAL32(pdu, msg_len + 24);1657 if (GETVAL16H(pdu, msg_len + 20) == PJ_STUN_ATTR_FINGERPRINT) { 1658 pj_uint16_t attr_len = GETVAL16H(pdu, msg_len + 22); 1659 pj_uint32_t fingerprint = GETVAL32H(pdu, msg_len + 24); 1633 1660 pj_uint32_t crc; 1634 1661 -
pjproject/trunk/pjnath/src/pjnath/stun_msg_dump.c
r1080 r1114 141 141 len = pj_ansi_snprintf(p, end-p, 142 142 ", err_code=%d, reason=\"%.*s\"\n", 143 attr->err_c lass*100 + attr->number,143 attr->err_code, 144 144 (int)attr->reason.slen, 145 145 attr->reason.ptr); -
pjproject/trunk/pjnath/src/pjnath/stun_transaction.c
r1111 r1114 285 285 pj_stun_msg_find_attr(msg, PJ_STUN_ATTR_ERROR_CODE, 0); 286 286 287 if (err_attr && err_attr->err_c lass <= 2) {287 if (err_attr && err_attr->err_code <= 200) { 288 288 /* draft-ietf-behave-rfc3489bis-05.txt Section 8.3.2: 289 289 * Any response between 100 and 299 MUST result in the cessation … … 292 292 PJ_LOG(4,(tsx->obj_name, 293 293 "STUN rx_msg() error: received provisional %d code (%.*s)", 294 err_attr->err_c lass * 100 + err_attr->number,294 err_attr->err_code, 295 295 (int)err_attr->reason.slen, 296 296 err_attr->reason.ptr)); … … 301 301 status = PJ_SUCCESS; 302 302 } else { 303 status = PJ_STATUS_FROM_STUN_CODE(err_attr->err_class * 100 + 304 err_attr->number); 303 status = PJ_STATUS_FROM_STUN_CODE(err_attr->err_code); 305 304 } 306 305
Note: See TracChangeset
for help on using the changeset viewer.