Changeset 6071


Ignore:
Timestamp:
Sep 23, 2019 7:25:41 AM (5 years ago)
Author:
ming
Message:

Fixed #2229: Limitations in ICE data sending

Location:
pjproject/trunk
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjmedia/src/pjmedia/transport_ice.c

    r6009 r6071  
    292292                            PJMEDIA_TRANSPORT_SO_SNDBUF_SIZE; 
    293293    } 
     294    if (ice_st_cfg.send_buf_size == 0) 
     295        ice_st_cfg.send_buf_size = PJMEDIA_MAX_MTU; 
    294296 
    295297    /* Create ICE */ 
     
    18881890{ 
    18891891    struct transport_ice *tp_ice = (struct transport_ice*)tp; 
     1892    pj_status_t status; 
    18901893 
    18911894    /* Simulate packet lost on TX direction */ 
     
    18991902    } 
    19001903 
    1901     return pj_ice_strans_sendto(tp_ice->ice_st, 1,  
    1902                                 pkt, size, &tp_ice->remote_rtp, 
    1903                                 tp_ice->addr_len); 
     1904    status = pj_ice_strans_sendto2(tp_ice->ice_st, 1,  
     1905                                   pkt, size, &tp_ice->remote_rtp, 
     1906                                   tp_ice->addr_len); 
     1907    if (status == PJ_EPENDING) 
     1908        status = PJ_SUCCESS; 
     1909 
     1910    return status; 
    19041911} 
    19051912 
     
    19211928 
    19221929    if (tp_ice->comp_cnt > 1 || tp_ice->use_rtcp_mux) { 
     1930        pj_status_t status; 
    19231931        unsigned comp_id = (tp_ice->use_rtcp_mux? 1: 2); 
     1932 
    19241933        if (addr == NULL) { 
    19251934            addr = &tp_ice->remote_rtcp; 
    19261935            addr_len = pj_sockaddr_get_len(addr); 
    19271936        }          
    1928         return pj_ice_strans_sendto(tp_ice->ice_st, comp_id, pkt, size, 
    1929                                     addr, addr_len); 
     1937 
     1938        status = pj_ice_strans_sendto2(tp_ice->ice_st, comp_id, pkt, size, 
     1939                                       addr, addr_len); 
     1940        if (status == PJ_EPENDING) 
     1941            status = PJ_SUCCESS; 
     1942 
     1943        return status; 
    19301944    } else { 
    19311945        return PJ_SUCCESS; 
  • pjproject/trunk/pjnath/include/pjnath/ice_session.h

    r5339 r6071  
    935935 * @param data_len      Size of data or packet, in bytes. 
    936936 * 
    937  * @return              PJ_SUCCESS if data is sent successfully. 
     937 * @return              If the callback \a on_tx_pkt() is called, this 
     938 *                      will contain the return value of the callback. 
     939 *                      Otherwise, it will indicate failure with 
     940 *                      the appropriate error code. 
    938941 */ 
    939942PJ_DECL(pj_status_t) pj_ice_sess_send_data(pj_ice_sess *ice, 
  • pjproject/trunk/pjnath/include/pjnath/ice_strans.h

    r5562 r6071  
    9999 *    pair. The ICE stream transport may not be able to send data while  
    100100 *    negotiation is in progress.\n\n 
    101  *  - application sends data by using #pj_ice_strans_sendto(). Incoming 
     101 *  - application sends data by using #pj_ice_strans_sendto2(). Incoming 
    102102 *    data will be reported in \a on_rx_data() callback of the 
    103103 *    #pj_ice_strans_cb.\n\n 
     
    114114 */ 
    115115 
     116/* Deprecated API pj_ice_strans_sendto() due to its limitations. See 
     117 * below for more info and refer to 
     118 * https://trac.pjsip.org/repos/ticket/2229 for more details. 
     119 */ 
     120#ifndef DEPRECATED_FOR_TICKET_2229 
     121#  define DEPRECATED_FOR_TICKET_2229    0 
     122#endif 
     123 
    116124/** Forward declaration for ICE stream transport. */ 
    117125typedef struct pj_ice_strans pj_ice_strans; 
     
    160168                          const pj_sockaddr_t *src_addr, 
    161169                          unsigned src_addr_len); 
     170 
     171    /** 
     172     * This callback is optional and will be called to notify the status of 
     173     * async send operations. 
     174     * 
     175     * @param ice_st        The ICE stream transport. 
     176     * @param sent          If value is positive non-zero it indicates the 
     177     *                      number of data sent. When the value is negative, 
     178     *                      it contains the error code which can be retrieved 
     179     *                      by negating the value (i.e. status=-sent). 
     180     */ 
     181    void    (*on_data_sent)(pj_ice_strans *sock, 
     182                            pj_ssize_t sent); 
    162183 
    163184    /** 
     
    416437     */ 
    417438    pj_ice_strans_turn_cfg turn_tp[PJ_ICE_MAX_TURN]; 
     439 
     440    /** 
     441     * Number of send buffers used for pj_ice_strans_sendto2(). If the send 
     442     * buffers are full, pj_ice_strans_sendto()/sendto2() will return 
     443     * PJ_EBUSY. 
     444     * 
     445     * Set this to 0 to disable buffering (then application will have to 
     446     * maintain the buffer passed to pj_ice_strans_sendto()/sendto2() 
     447     * until it has been sent). 
     448     * 
     449     * Default: 4 
     450     */ 
     451    unsigned             num_send_buf; 
     452 
     453    /** 
     454     * Buffer size used for pj_ice_strans_sendto2(). 
     455     * 
     456     * Default: 0 (size determined by the size of the first packet sent). 
     457     */ 
     458    unsigned             send_buf_size; 
    418459 
    419460    /** 
     
    905946 
    906947 
     948#if !DEPRECATED_FOR_TICKET_2229 
    907949/** 
    908950 * Send outgoing packet using this transport.  
     
    917959 * address, as negotiated by ICE. 
    918960 * 
     961 * Limitations: 
     962 * 1. This function cannot inform the app whether the data has been sent, 
     963 *    or currently still pending. 
     964 * 2. In case that the data is still pending, the application has no way 
     965 *    of knowing the status of the send operation (whether it's a success 
     966 *    or failure). 
     967 * Due to these limitations, the API is deprecated and will be removed 
     968 * in the future. 
     969 * 
     970 * Note that application shouldn't mix using pj_ice_strans_sendto() and 
     971 * pj_ice_strans_sendto2() to avoid inconsistent calling of 
     972 * on_data_sent() callback. 
     973 * 
    919974 * @param ice_st        The ICE stream transport. 
    920975 * @param comp_id       Component ID. 
     
    924979 * @param dst_addr_len  Length of destination address. 
    925980 * 
    926  * @return              PJ_SUCCESS if data is sent successfully. 
     981 * @return              PJ_SUCCESS if data has been sent, or will be sent 
     982 *                      later. No callback will be called. 
    927983 */ 
    928984PJ_DECL(pj_status_t) pj_ice_strans_sendto(pj_ice_strans *ice_st, 
     
    932988                                          const pj_sockaddr_t *dst_addr, 
    933989                                          int dst_addr_len); 
     990#endif 
     991 
     992 
     993/** 
     994 * Send outgoing packet using this transport.  
     995 * Application can send data (normally RTP or RTCP packets) at any time 
     996 * by calling this function. This function takes a destination 
     997 * address as one of the arguments, and this destination address should 
     998 * be taken from the default transport address of the component (that is 
     999 * the address in SDP c= and m= lines, or in a=rtcp attribute).  
     1000 * If ICE negotiation is in progress, this function will send the data  
     1001 * to the destination address. Otherwise if ICE negotiation has completed 
     1002 * successfully, this function will send the data to the nominated remote  
     1003 * address, as negotiated by ICE. 
     1004 * 
     1005 * Note that application shouldn't mix using pj_ice_strans_sendto() and 
     1006 * pj_ice_strans_sendto2() to avoid inconsistent calling of 
     1007 * on_data_sent() callback. 
     1008 * 
     1009 * @param ice_st        The ICE stream transport. 
     1010 * @param comp_id       Component ID. 
     1011 * @param data          The data or packet to be sent. 
     1012 * @param data_len      Size of data or packet, in bytes. 
     1013 * @param dst_addr      The destination address. 
     1014 * @param dst_addr_len  Length of destination address. 
     1015 * 
     1016 * @return              PJ_SUCCESS if data has been sent, or 
     1017 *                      PJ_EPENDING if data cannot be sent immediately. In 
     1018 *                      this case the \a on_data_sent() callback will be 
     1019 *                      called when data is actually sent. Any other return 
     1020 *                      value indicates error condition. 
     1021 */ 
     1022PJ_DECL(pj_status_t) pj_ice_strans_sendto2(pj_ice_strans *ice_st, 
     1023                                           unsigned comp_id, 
     1024                                           const void *data, 
     1025                                           pj_size_t data_len, 
     1026                                           const pj_sockaddr_t *dst_addr, 
     1027                                           int dst_addr_len); 
    9341028 
    9351029 
  • pjproject/trunk/pjnath/include/pjnath/turn_session.h

    r6004 r6071  
    234234    /** 
    235235     * This callback will be called by the TURN session whenever it 
    236      * needs to send outgoing message. Since the TURN session doesn't 
    237      * have a socket on its own, this callback must be implemented. 
     236     * needs to send data or outgoing messages. Since the TURN session 
     237     * doesn't have a socket on its own, this callback must be implemented. 
     238     * 
     239     * If the callback \a on_stun_send_pkt() is implemented, outgoing 
     240     * messages will use that callback instead. 
    238241     * 
    239242     * @param sess      The TURN session. 
     
    251254                               const pj_sockaddr_t *dst_addr, 
    252255                               unsigned addr_len); 
     256 
     257    /** 
     258     * This callback will be called by the TURN session whenever it 
     259     * needs to send outgoing STUN requests/messages for TURN signalling 
     260     * purposes (data sending will not invoke this callback). If this 
     261     * callback is not implemented, the callback \a on_send_pkt() 
     262     * will be called instead. 
     263     * 
     264     * @param sess      The TURN session. 
     265     * @param pkt       The packet/data to be sent. 
     266     * @param pkt_len   Length of the packet/data. 
     267     * @param dst_addr  Destination address of the packet. 
     268     * @param addr_len  Length of the destination address. 
     269     * 
     270     * @return          The callback should return the status of the 
     271     *                  send operation.  
     272     */ 
     273    pj_status_t (*on_stun_send_pkt)(pj_turn_session *sess, 
     274                                    const pj_uint8_t *pkt, 
     275                                    unsigned pkt_len, 
     276                                    const pj_sockaddr_t *dst_addr, 
     277                                    unsigned addr_len); 
    253278 
    254279    /** 
     
    763788 * @param addr_len      Length of the address. 
    764789 * 
    765  * @return              PJ_SUCCESS if the operation has been successful, 
    766  *                      or the appropriate error code on failure. 
     790 * @return              If the callback \a on_send_pkt() is called, this 
     791 *                      will contain the return value of the callback. 
     792 *                      Otherwise, it will indicate failure with 
     793 *                      the appropriate error code. 
    767794 */ 
    768795PJ_DECL(pj_status_t) pj_turn_session_sendto(pj_turn_session *sess, 
  • pjproject/trunk/pjnath/include/pjnath/turn_sock.h

    r6004 r6071  
    8787                       const pj_sockaddr_t *peer_addr, 
    8888                       unsigned addr_len); 
     89 
     90    /** 
     91     * Notifification when asynchronous send operation has completed. 
     92     * 
     93     * @param turn_sock     The TURN transport. 
     94     * @param sent          If value is positive non-zero it indicates the 
     95     *                      number of data sent. When the value is negative, 
     96     *                      it contains the error code which can be retrieved 
     97     *                      by negating the value (i.e. status=-sent). 
     98     * 
     99     * @return              Application should normally return PJ_TRUE to let 
     100     *                      the TURN transport continue its operation. However 
     101     *                      it must return PJ_FALSE if it has destroyed the 
     102     *                      TURN transport in this callback. 
     103     */ 
     104    pj_bool_t (*on_data_sent)(pj_turn_sock *sock, 
     105                              pj_ssize_t sent); 
    89106 
    90107    /** 
     
    575592 * @param addr_len      Length of the address. 
    576593 * 
    577  * @return              PJ_SUCCESS if the operation has been successful, 
    578  *                      or the appropriate error code on failure. 
     594 * @return              PJ_SUCCESS if data has been sent immediately, or 
     595 *                      PJ_EPENDING if data cannot be sent immediately. In 
     596 *                      this case the \a on_data_sent() callback will be 
     597 *                      called when data is actually sent. Any other return 
     598 *                      value indicates error condition. 
    579599 */  
    580600PJ_DECL(pj_status_t) pj_turn_sock_sendto(pj_turn_sock *turn_sock, 
  • pjproject/trunk/pjnath/src/pjnath/ice_strans.c

    r6048 r6071  
    128128                            const pj_sockaddr_t *peer_addr, 
    129129                            unsigned addr_len); 
     130static pj_bool_t turn_on_data_sent(pj_turn_sock *turn_sock, 
     131                                   pj_ssize_t sent); 
    130132static void turn_on_state(pj_turn_sock *turn_sock, pj_turn_state_t old_state, 
    131133                          pj_turn_state_t new_state); 
     
    134136 
    135137/* Forward decls */ 
     138static pj_bool_t on_data_sent(pj_ice_strans *ice_st, pj_ssize_t sent); 
    136139static void ice_st_on_destroy(void *obj); 
    137140static void destroy_ice_st(pj_ice_strans *ice_st); 
     
    179182 
    180183 
     184/* Pending send buffer */ 
     185typedef struct pending_send 
     186{ 
     187    void               *buffer; 
     188    unsigned            comp_id; 
     189    pj_size_t           data_len; 
     190    pj_sockaddr         dst_addr; 
     191    int                 dst_addr_len; 
     192} pending_send; 
     193 
    181194/** 
    182195 * This structure represents the ICE stream transport. 
     
    185198{ 
    186199    char                    *obj_name;  /**< Log ID.                    */ 
     200    pj_pool_factory         *pf;        /**< Pool factory.              */ 
    187201    pj_pool_t               *pool;      /**< Pool used by this object.  */ 
    188202    void                    *user_data; /**< Application data.          */ 
     
    198212    pj_ice_strans_comp     **comp;      /**< Components array.          */ 
    199213 
     214    pj_pool_t               *buf_pool;  /**< Pool for buffers.          */ 
     215    unsigned                 num_buf;   /**< Number of buffers.         */ 
     216    unsigned                 buf_idx;   /**< Index of buffer.           */ 
     217    unsigned                 empty_idx; /**< Index of empty buffer.     */ 
     218    unsigned                 buf_size;  /**< Buffer size.               */ 
     219    pending_send            *send_buf;  /**< Send buffers.              */ 
     220    pj_bool_t                is_pending;/**< Any pending send?          */ 
     221 
    200222    pj_timer_entry           ka_timer;  /**< STUN keep-alive timer.     */ 
    201223 
    202224    pj_bool_t                destroy_req;/**< Destroy has been called?  */ 
    203225    pj_bool_t                cb_called; /**< Init error callback called?*/ 
     226    pj_bool_t                call_send_cb;/**< Need to call send cb?    */ 
    204227}; 
    205228 
     
    242265    pj_ice_strans_turn_cfg_default(&cfg->turn); 
    243266    pj_ice_sess_options_default(&cfg->opt); 
     267 
     268    cfg->num_send_buf = 4; 
    244269} 
    245270 
     
    368393    pj_bzero(&turn_sock_cb, sizeof(turn_sock_cb)); 
    369394    turn_sock_cb.on_rx_data = &turn_on_rx_data; 
     395    turn_sock_cb.on_data_sent = &turn_on_data_sent; 
    370396    turn_sock_cb.on_state = &turn_on_state; 
    371397 
     
    786812} 
    787813 
     814static pj_status_t alloc_send_buf(pj_ice_strans *ice_st, unsigned buf_size) 
     815{ 
     816    if (buf_size > ice_st->buf_size) { 
     817        unsigned i; 
     818         
     819        if (ice_st->is_pending) { 
     820            /* The current buffer is insufficient, but still currently used.*/ 
     821            return PJ_EBUSY; 
     822        } 
     823 
     824        pj_pool_safe_release(&ice_st->buf_pool); 
     825 
     826        ice_st->buf_pool = pj_pool_create(ice_st->pf, "ice_buf", 
     827                               (buf_size + sizeof(pending_send)) * 
     828                               ice_st->num_buf, 512, NULL); 
     829        if (!ice_st->buf_pool) 
     830            return PJ_ENOMEM; 
     831 
     832        ice_st->buf_size = buf_size; 
     833        ice_st->send_buf = pj_pool_calloc(ice_st->buf_pool, ice_st->num_buf, 
     834                                          sizeof(pending_send)); 
     835        for (i = 0; i < ice_st->num_buf; i++) { 
     836            ice_st->send_buf[i].buffer = pj_pool_alloc(ice_st->buf_pool, 
     837                                                       buf_size); 
     838        } 
     839        ice_st->buf_idx = ice_st->empty_idx = 0; 
     840    } 
     841     
     842    return PJ_SUCCESS; 
     843} 
    788844 
    789845/* 
     
    816872    ice_st = PJ_POOL_ZALLOC_T(pool, pj_ice_strans); 
    817873    ice_st->pool = pool; 
     874    ice_st->pf = cfg->stun_cfg.pf; 
    818875    ice_st->obj_name = pool->obj_name; 
    819876    ice_st->user_data = user_data; 
     
    827884    if (status != PJ_SUCCESS) { 
    828885        pj_pool_release(pool); 
     886        pj_log_pop_indent(); 
     887        return status; 
     888    } 
     889 
     890    /* Allocate send buffer */ 
     891    ice_st->num_buf = cfg->num_send_buf; 
     892    status = alloc_send_buf(ice_st, cfg->send_buf_size); 
     893    if (status != PJ_SUCCESS) { 
     894        destroy_ice_st(ice_st); 
    829895        pj_log_pop_indent(); 
    830896        return status; 
     
    902968 
    903969    /* Done */ 
    904     pj_pool_release(ice_st->pool); 
     970    pj_pool_safe_release(&ice_st->buf_pool); 
     971    pj_pool_safe_release(&ice_st->pool); 
    905972} 
    906973 
     
    14641531     
    14651532    /* Protect with group lock, since this may cause race condition with 
    1466      * pj_ice_strans_sendto(). 
     1533     * pj_ice_strans_sendto2(). 
    14671534     * See ticket #1877. 
    14681535     */ 
     
    14811548} 
    14821549 
     1550static pj_status_t use_buffer( pj_ice_strans *ice_st, 
     1551                               unsigned comp_id, 
     1552                               const void *data, 
     1553                               pj_size_t data_len, 
     1554                               const pj_sockaddr_t *dst_addr, 
     1555                               int dst_addr_len, 
     1556                               void **buffer ) 
     1557{ 
     1558    unsigned idx; 
     1559    pj_status_t status; 
     1560 
     1561    /* Allocate send buffer, if necessary. */ 
     1562    status = alloc_send_buf(ice_st, data_len); 
     1563    if (status != PJ_SUCCESS) 
     1564        return status; 
     1565     
     1566    if (ice_st->is_pending && ice_st->empty_idx == ice_st->buf_idx) { 
     1567        /* We don't use buffer or there's no more empty buffer. */ 
     1568        return PJ_EBUSY; 
     1569    } 
     1570 
     1571    idx = ice_st->empty_idx; 
     1572    ice_st->empty_idx = (ice_st->empty_idx + 1) % ice_st->num_buf; 
     1573    ice_st->send_buf[idx].comp_id = comp_id; 
     1574    ice_st->send_buf[idx].data_len = data_len; 
     1575    pj_assert(ice_st->buf_size >= data_len); 
     1576    pj_memcpy(ice_st->send_buf[idx].buffer, data, data_len); 
     1577    pj_sockaddr_cp(&ice_st->send_buf[idx].dst_addr, dst_addr); 
     1578    ice_st->send_buf[idx].dst_addr_len = dst_addr_len; 
     1579    *buffer = ice_st->send_buf[idx].buffer; 
     1580     
     1581    if (ice_st->is_pending) { 
     1582        /* We'll continue later since there's still a pending send. */ 
     1583        return PJ_EPENDING; 
     1584    } 
     1585     
     1586    ice_st->is_pending = PJ_TRUE; 
     1587    ice_st->buf_idx = idx; 
     1588 
     1589    return PJ_SUCCESS; 
     1590} 
     1591 
    14831592/* 
    14841593 * Application wants to send outgoing packet. 
    14851594 */ 
    1486 PJ_DEF(pj_status_t) pj_ice_strans_sendto( pj_ice_strans *ice_st, 
    1487                                           unsigned comp_id, 
    1488                                           const void *data, 
    1489                                           pj_size_t data_len, 
    1490                                           const pj_sockaddr_t *dst_addr, 
    1491                                           int dst_addr_len) 
     1595static pj_status_t send_data(pj_ice_strans *ice_st, 
     1596                             unsigned comp_id, 
     1597                             const void *data, 
     1598                             pj_size_t data_len, 
     1599                             const pj_sockaddr_t *dst_addr, 
     1600                             int dst_addr_len, 
     1601                             pj_bool_t use_buf, 
     1602                             pj_bool_t call_cb) 
    14921603{ 
    14931604    pj_ice_strans_comp *comp; 
    14941605    pj_ice_sess_cand *def_cand; 
     1606    void *buf = (void *)data; 
    14951607    pj_status_t status; 
    14961608 
     
    15011613 
    15021614    /* Check that default candidate for the component exists */ 
    1503     if (comp->default_cand >= comp->cand_cnt) 
    1504         return PJ_EINVALIDOP; 
     1615    if (comp->default_cand >= comp->cand_cnt) { 
     1616        status = PJ_EINVALIDOP; 
     1617        goto on_return; 
     1618    } 
    15051619 
    15061620    /* Protect with group lock, since this may cause race condition with 
     
    15091623     */ 
    15101624    pj_grp_lock_acquire(ice_st->grp_lock); 
     1625 
     1626    if (use_buf && ice_st->num_buf > 0) { 
     1627        status = use_buffer(ice_st, comp_id, data, data_len, dst_addr, 
     1628                            dst_addr_len, &buf); 
     1629 
     1630        if (status == PJ_EPENDING || status != PJ_SUCCESS) { 
     1631            pj_grp_lock_release(ice_st->grp_lock); 
     1632            return status; 
     1633        } 
     1634    } 
    15111635 
    15121636    /* If ICE is available, send data with ICE, otherwise send with the 
     
    15171641     */ 
    15181642    if (ice_st->ice && ice_st->state == PJ_ICE_STRANS_STATE_RUNNING) { 
    1519         status = pj_ice_sess_send_data(ice_st->ice, comp_id, data, data_len); 
     1643        status = pj_ice_sess_send_data(ice_st->ice, comp_id, buf, data_len); 
    15201644         
    15211645        pj_grp_lock_release(ice_st->grp_lock); 
    15221646         
    1523         return status; 
     1647        goto on_return; 
    15241648    }  
    1525      
     1649 
    15261650    pj_grp_lock_release(ice_st->grp_lock); 
    15271651 
     
    15421666            if (comp->turn[tp_idx].sock == NULL) { 
    15431667                /* TURN socket error */ 
    1544                 return PJ_EINVALIDOP; 
     1668                status = PJ_EINVALIDOP; 
     1669                goto on_return; 
    15451670            } 
    15461671 
     
    15561681 
    15571682            status = pj_turn_sock_sendto(comp->turn[tp_idx].sock, 
    1558                                          (const pj_uint8_t*)data, 
     1683                                         (const pj_uint8_t*)buf, 
    15591684                                         (unsigned)data_len, 
    15601685                                         dst_addr, dst_addr_len); 
    1561             return (status==PJ_SUCCESS||status==PJ_EPENDING) ? 
    1562                     PJ_SUCCESS : status; 
     1686            goto on_return; 
    15631687        } else { 
    15641688            const pj_sockaddr_t *dest_addr; 
     
    15731697                                                    dst_addr); 
    15741698                    if (status != PJ_SUCCESS) 
    1575                         return status; 
     1699                        goto on_return; 
    15761700 
    15771701                    pj_sockaddr_cp(&comp->dst_addr, dst_addr); 
     
    15861710            } 
    15871711 
    1588             status = pj_stun_sock_sendto(comp->stun[tp_idx].sock, NULL, data, 
     1712            status = pj_stun_sock_sendto(comp->stun[tp_idx].sock, NULL, buf, 
    15891713                                         (unsigned)data_len, 0, dest_addr, 
    15901714                                         dest_addr_len); 
    1591             return (status==PJ_SUCCESS||status==PJ_EPENDING) ? 
    1592                     PJ_SUCCESS : status; 
     1715            goto on_return; 
    15931716        } 
    15941717 
    15951718    } else 
    1596         return PJ_EINVALIDOP; 
    1597 } 
     1719        status = PJ_EINVALIDOP; 
     1720 
     1721on_return: 
     1722    /* We continue later in on_data_sent() callback. */ 
     1723    if (status == PJ_EPENDING) 
     1724        return status; 
     1725 
     1726    if (call_cb) { 
     1727        on_data_sent(ice_st, (status == PJ_SUCCESS? data_len: -status)); 
     1728    } else { 
     1729        pj_grp_lock_acquire(ice_st->grp_lock); 
     1730        if (ice_st->num_buf > 0) { 
     1731            ice_st->buf_idx = (ice_st->buf_idx + 1) % ice_st->num_buf; 
     1732            pj_assert (ice_st->buf_idx == ice_st->empty_idx); 
     1733        } 
     1734        ice_st->is_pending = PJ_FALSE; 
     1735        pj_grp_lock_release(ice_st->grp_lock); 
     1736    } 
     1737 
     1738    return status; 
     1739} 
     1740 
     1741 
     1742#if !DEPRECATED_FOR_TICKET_2229 
     1743/* 
     1744 * Application wants to send outgoing packet. 
     1745 */ 
     1746PJ_DEF(pj_status_t) pj_ice_strans_sendto( pj_ice_strans *ice_st, 
     1747                                          unsigned comp_id, 
     1748                                          const void *data, 
     1749                                          pj_size_t data_len, 
     1750                                          const pj_sockaddr_t *dst_addr, 
     1751                                          int dst_addr_len) 
     1752{ 
     1753    pj_status_t status; 
     1754 
     1755    PJ_LOG(1, (ice_st->obj_name, "pj_ice_strans_sendto() is deprecated. " 
     1756                                 "Application is recommended to use " 
     1757                                 "pj_ice_strans_sendto2() instead.")); 
     1758    status = send_data(ice_st, comp_id, data, data_len, dst_addr, 
     1759                       dst_addr_len, PJ_TRUE, PJ_FALSE); 
     1760    if (status == PJ_EPENDING) 
     1761        status = PJ_SUCCESS; 
     1762     
     1763    return status; 
     1764} 
     1765#endif 
     1766 
     1767 
     1768/* 
     1769 * Application wants to send outgoing packet. 
     1770 */ 
     1771PJ_DEF(pj_status_t) pj_ice_strans_sendto2(pj_ice_strans *ice_st, 
     1772                                          unsigned comp_id, 
     1773                                          const void *data, 
     1774                                          pj_size_t data_len, 
     1775                                          const pj_sockaddr_t *dst_addr, 
     1776                                          int dst_addr_len) 
     1777{ 
     1778    ice_st->call_send_cb = PJ_TRUE; 
     1779    return send_data(ice_st, comp_id, data, data_len, dst_addr, 
     1780                     dst_addr_len, PJ_TRUE, PJ_FALSE); 
     1781} 
     1782 
    15981783 
    15991784/* 
     
    17061891    pj_ice_strans_comp *comp; 
    17071892    pj_status_t status; 
     1893    void *buf = (void *)pkt; 
     1894    pj_bool_t use_buf = PJ_FALSE; 
    17081895#if defined(ENABLE_TRACE) && (ENABLE_TRACE != 0) 
    17091896    char daddr[PJ_INET6_ADDRSTRLEN]; 
     
    17131900 
    17141901    PJ_ASSERT_RETURN(comp_id && comp_id <= ice_st->comp_cnt, PJ_EINVAL); 
     1902 
     1903    pj_grp_lock_acquire(ice_st->grp_lock); 
     1904    if (ice_st->num_buf > 0 && 
     1905        ice_st->send_buf[ice_st->buf_idx].buffer != pkt) 
     1906    { 
     1907        use_buf = PJ_TRUE; 
     1908        status = use_buffer(ice_st, comp_id, pkt, size, dst_addr, 
     1909                            dst_addr_len, &buf); 
     1910        if (status == PJ_EPENDING || status != PJ_SUCCESS) { 
     1911            pj_grp_lock_release(ice_st->grp_lock); 
     1912            return status; 
     1913        } 
     1914    } 
     1915    pj_grp_lock_release(ice_st->grp_lock); 
    17151916 
    17161917    comp = ice_st->comp[comp_id-1]; 
     
    17261927        if (comp->turn[tp_idx].sock) { 
    17271928            status = pj_turn_sock_sendto(comp->turn[tp_idx].sock, 
    1728                                          (const pj_uint8_t*)pkt, 
     1929                                         (const pj_uint8_t*)buf, 
    17291930                                         (unsigned)size, 
    17301931                                         dst_addr, dst_addr_len); 
     
    17421943                status = pj_sockaddr_synthesize(pj_AF_INET6(), 
    17431944                                                &comp->synth_addr, dst_addr); 
    1744                 if (status != PJ_SUCCESS) 
    1745                     return status; 
     1945                if (status != PJ_SUCCESS) { 
     1946                    goto on_return; 
     1947                } 
    17461948             
    17471949                pj_sockaddr_cp(&comp->dst_addr, dst_addr); 
     
    17561958 
    17571959        status = pj_stun_sock_sendto(comp->stun[tp_idx].sock, NULL, 
    1758                                      pkt, (unsigned)size, 0, 
     1960                                     buf, (unsigned)size, 0, 
    17591961                                     dest_addr, dest_addr_len); 
    17601962    } else { 
     
    17631965    } 
    17641966 
    1765     return (status==PJ_SUCCESS||status==PJ_EPENDING) ? PJ_SUCCESS : status; 
     1967on_return: 
     1968    if (use_buf && status != PJ_EPENDING) { 
     1969        pj_grp_lock_acquire(ice_st->grp_lock); 
     1970        if (ice_st->num_buf > 0) { 
     1971            ice_st->buf_idx = (ice_st->buf_idx + 1) % ice_st->num_buf; 
     1972            pj_assert(ice_st->buf_idx == ice_st->empty_idx); 
     1973        } 
     1974        ice_st->is_pending = PJ_FALSE; 
     1975        pj_grp_lock_release(ice_st->grp_lock); 
     1976    } 
     1977 
     1978    return status; 
    17661979} 
    17671980 
     
    17841997                                 src_addr, src_addr_len); 
    17851998    } 
     1999} 
     2000 
     2001/* Notifification when asynchronous send operation via STUN/TURN 
     2002 * has completed. 
     2003 */ 
     2004static pj_bool_t on_data_sent(pj_ice_strans *ice_st, pj_ssize_t sent) 
     2005{ 
     2006    if (ice_st->destroy_req || !ice_st->is_pending) 
     2007        return PJ_TRUE; 
     2008 
     2009    if (ice_st->call_send_cb && ice_st->cb.on_data_sent) { 
     2010        (*ice_st->cb.on_data_sent)(ice_st, sent); 
     2011    } 
     2012 
     2013    pj_grp_lock_acquire(ice_st->grp_lock); 
     2014 
     2015    if (ice_st->num_buf > 0) 
     2016        ice_st->buf_idx = (ice_st->buf_idx + 1) % ice_st->num_buf; 
     2017     
     2018    if (ice_st->num_buf > 0 && ice_st->buf_idx != ice_st->empty_idx) { 
     2019        /* There's still more pending send. Send it one by one. */ 
     2020        pending_send *ps = &ice_st->send_buf[ice_st->buf_idx]; 
     2021 
     2022        pj_grp_lock_release(ice_st->grp_lock); 
     2023        send_data(ice_st, ps->comp_id, ps->buffer, ps->data_len, 
     2024                  &ps->dst_addr, ps->dst_addr_len, PJ_FALSE, PJ_TRUE); 
     2025    } else { 
     2026        ice_st->is_pending = PJ_FALSE; 
     2027        pj_grp_lock_release(ice_st->grp_lock); 
     2028    } 
     2029 
     2030    return PJ_TRUE; 
    17862031} 
    17872032 
     
    18452090                                   pj_ssize_t sent) 
    18462091{ 
    1847     PJ_UNUSED_ARG(stun_sock); 
     2092    sock_user_data *data; 
     2093 
    18482094    PJ_UNUSED_ARG(send_key); 
    1849     PJ_UNUSED_ARG(sent); 
    1850     return PJ_TRUE; 
     2095 
     2096    data = (sock_user_data *)pj_stun_sock_get_user_data(stun_sock); 
     2097    if (!data || !data->comp || !data->comp->ice_st) return PJ_TRUE; 
     2098 
     2099    return on_data_sent(data->comp->ice_st, sent); 
    18512100} 
    18522101 
     
    21062355} 
    21072356 
     2357/* Notifification when asynchronous send operation to the TURN socket 
     2358 * has completed. 
     2359 */ 
     2360static pj_bool_t turn_on_data_sent(pj_turn_sock *turn_sock, 
     2361                                   pj_ssize_t sent) 
     2362{ 
     2363    sock_user_data *data; 
     2364 
     2365    data = (sock_user_data *)pj_turn_sock_get_user_data(turn_sock); 
     2366    if (!data || !data->comp || !data->comp->ice_st) return PJ_TRUE; 
     2367 
     2368    return on_data_sent(data->comp->ice_st, sent); 
     2369} 
    21082370 
    21092371/* Callback when TURN client state has changed */ 
  • pjproject/trunk/pjnath/src/pjnath/stun_sock.c

    r6045 r6071  
    638638                                    pj_sockaddr_get_len(&stun_sock->srv_addr), 
    639639                                    tdata); 
    640     if (status != PJ_SUCCESS && status != PJ_EPENDING) 
     640    if (status != PJ_SUCCESS) 
    641641        goto on_error; 
    642642 
  • pjproject/trunk/pjnath/src/pjnath/stun_transaction.c

    r5133 r6071  
    259259    /* Send message */ 
    260260    status = tsx->cb.on_send_msg(tsx, tsx->last_pkt, tsx->last_pkt_size); 
     261    if (status == PJ_EPENDING || status == PJ_EBUSY) 
     262        status = PJ_SUCCESS; 
    261263 
    262264    if (status == PJNATH_ESTUNDESTROYED) { 
  • pjproject/trunk/pjnath/src/pjnath/turn_session.c

    r5987 r6071  
    13271327 
    13281328    sess = (pj_turn_session*) pj_stun_session_get_user_data(stun); 
    1329     return (*sess->cb.on_send_pkt)(sess, (const pj_uint8_t*)pkt,  
    1330                                    (unsigned)pkt_size,  
    1331                                    dst_addr, addr_len); 
     1329    if (*sess->cb.on_stun_send_pkt) { 
     1330        return (*sess->cb.on_stun_send_pkt)(sess, (const pj_uint8_t*)pkt, 
     1331                                            (unsigned)pkt_size, 
     1332                                            dst_addr, addr_len); 
     1333    } else { 
     1334        return (*sess->cb.on_send_pkt)(sess, (const pj_uint8_t*)pkt, 
     1335                                       (unsigned)pkt_size, 
     1336                                       dst_addr, addr_len); 
     1337    } 
    13321338} 
    13331339 
  • pjproject/trunk/pjnath/src/pjnath/turn_sock.c

    r6039 r6071  
    9494 
    9595    pj_ioqueue_op_key_t  send_key; 
     96    pj_ioqueue_op_key_t  int_send_key; 
     97    unsigned             pkt_len; 
     98    unsigned             body_len; 
    9699 
    97100    /* Data connection, when peer_conn_type==PJ_TURN_TP_TCP (RFC 6062) */ 
     
    109112                                    const pj_sockaddr_t *dst_addr, 
    110113                                    unsigned dst_addr_len); 
     114static pj_status_t turn_on_stun_send_pkt(pj_turn_session *sess, 
     115                                         const pj_uint8_t *pkt, 
     116                                         unsigned pkt_len, 
     117                                         const pj_sockaddr_t *dst_addr, 
     118                                         unsigned dst_addr_len); 
    111119static void turn_on_channel_bound(pj_turn_session *sess, 
    112120                                  const pj_sockaddr_t *peer_addr, 
     
    136144                              pj_status_t status, 
    137145                              pj_size_t *remainder); 
     146static pj_bool_t on_data_sent(pj_turn_sock *turn_sock, 
     147                              pj_ioqueue_op_key_t *send_key, 
     148                              pj_ssize_t sent); 
    138149static pj_bool_t on_connect_complete(pj_turn_sock *turn_sock, 
    139150                                     pj_status_t status); 
     
    149160                                    pj_status_t status, 
    150161                                    pj_size_t *remainder); 
     162static pj_bool_t on_data_sent_asock(pj_activesock_t *asock, 
     163                                     pj_ioqueue_op_key_t *send_key, 
     164                                     pj_ssize_t sent); 
    151165 
    152166/* 
     
    168182                                       pj_status_t status, 
    169183                                       pj_size_t *remainder); 
     184static pj_bool_t dataconn_on_data_sent(pj_activesock_t *asock, 
     185                                       pj_ioqueue_op_key_t *send_key, 
     186                                       pj_ssize_t sent); 
    170187static pj_bool_t dataconn_on_connect_complete(pj_activesock_t *asock, 
    171188                                              pj_status_t status); 
     
    328345    pj_bzero(&sess_cb, sizeof(sess_cb)); 
    329346    sess_cb.on_send_pkt = &turn_on_send_pkt; 
     347    sess_cb.on_stun_send_pkt = &turn_on_stun_send_pkt; 
    330348    sess_cb.on_channel_bound = &turn_on_channel_bound; 
    331349    sess_cb.on_rx_data = &turn_on_rx_data; 
     
    628646        return PJ_EINVALIDOP; 
    629647 
     648    /* TURN session may add some headers to the packet, so we need 
     649     * to store our actual data length to be sent here. 
     650     */ 
     651    turn_sock->body_len = pkt_len; 
    630652    return pj_turn_session_sendto(turn_sock->sess, pkt, pkt_len,  
    631653                                  addr, addr_len); 
     
    694716    /* Init send_key */ 
    695717    pj_ioqueue_op_key_init(&turn_sock->send_key, sizeof(turn_sock->send_key)); 
     718    pj_ioqueue_op_key_init(&turn_sock->int_send_key, 
     719                           sizeof(turn_sock->int_send_key)); 
    696720 
    697721    /* Send Allocate request */ 
     
    861885} 
    862886 
     887static pj_bool_t on_data_sent(pj_turn_sock *turn_sock, 
     888                              pj_ioqueue_op_key_t *send_key, 
     889                              pj_ssize_t sent) 
     890{ 
     891    unsigned header_len, sent_size; 
     892 
     893    /* Don't report to callback if this is internal message. */ 
     894    if (send_key == &turn_sock->int_send_key) { 
     895        return PJ_TRUE; 
     896    } 
     897 
     898    if (turn_sock->cb.on_data_sent) { 
     899        /* Remove the length of packet header from sent size. */ 
     900        header_len = turn_sock->pkt_len - turn_sock->body_len; 
     901        sent_size = (sent > header_len)? (sent - header_len) : 0; 
     902        (*turn_sock->cb.on_data_sent)(turn_sock, sent_size); 
     903    } 
     904 
     905    return PJ_TRUE; 
     906} 
     907 
     908 
     909static pj_bool_t on_data_sent_asock(pj_activesock_t *asock, 
     910                                     pj_ioqueue_op_key_t *send_key, 
     911                                     pj_ssize_t sent) 
     912{ 
     913    pj_turn_sock *turn_sock; 
     914 
     915    turn_sock = (pj_turn_sock*)pj_activesock_get_user_data(asock); 
     916 
     917    return on_data_sent(turn_sock, send_key, sent); 
     918} 
     919 
     920 
    863921#if PJ_HAS_SSL_SOCK 
    864922static pj_bool_t on_data_read_ssl_sock(pj_ssl_sock_t *ssl_sock, 
     
    897955    } 
    898956 
    899     return PJ_TRUE; 
     957    return on_data_sent(turn_sock, op_key, bytes_sent); 
    900958} 
    901959#endif 
    902960 
    903 /* 
    904  * Callback from TURN session to send outgoing packet. 
    905  */ 
    906 static pj_status_t turn_on_send_pkt(pj_turn_session *sess, 
    907                                     const pj_uint8_t *pkt, 
    908                                     unsigned pkt_len, 
    909                                     const pj_sockaddr_t *dst_addr, 
    910                                     unsigned dst_addr_len) 
     961 
     962static pj_status_t send_pkt(pj_turn_session *sess, 
     963                            pj_bool_t internal, 
     964                            const pj_uint8_t *pkt, 
     965                            unsigned pkt_len, 
     966                            const pj_sockaddr_t *dst_addr, 
     967                            unsigned dst_addr_len) 
    911968{ 
    912969    pj_turn_sock *turn_sock = (pj_turn_sock*)  
     
    914971    pj_ssize_t len = pkt_len; 
    915972    pj_status_t status = PJ_SUCCESS; 
     973    pj_ioqueue_key_t *send_key = &turn_sock->send_key; 
    916974 
    917975    if (turn_sock == NULL || turn_sock->is_destroying) { 
     
    922980    } 
    923981 
     982    if (internal) 
     983        send_key = &turn_sock->int_send_key; 
     984    turn_sock->pkt_len = pkt_len; 
     985 
    924986    if (turn_sock->conn_type == PJ_TURN_TP_UDP) { 
    925987        status = pj_activesock_sendto(turn_sock->active_sock, 
    926                                       &turn_sock->send_key, pkt, &len, 0, 
     988                                      send_key, pkt, &len, 0, 
    927989                                      dst_addr, dst_addr_len); 
    928990    } else if (turn_sock->alloc_param.peer_conn_type == PJ_TURN_TP_TCP) { 
     
    932994            /* Destination address is TURN server */ 
    933995            status = pj_activesock_send(turn_sock->active_sock, 
    934                                         &turn_sock->send_key, pkt, &len, 0); 
     996                                        send_key, pkt, &len, 0); 
    935997        } else { 
    936998            /* Destination address is peer, lookup data connection */ 
     
    9521014    } else  if (turn_sock->conn_type == PJ_TURN_TP_TCP) { 
    9531015        status = pj_activesock_send(turn_sock->active_sock, 
    954                                     &turn_sock->send_key, pkt, &len, 0); 
     1016                                    send_key, pkt, &len, 0); 
    9551017    } 
    9561018#if PJ_HAS_SSL_SOCK 
    9571019    else if (turn_sock->conn_type == PJ_TURN_TP_TLS) { 
    9581020        status = pj_ssl_sock_send(turn_sock->ssl_sock, 
    959                                   &turn_sock->send_key, pkt, &len, 0); 
     1021                                  send_key, pkt, &len, 0); 
    9601022    } 
    9611023#endif 
     
    9691031 
    9701032    return status; 
     1033} 
     1034 
     1035 
     1036/* 
     1037 * Callback from TURN session to send outgoing packet. 
     1038 */ 
     1039static pj_status_t turn_on_send_pkt(pj_turn_session *sess, 
     1040                                    const pj_uint8_t *pkt, 
     1041                                    unsigned pkt_len, 
     1042                                    const pj_sockaddr_t *dst_addr, 
     1043                                    unsigned dst_addr_len) 
     1044{ 
     1045    return send_pkt(sess, PJ_FALSE, pkt, pkt_len, 
     1046                    dst_addr, dst_addr_len); 
     1047} 
     1048 
     1049static pj_status_t turn_on_stun_send_pkt(pj_turn_session *sess, 
     1050                                         const pj_uint8_t *pkt, 
     1051                                         unsigned pkt_len, 
     1052                                         const pj_sockaddr_t *dst_addr, 
     1053                                         unsigned dst_addr_len) 
     1054{ 
     1055    return send_pkt(sess, PJ_TRUE, pkt, pkt_len, 
     1056                    dst_addr, dst_addr_len); 
    9711057} 
    9721058 
     
    11701256            pj_bzero(&asock_cb, sizeof(asock_cb)); 
    11711257            asock_cb.on_data_read = &on_data_read_asock; 
     1258            asock_cb.on_data_sent = &on_data_sent_asock; 
    11721259            asock_cb.on_connect_complete = &on_connect_complete_asock; 
    11731260            status = pj_activesock_create(turn_sock->pool, sock, 
     
    13991486} 
    14001487 
     1488static pj_bool_t dataconn_on_data_sent(pj_activesock_t *asock, 
     1489                                       pj_ioqueue_op_key_t *send_key, 
     1490                                       pj_ssize_t sent) 
     1491{ 
     1492    tcp_data_conn_t *conn = (tcp_data_conn_t*) 
     1493                            pj_activesock_get_user_data(asock); 
     1494    pj_turn_sock *turn_sock = conn->turn_sock; 
     1495 
     1496    return on_data_sent(turn_sock, send_key, sent); 
     1497} 
     1498 
    14011499static pj_bool_t dataconn_on_connect_complete(pj_activesock_t *asock, 
    14021500                                              pj_status_t status) 
     
    15771675    pj_bzero(&asock_cb, sizeof(asock_cb)); 
    15781676    asock_cb.on_data_read = &dataconn_on_data_read; 
     1677    asock_cb.on_data_sent = &dataconn_on_data_sent; 
    15791678    asock_cb.on_connect_complete = &dataconn_on_connect_complete; 
    15801679    status = pj_activesock_create(pool, sock, 
  • pjproject/trunk/pjnath/src/pjturn-client/client_main.c

    r3553 r6071  
    479479                                        &peer->mapped_addr,  
    480480                                        pj_sockaddr_get_len(&peer->mapped_addr)); 
    481             if (status != PJ_SUCCESS) 
     481            if (status != PJ_SUCCESS && status != PJ_EPENDING) 
    482482                my_perror("turn_udp_sendto() failed", status); 
    483483            break; 
  • pjproject/trunk/pjsip-apps/src/samples/footprint.c

    r6035 r6071  
    223223    pj_ice_strans_start_ice(NULL, NULL, NULL, 0, NULL); 
    224224    pj_ice_strans_stop_ice(NULL); 
    225     pj_ice_strans_sendto(NULL, 0, NULL, 0, NULL, 0); 
     225    pj_ice_strans_sendto2(NULL, 0, NULL, 0, NULL, 0); 
    226226#endif 
    227227 
  • pjproject/trunk/pjsip-apps/src/samples/icedemo.c

    r4624 r6071  
    994994    } 
    995995 
    996     status = pj_ice_strans_sendto(icedemo.icest, comp_id, data, strlen(data), 
    997                                   &icedemo.rem.def_addr[comp_id-1], 
    998                                   pj_sockaddr_get_len(&icedemo.rem.def_addr[comp_id-1])); 
    999     if (status != PJ_SUCCESS) 
     996    status = pj_ice_strans_sendto2(icedemo.icest, comp_id, data, strlen(data), 
     997                                   &icedemo.rem.def_addr[comp_id-1], 
     998                                   pj_sockaddr_get_len(&icedemo.rem.def_addr[comp_id-1])); 
     999    if (status != PJ_SUCCESS && status != PJ_EPENDING) 
    10001000        icedemo_perror("Error sending data", status); 
    10011001    else 
    1002         PJ_LOG(3,(THIS_FILE, "Data sent")); 
     1002        PJ_LOG(3,(THIS_FILE, "Data sent/will be sent")); 
    10031003} 
    10041004 
Note: See TracChangeset for help on using the changeset viewer.