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/pjsip-apps/src/samples/icedemo.c

    r2724 r3028  
    4848        pj_str_t    turn_password; 
    4949        pj_bool_t   turn_fingerprint; 
     50        const char *log_file; 
    5051    } opt; 
    5152 
     
    5758    pj_ice_strans_cfg    ice_cfg; 
    5859    pj_ice_strans       *icest; 
     60    FILE                *log_fhnd; 
    5961 
    6062    /* Variables to store parsed remote ICE info */ 
     
    110112 
    111113    pj_shutdown(); 
     114 
     115    if (icedemo.log_fhnd) { 
     116        fclose(icedemo.log_fhnd); 
     117        icedemo.log_fhnd = NULL; 
     118    } 
     119 
    112120    exit(status != PJ_SUCCESS); 
    113121} 
     
    217225    PJ_UNUSED_ARG(pkt); 
    218226 
    219     ((char*)pkt)[size] = '\0'; 
    220  
    221     PJ_LOG(3,(THIS_FILE, "Component %d: received %d bytes data from %s: \"%s\"", 
     227    // Don't do this! It will ruin the packet buffer in case TCP is used! 
     228    //((char*)pkt)[size] = '\0'; 
     229 
     230    PJ_LOG(3,(THIS_FILE, "Component %d: received %d bytes data from %s: \"%.*s\"", 
    222231              comp_id, size, 
    223232              pj_sockaddr_print(src_addr, ipstr, sizeof(ipstr), 3), 
     233              (unsigned)size, 
    224234              (char*)pkt)); 
    225235} 
     
    236246        (op==PJ_ICE_STRANS_OP_INIT? "initialization" : 
    237247            (op==PJ_ICE_STRANS_OP_NEGOTIATION ? "negotiation" : "unknown_op")); 
    238  
    239     PJ_UNUSED_ARG(ice_st); 
    240248 
    241249    if (status == PJ_SUCCESS) { 
     
    246254        pj_strerror(status, errmsg, sizeof(errmsg)); 
    247255        PJ_LOG(1,(THIS_FILE, "ICE %s failed: %s", opname, errmsg)); 
    248     } 
    249 } 
    250  
     256        pj_ice_strans_destroy(ice_st); 
     257        icedemo.icest = NULL; 
     258    } 
     259} 
     260 
     261/* log callback to write to file */ 
     262static void log_func(int level, const char *data, int len) 
     263{ 
     264    if (icedemo.log_fhnd) 
     265        fwrite(data, len, 1, icedemo.log_fhnd); 
     266    pj_log_write(level, data, len); 
     267} 
    251268 
    252269/* 
     
    258275{ 
    259276    pj_status_t status; 
     277 
     278    if (icedemo.opt.log_file) { 
     279        icedemo.log_fhnd = fopen(icedemo.opt.log_file, "a"); 
     280        pj_log_set_log_func(&log_func); 
     281    } 
    260282 
    261283    /* Initialize the libraries before anything else */ 
     
    11481170    puts(" --max-host, -H N          Set max number of host candidates to N"); 
    11491171    puts(" --regular, -R             Use regular nomination (default aggressive)"); 
     1172    puts(" --log-file, -L FILE       Save output to log FILE"); 
    11501173    puts(" --help, -h                Display this screen."); 
    11511174    puts(""); 
     
    11831206        { "turn-password",      1, 0, 'p'}, 
    11841207        { "turn-fingerprint",   0, 0, 'F'}, 
    1185         { "regular",            0, 0, 'R'} 
     1208        { "regular",            0, 0, 'R'}, 
     1209        { "log-file",           1, 0, 'L'}, 
    11861210    }; 
    11871211    int c, opt_id; 
     
    11911215    icedemo.opt.max_host = -1; 
    11921216 
    1193     while((c=pj_getopt_long(argc,argv, "c:n:s:t:u:p:H:hTFR", long_options, &opt_id))!=-1) { 
     1217    while((c=pj_getopt_long(argc,argv, "c:n:s:t:u:p:H:L:hTFR", long_options, &opt_id))!=-1) { 
    11941218        switch (c) { 
    11951219        case 'c': 
     
    12301254            icedemo.opt.regular = PJ_TRUE; 
    12311255            break; 
     1256        case 'L': 
     1257            icedemo.opt.log_file = pj_optarg; 
     1258            break; 
    12321259        default: 
    12331260            printf("Argument \"%s\" is not valid. Use -h to see help", 
Note: See TracChangeset for help on using the changeset viewer.