Ignore:
Timestamp:
Dec 8, 2009 1:11:25 PM (13 years ago)
Author:
bennylp
Message:

Fixed ticket #999:

Several bug fixes to the TURN client library and icedemo sample application:

  1. ICE stream transport reports ICE initialization/candidate gathering stage as successful even when TURN client TCP connection has failed.
  2. Bad ChannelData? framing when TCP is used. PJNATH did not properly add padding to the TURN ChannelData? packet if TCP is used and the data is not aligned to four bytes boundary. Similarly incoming ChannelData? with padding (over TCP) may not be handled correctly.
  3. Incoming data over TCP may be delayed. PJNATH only processed one frame (be it request, indication, or ChannelData?) on an incoming stream, so if the stream contains more than one frames, the processing of subsequent frames will be delayed until more stream is received on the TCP transport.
  4. The icedemo sample application overwrites the incoming packet buffer with NULL character ('\0') before printing the message to console. If there is another packet after current packet (as often happens when TCP is used), the subsequent packet will get corrupted.

The combinations of bugs above may cause PJNATH to return "Invalid STUN message length (PJNATH_EINSTUNMSGLEN)" error when processing incoming TURN ChannelData? message over TCP.

And a small enhancement:

  1. Add logging to file option to icedemo sample.

Thanks Sarun Nandakumar for the report.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjnath/src/pjnath/turn_session.c

    r2774 r3028  
    462462 * Forcefully destroy the TURN session. 
    463463 */ 
    464 PJ_DEF(pj_status_t) pj_turn_session_destroy( pj_turn_session *sess) 
     464PJ_DEF(pj_status_t) pj_turn_session_destroy( pj_turn_session *sess, 
     465                                             pj_status_t last_err) 
    465466{ 
    466467    PJ_ASSERT_RETURN(sess, PJ_EINVAL); 
    467468 
     469    if (last_err != PJ_SUCCESS && sess->last_status == PJ_SUCCESS) 
     470        sess->last_status = last_err; 
    468471    set_state(sess, PJ_TURN_STATE_DEALLOCATED); 
    469472    sess_shutdown(sess, PJ_SUCCESS); 
     
    960963                           PJ_FALSE, PJ_FALSE); 
    961964    if (ch && ch->num != PJ_TURN_INVALID_CHANNEL && ch->bound) { 
     965        unsigned total_len; 
     966 
    962967        /* Peer is assigned a channel number, we can use ChannelData */ 
    963968        pj_turn_channel_data *cd = (pj_turn_channel_data*)sess->tx_pkt; 
     
    965970        pj_assert(sizeof(*cd)==4); 
    966971 
    967         if (pkt_len > sizeof(sess->tx_pkt)-sizeof(*cd)) { 
     972        /* Calculate total length, including paddings */ 
     973        total_len = (pkt_len + sizeof(*cd) + 3) & (~3); 
     974        if (total_len > sizeof(sess->tx_pkt)) { 
    968975            status = PJ_ETOOBIG; 
    969976            goto on_return; 
     
    976983        pj_assert(sess->srv_addr != NULL); 
    977984 
    978         status = sess->cb.on_send_pkt(sess, sess->tx_pkt, pkt_len+sizeof(*cd), 
     985        status = sess->cb.on_send_pkt(sess, sess->tx_pkt, total_len, 
    979986                                      sess->srv_addr, 
    980987                                      pj_sockaddr_get_len(sess->srv_addr)); 
     
    11571164        } else { 
    11581165            if (parsed_len) { 
    1159                 *parsed_len = cd.length + sizeof(cd); 
     1166                /* Apply padding too */ 
     1167                *parsed_len = ((cd.length + 3) & (~3)) + sizeof(cd); 
    11601168            } 
    11611169        } 
Note: See TracChangeset for help on using the changeset viewer.