Changeset 1926 for pjproject


Ignore:
Timestamp:
Apr 14, 2008 1:48:39 AM (17 years ago)
Author:
bennylp
Message:

More ticket #485: huge changeset to integrate TURN with ICE and PJSUA-LIB/pjsua. Still experimental

Location:
pjproject/branches/projects/ice-turn07
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/ice-turn07/pjlib/include/pj/sock.h

    r1613 r1926  
    777777 * @param dst       Destination socket address. 
    778778 * @param src       Source socket address. 
     779 * 
     780 * @see @pj_sockaddr_cp() 
    779781 */ 
    780782PJ_DECL(void) pj_sockaddr_copy_addr(pj_sockaddr *dst, 
    781783                                    const pj_sockaddr *src); 
     784/** 
     785 * Copy socket address. This will copy the whole structure depending 
     786 * on the address family of the source socket address. 
     787 * 
     788 * @param dst       Destination socket address. 
     789 * @param src       Source socket address. 
     790 * 
     791 * @see @pj_sockaddr_copy_addr() 
     792 */ 
     793PJ_DECL(void) pj_sockaddr_cp(pj_sockaddr_t *dst, const pj_sockaddr_t *src); 
     794 
    782795/** 
    783796 * Get the IP address of an IPv4 socket address. 
  • pjproject/branches/projects/ice-turn07/pjlib/src/pj/sock_common.c

    r1647 r1926  
    391391 
    392392/* 
     393 * Copy socket address. 
     394 */ 
     395PJ_DEF(void) pj_sockaddr_cp(pj_sockaddr_t *dst, const pj_sockaddr_t *src) 
     396{ 
     397    pj_memcpy(dst, src, pj_sockaddr_get_len(src)); 
     398} 
     399 
     400/* 
    393401 * Set port number of pj_sockaddr_in 
    394402 */ 
  • pjproject/branches/projects/ice-turn07/pjmedia/include/pjmedia/transport_ice.h

    r1735 r1926  
    6363 *                      for logging purposes. 
    6464 * @param comp_cnt      Number of components to be created. 
    65  * @param stun_cfg      Pointer to STUN configuration settings. 
     65 * @param cfg           Pointer to configuration settings. 
    6666 * @param cb            Optional callbacks. 
    6767 * @param p_tp          Pointer to receive the media transport instance. 
     
    7272                                        const char *name, 
    7373                                        unsigned comp_cnt, 
    74                                         pj_stun_config *stun_cfg, 
     74                                        const pj_ice_strans_cfg *cfg, 
    7575                                        const pjmedia_ice_cb *cb, 
    7676                                        pjmedia_transport **p_tp); 
     
    105105 *                        no other host candidates will be added for this 
    106106 *                        socket. 
    107  * @param stun_srv      Address of the STUN server, or NULL if STUN server 
    108  *                      reflexive mapping is not to be used. 
    109  * @param turn_srv      Address of the TURN server, or NULL if TURN relay 
    110  *                      is not to be used. 
    111107 * 
    112108 * @return              PJ_SUCCESS when the initialization process has started 
     
    115111PJ_DECL(pj_status_t) pjmedia_ice_start_init(pjmedia_transport *tp, 
    116112                                            unsigned options, 
    117                                             const pj_sockaddr_in *start_addr, 
    118                                             const pj_sockaddr_in *stun_srv, 
    119                                             const pj_sockaddr_in *turn_srv); 
     113                                            const pj_sockaddr_in *start_addr); 
    120114 
    121115/** 
  • pjproject/branches/projects/ice-turn07/pjmedia/src/pjmedia/transport_ice.c

    r1873 r1926  
    129129                                       const char *name, 
    130130                                       unsigned comp_cnt, 
    131                                        pj_stun_config *stun_cfg, 
     131                                       const pj_ice_strans_cfg *cfg, 
    132132                                       const pjmedia_ice_cb *cb, 
    133133                                       pjmedia_transport **p_tp) 
     
    146146 
    147147    /* Create ICE */ 
    148     status = pj_ice_strans_create(stun_cfg, name, comp_cnt, NULL,  
    149                               &ice_st_cb, &ice_st); 
     148    status = pj_ice_strans_create(cfg, name, comp_cnt, NULL,  
     149                                  &ice_st_cb, &ice_st); 
    150150    if (status != PJ_SUCCESS) 
    151151        return status; 
     
    177177PJ_DEF(pj_status_t) pjmedia_ice_start_init( pjmedia_transport *tp, 
    178178                                            unsigned options, 
    179                                             const pj_sockaddr_in *start_addr, 
    180                                             const pj_sockaddr_in *stun_srv, 
    181                                             const pj_sockaddr_in *turn_srv) 
     179                                            const pj_sockaddr_in *start_addr) 
    182180{ 
    183181    struct transport_ice *tp_ice = (struct transport_ice*)tp; 
    184182    pj_status_t status; 
    185  
    186     status = pj_ice_strans_set_stun_srv(tp_ice->ice_st, stun_srv, turn_srv); 
    187     if (status != PJ_SUCCESS) 
    188         return status; 
    189183 
    190184    status = pj_ice_strans_create_comp(tp_ice->ice_st, 1, options, start_addr); 
     
    350344            PJ_TODO(RELATED_ADDR_FOR_RELAYED_ADDR); 
    351345            len = pj_ansi_snprintf(buffer+len, MAXLEN-len, 
    352                              "srflx raddr %s rport %d", 
     346                             "relay raddr %s rport %d", 
    353347                             pj_inet_ntoa(cand->base_addr.ipv4.sin_addr), 
    354348                             (int)pj_ntohs(cand->base_addr.ipv4.sin_port)); 
  • pjproject/branches/projects/ice-turn07/pjnath/include/pjnath/ice_session.h

    r1654 r1926  
    431431     * @param ice           The ICE session. 
    432432     * @param comp_id       ICE component ID. 
     433     * @param cand_id       ICE candidate ID. 
    433434     * @param pkt           The STUN packet. 
    434435     * @param size          The size of the packet. 
     
    437438     */ 
    438439    pj_status_t (*on_tx_pkt)(pj_ice_sess *ice, unsigned comp_id,  
     440                             unsigned cand_id, 
    439441                             const void *pkt, pj_size_t size, 
    440442                             const pj_sockaddr_t *dst_addr, 
     
    798800 * @param ice           The ICE session. 
    799801 * @param comp_id       Component ID. 
     802 * @param cand_id       The candidate ID where this packet was received 
     803 *                      from. This parameter will be returned back to 
     804 *                      application in \a on_tx_pkt() callback, and 
     805 *                      application may use it to determine whether to 
     806 *                      send outgoing packet using local socket or with 
     807 *                      the TURN relay. The ICE session will not use 
     808 *                      this information to determine the local candidate 
     809 *                      for this packet. 
    800810 * @param pkt           Incoming packet. 
    801811 * @param pkt_size      Size of incoming packet. 
     
    807817PJ_DECL(pj_status_t) pj_ice_sess_on_rx_pkt(pj_ice_sess *ice, 
    808818                                           unsigned comp_id, 
     819                                           unsigned cand_id, 
    809820                                           void *pkt, 
    810821                                           pj_size_t pkt_size, 
  • pjproject/branches/projects/ice-turn07/pjnath/include/pjnath/ice_strans.h

    r1487 r1926  
    2626 */ 
    2727#include <pjnath/ice_session.h> 
     28#include <pjnath/turn_sock.h> 
    2829#include <pjlib-util/resolver.h> 
    2930#include <pj/ioqueue.h> 
     
    9293 *        has completed, either successfully or with failure. 
    9394 * 
    94  * After the ICE stream transport is created, application may set up the 
    95  * STUN servers to be used to obtain STUN server reflexive and relayed 
    96  * candidate, by calling #pj_ice_strans_set_stun_domain() or  
    97  * #pj_ice_strans_set_stun_srv(). 
    98  * 
    9995 * Application then creates each component by calling  
    10096 * #pj_ice_strans_create_comp(); this would create an actual socket 
     
    336332    pj_uint8_t           ka_tsx_id[12]; /**< ID for keep STUN alives    */ 
    337333 
     334    pj_turn_sock        *turn_relay;    /**< TURN relay object.         */ 
     335 
    338336    pj_sockaddr          local_addr;    /**< Local/base address.        */ 
    339337 
     
    356354 
    357355/** 
     356 * This structure describes ICE stream transport configuration. 
     357 */ 
     358typedef struct pj_ice_strans_cfg 
     359{ 
     360    /** 
     361     * STUN config. This setting is mandatory. 
     362     */ 
     363    pj_stun_config      stun_cfg; 
     364 
     365    /** 
     366     * STUN server address, if STUN is enabled. 
     367     * 
     368     * Default is to have no TURN server. 
     369     */ 
     370    pj_sockaddr         stun_srv; 
     371 
     372    /** 
     373     * TURN server address, if TURN is enabled. 
     374     * 
     375     * Default is to have no TURN server. 
     376     */ 
     377    pj_sockaddr         turn_srv; 
     378 
     379    /** 
     380     * Type of connection to the TURN server. 
     381     * 
     382     * Default is PJ_TURN_TP_UDP. 
     383     */ 
     384    pj_turn_tp_type     turn_conn_type; 
     385 
     386    /** 
     387     * Credential to be used for the TURN session. 
     388     * 
     389     * Default is to have no credential. 
     390     */ 
     391    pj_stun_auth_cred   turn_cred; 
     392 
     393    /** 
     394     * Optional TURN Allocate parameter. 
     395     * 
     396     * Default is all empty. 
     397     */ 
     398    pj_turn_alloc_param turn_alloc_param; 
     399 
     400} pj_ice_strans_cfg; 
     401 
     402 
     403/** 
    358404 * This structure represents the ICE stream transport. 
    359405 */ 
     
    364410    pj_pool_t               *pool;      /**< Pool used by this object.  */ 
    365411    void                    *user_data; /**< Application data.          */ 
    366     pj_stun_config           stun_cfg;  /**< STUN settings.             */ 
     412    pj_ice_strans_cfg        cfg;       /**< Configuration.             */ 
    367413    pj_ice_strans_cb         cb;        /**< Application callback.      */ 
    368414 
     
    371417    unsigned                 comp_cnt;  /**< Number of components.      */ 
    372418    pj_ice_strans_comp     **comp;      /**< Components array.          */ 
    373  
    374     pj_dns_resolver         *resolver;  /**< The resolver instance.     */ 
    375     pj_bool_t                has_rjob;  /**< Has pending resolve?       */ 
    376     pj_sockaddr_in           stun_srv;  /**< STUN server address.       */ 
    377     pj_sockaddr_in           turn_srv;  /**< TURN server address.       */ 
    378419 
    379420    pj_timer_entry           ka_timer;  /**< STUN keep-alive timer.     */ 
     
    388429 * function. 
    389430 * 
    390  * @param stun_cfg      The STUN settings. 
     431 * @param cfg           Configuration. 
    391432 * @param name          Optional name for logging identification. 
    392433 * @param comp_cnt      Number of components. 
     
    400441 *                      successfully. 
    401442 */ 
    402 PJ_DECL(pj_status_t) pj_ice_strans_create(pj_stun_config *stun_cfg, 
     443PJ_DECL(pj_status_t) pj_ice_strans_create(const pj_ice_strans_cfg *cfg, 
    403444                                          const char *name, 
    404445                                          unsigned comp_cnt, 
     
    417458 */ 
    418459PJ_DECL(pj_status_t) pj_ice_strans_destroy(pj_ice_strans *ice_st); 
    419  
    420  
    421 /** 
    422  * Set the domain to be used when resolving the STUN servers. If application 
    423  * wants to utillize STUN, then STUN server must be specified, either by 
    424  * calling this function or by calling #pj_ice_strans_set_stun_srv(). 
    425  * 
    426  * If application calls this function, then the STUN/TURN servers will 
    427  * be resolved by querying DNS SRV records for the specified domain. 
    428  * 
    429  * @param ice_st        The ICE stream transport. 
    430  * @param resolver      The resolver instance that will be used to 
    431  *                      resolve the STUN/TURN servers. 
    432  * @param domain        The target domain. 
    433  * 
    434  * @return              PJ_SUCCESS if DNS SRV resolution job can be 
    435  *                      started. The resolution process itself will 
    436  *                      complete asynchronously. 
    437  */ 
    438 PJ_DECL(pj_status_t) pj_ice_strans_set_stun_domain(pj_ice_strans *ice_st, 
    439                                                    pj_dns_resolver *resolver, 
    440                                                    const pj_str_t *domain); 
    441  
    442 /** 
    443  * Set the STUN and TURN server addresses. If application 
    444  * wants to utillize STUN, then STUN server must be specified, either by 
    445  * calling this function or by calling #pj_ice_strans_set_stun_domain(). 
    446  * 
    447  * With this function, the STUN and TURN server addresses will be  
    448  * assigned immediately, that is no DNS resolution will need to be  
    449  * performed. 
    450  * 
    451  * @param ice_st        The ICE stream transport. 
    452  * @param stun_srv      The STUN server address, or NULL if STUN 
    453  *                      reflexive candidate is not to be used. 
    454  * @param turn_srv      The TURN server address, or NULL if STUN 
    455  *                      relay candidate is not to be used. 
    456  * 
    457  * @return              PJ_SUCCESS, or the appropriate error code. 
    458  */ 
    459 PJ_DECL(pj_status_t)  
    460 pj_ice_strans_set_stun_srv( pj_ice_strans *ice_st, 
    461                             const pj_sockaddr_in *stun_srv, 
    462                             const pj_sockaddr_in *turn_srv); 
    463460 
    464461/** 
  • pjproject/branches/projects/ice-turn07/pjnath/include/pjnath/stun_config.h

    r1374 r1926  
    2626 
    2727#include <pjnath/stun_msg.h> 
     28#include <pj/assert.h> 
     29#include <pj/errno.h> 
    2830#include <pj/string.h> 
    2931 
     
    104106 
    105107/** 
     108 * Check that STUN config is valid. 
     109 */ 
     110PJ_INLINE(pj_status_t) pj_stun_config_check_valid(const pj_stun_config *cfg) 
     111{ 
     112    PJ_ASSERT_RETURN(cfg->ioqueue && cfg->pf && cfg->timer_heap && 
     113                     cfg->rto_msec && cfg->res_cache_msec, PJ_EINVAL); 
     114    return PJ_SUCCESS; 
     115} 
     116 
     117 
     118/** 
    106119 * @} 
    107120 */ 
  • pjproject/branches/projects/ice-turn07/pjnath/include/pjnath/turn_session.h

    r1914 r1926  
    177177     */ 
    178178    void (*on_rx_data)(pj_turn_session *sess, 
    179                        const pj_uint8_t *pkt, 
     179                       void *pkt, 
    180180                       unsigned pkt_len, 
    181181                       const pj_sockaddr_t *peer_addr, 
     
    258258 * Create TURN client session. 
    259259 */ 
    260 PJ_DECL(pj_status_t) pj_turn_session_create(pj_stun_config *cfg, 
     260PJ_DECL(pj_status_t) pj_turn_session_create(const pj_stun_config *cfg, 
    261261                                            const char *name, 
    262262                                            int af, 
     
    341341 */ 
    342342PJ_DECL(pj_status_t) pj_turn_session_on_rx_pkt(pj_turn_session *sess, 
    343                                                const pj_uint8_t *pkt, 
     343                                               void *pkt, 
    344344                                               unsigned pkt_len, 
    345345                                               pj_bool_t is_datagram); 
  • pjproject/branches/projects/ice-turn07/pjnath/include/pjnath/turn_sock.h

    r1913 r1926  
    1717 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  
    1818 */ 
    19 #ifndef __PJNATH_turn_sock_H__ 
    20 #define __PJNATH_turn_sock_H__ 
     19#ifndef __PJNATH_TURN_SOCK_H__ 
     20#define __PJNATH_TURN_SOCK_H__ 
    2121 
    2222/** 
     
    5454     */ 
    5555    void (*on_rx_data)(pj_turn_sock *turn_sock, 
    56                        const pj_uint8_t *pkt, 
     56                       void *pkt, 
    5757                       unsigned pkt_len, 
    5858                       const pj_sockaddr_t *peer_addr, 
     
    105105 
    106106/** 
     107 * Lock the TURN socket. Application may need to call this function to 
     108 * synchronize access to other objects to avoid deadlock. 
     109 */ 
     110PJ_DECL(pj_status_t) pj_turn_sock_lock(pj_turn_sock *turn_sock); 
     111 
     112 
     113/** 
     114 * Unlock the TURN socket. 
     115 */ 
     116PJ_DECL(pj_status_t) pj_turn_sock_unlock(pj_turn_sock *turn_sock); 
     117 
     118 
     119/** 
    107120 * Initialize. 
    108121 */ 
     
    139152 
    140153 
    141 #endif  /* __PJNATH_turn_sock_H__ */ 
     154#endif  /* __PJNATH_TURN_SOCK_H__ */ 
    142155 
  • pjproject/branches/projects/ice-turn07/pjnath/src/pjnath/ice_session.c

    r1913 r1926  
    102102 
    103103 
     104/* This is the data that will be attached as token to outgoing 
     105 * STUN messages. 
     106 */ 
     107struct msg_data 
     108{ 
     109    pj_bool_t                        is_request; 
     110 
     111    union data { 
     112        struct request_data { 
     113            pj_ice_sess             *ice; 
     114            pj_ice_sess_checklist   *clist; 
     115            unsigned                 ckid; 
     116        } req; 
     117 
     118        struct response_data { 
     119            unsigned                 cand_id; 
     120        } res; 
     121    } data; 
     122}; 
     123 
     124 
    104125/* Forward declarations */ 
    105126static void destroy_ice(pj_ice_sess *ice, 
     
    13461367} 
    13471368 
    1348  
    1349 /* This is the data that will be attached as user data to outgoing 
    1350  * STUN requests, and it will be given back when we receive completion 
    1351  * status of the request. 
    1352  */ 
    1353 struct req_data 
    1354 { 
    1355     pj_ice_sess             *ice; 
    1356     pj_ice_sess_checklist   *clist; 
    1357     unsigned                 ckid; 
    1358 }; 
    1359  
    1360  
    13611369/* Perform check on the specified candidate pair */ 
    13621370static pj_status_t perform_check(pj_ice_sess *ice,  
     
    13651373{ 
    13661374    pj_ice_sess_comp *comp; 
    1367     struct req_data *rd; 
     1375    struct msg_data *msg_data; 
    13681376    pj_ice_sess_check *check; 
    13691377    const pj_ice_sess_cand *lcand; 
     
    13931401     * completes and on_stun_request_complete() callback is called. 
    13941402     */ 
    1395     rd = PJ_POOL_ZALLOC_T(check->tdata->pool, struct req_data); 
    1396     rd->ice = ice; 
    1397     rd->clist = clist; 
    1398     rd->ckid = check_id; 
     1403    msg_data = PJ_POOL_ZALLOC_T(check->tdata->pool, struct msg_data); 
     1404    msg_data->is_request = PJ_TRUE; 
     1405    msg_data->data.req.ice = ice; 
     1406    msg_data->data.req.clist = clist; 
     1407    msg_data->data.req.ckid = check_id; 
    13991408 
    14001409    /* Add PRIORITY */ 
     
    14281437 
    14291438    /* Initiate STUN transaction to send the request */ 
    1430     status = pj_stun_session_send_msg(comp->stun_sess, (void*)rd, PJ_FALSE,  
     1439    status = pj_stun_session_send_msg(comp->stun_sess, msg_data, PJ_FALSE,  
    14311440                                      PJ_TRUE, &rcand->addr,  
    14321441                                      sizeof(pj_sockaddr_in), check->tdata); 
     
    16561665    stun_data *sd = (stun_data*) pj_stun_session_get_user_data(sess); 
    16571666    pj_ice_sess *ice = sd->ice; 
    1658  
    1659     PJ_UNUSED_ARG(token); 
    1660  
    1661     return (*ice->cb.on_tx_pkt)(ice, sd->comp_id,  
    1662                                 pkt, pkt_size,  
    1663                                 dst_addr, addr_len); 
     1667    struct msg_data *msg_data = (struct msg_data*) token; 
     1668    unsigned cand_id; 
     1669     
     1670    if (msg_data->is_request) { 
     1671        pj_ice_sess_checklist *clist = msg_data->data.req.clist; 
     1672        pj_ice_sess_cand *lcand = clist->checks[msg_data->data.req.ckid].lcand; 
     1673 
     1674        cand_id = lcand - ice->lcand; 
     1675         
     1676    } else { 
     1677        cand_id = msg_data->data.res.cand_id; 
     1678    } 
     1679 
     1680    return (*ice->cb.on_tx_pkt)(ice, sd->comp_id, cand_id, 
     1681                                pkt, pkt_size, dst_addr, addr_len); 
    16641682} 
    16651683 
     
    16741692                                     unsigned src_addr_len) 
    16751693{ 
    1676     struct req_data *rd = (struct req_data*) token; 
     1694    struct msg_data *msg_data = (struct msg_data*) token; 
    16771695    pj_ice_sess *ice; 
    16781696    pj_ice_sess_check *check, *new_check; 
     
    16851703    PJ_UNUSED_ARG(src_addr_len); 
    16861704 
    1687     ice = rd->ice; 
    1688     check = &rd->clist->checks[rd->ckid]; 
    1689     clist = rd->clist; 
     1705    pj_assert(msg_data->is_request); 
     1706 
     1707    ice = msg_data->data.req.ice; 
     1708    clist = msg_data->data.req.clist; 
     1709    check = &clist->checks[msg_data->data.req.ckid]; 
     1710     
    16901711 
    16911712    /* Mark STUN transaction as complete */ 
     
    17401761            LOG4((ice->obj_name, "Resending check because of role conflict")); 
    17411762            check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_WAITING, 0); 
    1742             perform_check(ice, clist, rd->ckid); 
     1763            perform_check(ice, clist, msg_data->data.req.ckid); 
    17431764            pj_mutex_unlock(ice->mutex); 
    17441765            return; 
     
    19191940{ 
    19201941    stun_data *sd; 
     1942    unsigned *param_cand_id; 
    19211943    const pj_stun_msg *msg = rdata->msg; 
     1944    struct msg_data *msg_data; 
    19221945    pj_ice_sess *ice; 
    19231946    pj_stun_priority_attr *prio_attr; 
     
    19301953    PJ_UNUSED_ARG(pkt); 
    19311954    PJ_UNUSED_ARG(pkt_len); 
    1932     PJ_UNUSED_ARG(token); 
     1955     
     1956    /* 
     1957     * Note about candidate ID parameter: 
     1958     *  This parameter is given by us by user, and it cannot be used to 
     1959     *  distinguish local and server reflexive candidate. Just about the 
     1960     *  only thing that we can do with it is to return it back to user 
     1961     *  in the on_tx_pkt(). The user needs this information to determine 
     1962     *  whether to send packet using local socket or the relay. 
     1963     */ 
     1964    param_cand_id = (unsigned*)token; 
    19331965 
    19341966    /* Reject any requests except Binding request */ 
     
    20352067    } 
    20362068 
     2069    /* Add XOR-MAPPED-ADDRESS attribute */ 
    20372070    status = pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg,  
    20382071                                           PJ_STUN_ATTR_XOR_MAPPED_ADDR, 
    20392072                                           PJ_TRUE, src_addr, src_addr_len); 
    20402073 
    2041     status = pj_stun_session_send_msg(sess, NULL, PJ_TRUE, PJ_TRUE, 
     2074    /* Create a msg_data to be associated with this response */ 
     2075    msg_data = PJ_POOL_ZALLOC_T(tdata->pool, struct msg_data); 
     2076    msg_data->is_request = PJ_FALSE; 
     2077    msg_data->data.res.cand_id = *param_cand_id; 
     2078 
     2079    /* Send the response */ 
     2080    status = pj_stun_session_send_msg(sess, msg_data, PJ_TRUE, PJ_TRUE, 
    20422081                                      src_addr, src_addr_len, tdata); 
    20432082 
     
    20912130    pj_ice_sess_cand *rcand; 
    20922131    unsigned i; 
    2093     pj_bool_t is_relayed; 
    20942132 
    20952133    comp = find_comp(ice, rcheck->comp_id); 
     
    21712209     * Create candidate pair for this request.  
    21722210     */ 
    2173     /* First check if the source address is the source address of the  
    2174      * STUN relay, to determine if local candidate is relayed candidate. 
    2175      */ 
    2176     PJ_TODO(DETERMINE_IF_REQUEST_COMES_FROM_RELAYED_CANDIDATE); 
    2177     is_relayed = PJ_FALSE; 
    21782211 
    21792212    /*  
     
    23102343    pj_status_t status = PJ_SUCCESS; 
    23112344    pj_ice_sess_comp *comp; 
     2345    unsigned cand_id; 
    23122346 
    23132347    PJ_ASSERT_RETURN(ice && comp_id, PJ_EINVAL); 
     
    23332367    } 
    23342368 
    2335     status = (*ice->cb.on_tx_pkt)(ice, comp_id, data, data_len,  
     2369    cand_id = comp->valid_check->lcand - ice->lcand; 
     2370 
     2371    status = (*ice->cb.on_tx_pkt)(ice, comp_id, cand_id, data, data_len,  
    23362372                                  &comp->valid_check->rcand->addr,  
    23372373                                  sizeof(pj_sockaddr_in)); 
     
    23452381PJ_DEF(pj_status_t) pj_ice_sess_on_rx_pkt(pj_ice_sess *ice, 
    23462382                                          unsigned comp_id, 
     2383                                          unsigned cand_id, 
    23472384                                          void *pkt, 
    23482385                                          pj_size_t pkt_size, 
     
    23682405    if (stun_status == PJ_SUCCESS) { 
    23692406        status = pj_stun_session_on_rx_pkt(comp->stun_sess, pkt, pkt_size, 
    2370                                            PJ_STUN_IS_DATAGRAM, NULL, 
     2407                                           PJ_STUN_IS_DATAGRAM, &cand_id, 
    23712408                                           NULL, src_addr, src_addr_len); 
    23722409        if (status != PJ_SUCCESS) { 
  • pjproject/branches/projects/ice-turn07/pjnath/src/pjnath/ice_strans.c

    r1913 r1926  
    4141static pj_status_t ice_tx_pkt(pj_ice_sess *ice,  
    4242                              unsigned comp_id, 
     43                              unsigned cand_id, 
    4344                              const void *pkt, pj_size_t size, 
    4445                              const pj_sockaddr_t *dst_addr, 
     
    7475                                     unsigned src_addr_len); 
    7576 
     77/* TURN callbacks */ 
     78static void turn_on_rx_data(pj_turn_sock *turn_sock, 
     79                            void *pkt, 
     80                            unsigned pkt_len, 
     81                            const pj_sockaddr_t *peer_addr, 
     82                            unsigned addr_len); 
     83static void turn_on_state(pj_turn_sock *turn_sock, pj_turn_state_t old_state, 
     84                          pj_turn_state_t new_state); 
     85 
     86 
    7687/* Keep-alive timer */ 
    7788static void start_ka_timer(pj_ice_strans *ice_st); 
     
    8192#define ice_st_perror(ice_st,msg,rc) pjnath_perror(ice_st->obj_name,msg,rc) 
    8293 
     94/* Validate configuration */ 
     95static pj_status_t pj_ice_strans_cfg_check_valid(const pj_ice_strans_cfg *cfg) 
     96{ 
     97    pj_status_t status; 
     98 
     99    status = pj_stun_config_check_valid(&cfg->stun_cfg); 
     100    if (!status) 
     101        return status; 
     102 
     103    /* If TURN is specified then TURN credential must be specified */ 
     104    PJ_ASSERT_RETURN(!pj_sockaddr_has_addr(&cfg->turn_srv) || 
     105                      cfg->turn_cred.type != PJ_STUN_AUTH_NONE, 
     106                     PJ_EINVAL); 
     107 
     108    return PJ_SUCCESS; 
     109} 
     110 
     111 
    83112/*  
    84113 * Create ICE stream transport  
    85114 */ 
    86 PJ_DEF(pj_status_t) pj_ice_strans_create( pj_stun_config *stun_cfg, 
     115PJ_DEF(pj_status_t) pj_ice_strans_create( const pj_ice_strans_cfg *cfg, 
    87116                                          const char *name, 
    88117                                          unsigned comp_cnt, 
     
    93122    pj_pool_t *pool; 
    94123    pj_ice_strans *ice_st; 
    95  
    96     PJ_ASSERT_RETURN(stun_cfg && comp_cnt && cb && p_ice_st, PJ_EINVAL); 
    97     PJ_ASSERT_RETURN(stun_cfg->ioqueue && stun_cfg->timer_heap, PJ_EINVAL); 
     124    pj_status_t status; 
     125 
     126    status = pj_ice_strans_cfg_check_valid(cfg); 
     127    if (status != PJ_SUCCESS) 
     128        return status; 
     129 
     130    PJ_ASSERT_RETURN(comp_cnt && cb && p_ice_st, PJ_EINVAL); 
    98131 
    99132    if (name == NULL) 
    100133        name = "icstr%p"; 
    101134 
    102     pool = pj_pool_create(stun_cfg->pf, name, PJNATH_POOL_LEN_ICE_STRANS,  
     135    pool = pj_pool_create(cfg->stun_cfg.pf, name, PJNATH_POOL_LEN_ICE_STRANS,  
    103136                          PJNATH_POOL_INC_ICE_STRANS, NULL); 
    104137    ice_st = PJ_POOL_ZALLOC_T(pool, pj_ice_strans); 
    105138    ice_st->pool = pool; 
     139    pj_memcpy(&ice_st->cfg, cfg, sizeof(*cfg)); 
     140    pj_stun_auth_cred_dup(pool, &ice_st->cfg.turn_cred, &cfg->turn_cred); 
    106141    pj_memcpy(ice_st->obj_name, pool->obj_name, PJ_MAX_OBJ_NAME); 
    107142    ice_st->user_data = user_data; 
     
    112147 
    113148    pj_memcpy(&ice_st->cb, cb, sizeof(*cb)); 
    114     pj_memcpy(&ice_st->stun_cfg, stun_cfg, sizeof(*stun_cfg)); 
    115149 
    116150 
     
    179213    PJ_UNUSED_ARG(domain); 
    180214    return -1; 
    181 } 
    182  
    183 /* 
    184  * Set STUN server address. 
    185  */ 
    186 PJ_DEF(pj_status_t) pj_ice_strans_set_stun_srv( pj_ice_strans *ice_st, 
    187                                                 const pj_sockaddr_in *stun_srv, 
    188                                                 const pj_sockaddr_in *turn_srv) 
    189 { 
    190     PJ_ASSERT_RETURN(ice_st, PJ_EINVAL); 
    191     /* Must not have pending resolver job */ 
    192     PJ_ASSERT_RETURN(ice_st->has_rjob==PJ_FALSE, PJ_EINVALIDOP); 
    193  
    194     if (stun_srv) { 
    195         pj_memcpy(&ice_st->stun_srv, stun_srv, sizeof(pj_sockaddr_in)); 
    196     } else { 
    197         pj_bzero(&ice_st->stun_srv, sizeof(pj_sockaddr_in)); 
    198     } 
    199  
    200     if (turn_srv) { 
    201         pj_memcpy(&ice_st->turn_srv, turn_srv, sizeof(pj_sockaddr_in)); 
    202     } else { 
    203         pj_bzero(&ice_st->turn_srv, sizeof(pj_sockaddr_in)); 
    204     } 
    205  
    206     return PJ_SUCCESS; 
    207215} 
    208216 
     
    328336    pj_bzero(&ioqueue_cb, sizeof(ioqueue_cb)); 
    329337    ioqueue_cb.on_read_complete = &on_read_complete; 
    330     status = pj_ioqueue_register_sock(ice_st->pool, ice_st->stun_cfg.ioqueue,  
     338    status = pj_ioqueue_register_sock(ice_st->pool,  
     339                                      ice_st->cfg.stun_cfg.ioqueue,  
    331340                                      comp->sock, comp, &ioqueue_cb,  
    332341                                      &comp->key); 
     
    388397             * as default candidate. 
    389398             */ 
    390             if (ifs[i].ipv4.sin_addr.s_addr == comp->local_addr.ipv4.sin_addr.s_addr) { 
     399            if (ifs[i].ipv4.sin_addr.s_addr ==  
     400                    comp->local_addr.ipv4.sin_addr.s_addr)  
     401            { 
    391402                set_default = PJ_TRUE; 
    392403                local_pref = 65535; 
     
    464475         *    the binding alive. 
    465476         *  
    466          * 2) this could be a packet (STUN or not STUN) sent from the STUN 
    467          *    relay server. In this case, still there are few options to do 
    468          *    for this packet: a) process this locally if this packet is 
    469          *    related to TURN session management (e.g. Allocate response), 
    470          *    b) forward this packet to ICE if this is related to ICE 
     477         * 2) this could be a STUN request or response sent as part of ICE 
    471478         *    discovery process. 
    472479         * 
    473          * 3) this could be a STUN request or response sent as part of ICE 
    474          *    discovery process. 
    475          * 
    476          * 4) this could be application's packet, e.g. when ICE processing 
     480         * 3) this could be application's packet, e.g. when ICE processing 
    477481         *    is done and agents start sending RTP/RTCP packets to each 
    478482         *    other, or when ICE processing is not done and this ICE stream 
    479483         *    transport decides to allow sending data. 
    480484         * 
    481          * So far we don't have good solution for this. 
    482          * The process below is just a workaround. 
    483485         */ 
     486        unsigned cand_id; 
     487 
     488        /* Find candidate ID for this packet */ 
     489        for (cand_id=0; cand_id<comp->cand_cnt; ++cand_id) { 
     490            if (comp->cand_list[cand_id].type != PJ_ICE_CAND_TYPE_RELAYED) 
     491                break; 
     492        } 
     493        if (cand_id == comp->cand_cnt) { 
     494            //pj_assert(!"We should have at least one host/srflx candidate"); 
     495            //cand_id = 0; 
     496            PJ_LOG(2,(ice_st->obj_name,  
     497                      "Received pkt on comp %d which doesn't have host/srflx " 
     498                      "candidate", 
     499                      comp->comp_id)); 
     500            goto next_packet; 
     501        } 
     502 
     503        /* Is this a STUN message? */ 
    484504        status = pj_stun_msg_check(comp->pkt, bytes_read,  
    485505                                   PJ_STUN_IS_DATAGRAM); 
     
    496516                                                   comp->src_addr_len); 
    497517            } else if (ice_st->ice) { 
    498                 PJ_TODO(DISTINGUISH_BETWEEN_LOCAL_AND_RELAY); 
    499  
    500518                TRACE_PKT((comp->ice_st->obj_name,  
    501519                          "Component %d RX packet from %s:%d", 
     
    505523 
    506524                status = pj_ice_sess_on_rx_pkt(ice_st->ice, comp->comp_id,  
    507                                                comp->pkt, bytes_read, 
     525                                               cand_id, comp->pkt, bytes_read, 
    508526                                               &comp->src_addr,  
    509527                                               comp->src_addr_len); 
     
    525543 
    526544    /* Read next packet */ 
     545next_packet: 
    527546    for (retry=0; retry<RETRY;) { 
    528547        pkt_size = sizeof(comp->pkt); 
     
    552571static void destroy_component(pj_ice_strans_comp *comp) 
    553572{ 
     573    if (comp->turn_relay) { 
     574        pj_turn_sock_destroy(comp->turn_relay); 
     575        comp->turn_relay = NULL; 
     576    } 
     577 
    554578    if (comp->stun_sess) { 
    555579        pj_stun_session_destroy(comp->stun_sess); 
     
    611635                  pj_ntohs(comp->local_addr.ipv4.sin_port))); 
    612636        status = pj_stun_session_send_msg(comp->stun_sess, &comp->cand_list[j], 
    613                                           PJ_FALSE, PJ_TRUE, &ice_st->stun_srv, 
     637                                          PJ_FALSE, PJ_TRUE,  
     638                                          &ice_st->cfg.stun_srv, 
    614639                                          sizeof(pj_sockaddr_in), tdata); 
    615640        if (status != PJ_SUCCESS) { 
     
    638663    ice_st->ka_timer.user_data = ice_st; 
    639664     
    640     if (pj_timer_heap_schedule(ice_st->stun_cfg.timer_heap,  
     665    if (pj_timer_heap_schedule(ice_st->cfg.stun_cfg.timer_heap,  
    641666                               &ice_st->ka_timer, &delay)==PJ_SUCCESS) 
    642667    { 
     
    653678        return; 
    654679 
    655     pj_timer_heap_cancel(ice_st->stun_cfg.timer_heap, &ice_st->ka_timer); 
     680    pj_timer_heap_cancel(ice_st->cfg.stun_cfg.timer_heap, &ice_st->ka_timer); 
    656681    ice_st->ka_timer.id = PJ_FALSE; 
    657682} 
     
    671696    PJ_ASSERT_RETURN(ice_st && comp, PJ_EINVAL); 
    672697     
    673     /* Bail out if STUN server is still being resolved */ 
    674     if (ice_st->has_rjob) 
    675         return PJ_EBUSY; 
    676  
    677698    /* Just return (successfully) if STUN server is not configured */ 
    678     if (ice_st->stun_srv.sin_family == 0) 
     699    if (ice_st->cfg.stun_srv.addr.sa_family == 0) 
    679700        return PJ_SUCCESS; 
    680701 
     
    684705    sess_cb.on_request_complete = &stun_on_request_complete; 
    685706    sess_cb.on_send_msg = &stun_on_send_msg; 
    686     status = pj_stun_session_create(&ice_st->stun_cfg, ice_st->obj_name, 
     707    status = pj_stun_session_create(&ice_st->cfg.stun_cfg, ice_st->obj_name, 
    687708                                    &sess_cb, PJ_FALSE, &comp->stun_sess); 
    688709    if (status != PJ_SUCCESS) 
     
    711732    /* Add new alias to this component */ 
    712733    cand->type = PJ_ICE_CAND_TYPE_SRFLX; 
    713     cand->status = PJ_EPENDING; 
     734    cand->status = PJ_SUCCESS; 
    714735    cand->ice_cand_id = -1; 
    715736    cand->local_pref = 65535; 
     
    721742    /* Send STUN binding request */ 
    722743    status = pj_stun_session_send_msg(comp->stun_sess, (void*)cand, PJ_FALSE,  
    723                                       PJ_TRUE, &ice_st->stun_srv,  
     744                                      PJ_TRUE, &ice_st->cfg.stun_srv,  
    724745                                      sizeof(pj_sockaddr_in), tdata); 
    725746    if (status != PJ_SUCCESS) { 
     
    753774    PJ_ASSERT_RETURN(ice_st->ice == NULL, PJ_EBUSY); 
    754775     
    755     /* Can't add new component while resolver is running */ 
    756     PJ_ASSERT_RETURN(ice_st->has_rjob == PJ_FALSE, PJ_EBUSY); 
    757  
    758776 
    759777    /* Create component */ 
     
    762780        return status; 
    763781 
    764     if ((options & PJ_ICE_ST_OPT_DISABLE_STUN) == 0) { 
     782    /* Start STUN mapped address resolution */ 
     783    if ((options & PJ_ICE_ST_OPT_DISABLE_STUN) == 0 && 
     784        pj_sockaddr_has_addr(&ice_st->cfg.stun_srv))  
     785    { 
    765786        status = get_stun_mapped_addr(ice_st, comp); 
    766787        if (status != PJ_SUCCESS) { 
     
    769790        } 
    770791    } 
     792 
     793    /* Create TURN relay if wanted. */ 
     794    if ((options & PJ_ICE_ST_OPT_DISABLE_RELAY) == 0 && 
     795        pj_sockaddr_has_addr(&ice_st->cfg.turn_srv))  
     796    { 
     797        pj_turn_sock_cb turn_sock_cb; 
     798        char ipaddr[PJ_INET6_ADDRSTRLEN+8]; 
     799        pj_str_t s; 
     800 
     801        pj_assert(comp->cand_cnt < PJ_ICE_ST_MAX_CAND); 
     802 
     803        /* Init TURN socket */ 
     804        pj_bzero(&turn_sock_cb, sizeof(turn_sock_cb)); 
     805        turn_sock_cb.on_rx_data = &turn_on_rx_data; 
     806        turn_sock_cb.on_state = &turn_on_state; 
     807 
     808        status = pj_turn_sock_create(&ice_st->cfg.stun_cfg, pj_AF_INET(), 
     809                                     ice_st->cfg.turn_conn_type, 
     810                                     &turn_sock_cb, 0, comp, 
     811                                     &comp->turn_relay); 
     812        if (status != PJ_SUCCESS) { 
     813            destroy_component(comp); 
     814            return status; 
     815        } 
     816 
     817        pj_sockaddr_print(&ice_st->cfg.turn_srv, ipaddr, sizeof(ipaddr), 0); 
     818 
     819        ++comp->pending_cnt; 
     820 
     821        /* Start allocation */ 
     822        status = pj_turn_sock_init(comp->turn_relay, pj_cstr(&s, ipaddr),  
     823                                   pj_sockaddr_get_port(&ice_st->cfg.turn_srv), 
     824                                   NULL, &ice_st->cfg.turn_cred,  
     825                                   &ice_st->cfg.turn_alloc_param); 
     826        if (status != PJ_SUCCESS) { 
     827            if (comp->turn_relay) { 
     828                pj_turn_sock_destroy(comp->turn_relay); 
     829            } 
     830            comp->turn_relay = NULL; 
     831            --comp->pending_cnt; 
     832            destroy_component(comp); 
     833            return status; 
     834        } 
     835 
     836    } 
     837 
    771838 
    772839    /* Store this component */ 
     
    849916 
    850917    /* Create! */ 
    851     status = pj_ice_sess_create(&ice_st->stun_cfg, ice_st->obj_name, role, 
     918    status = pj_ice_sess_create(&ice_st->cfg.stun_cfg, ice_st->obj_name, role, 
    852919                                ice_st->comp_cnt, &ice_cb,  
    853920                                local_ufrag, local_passwd, &ice_st->ice); 
     
    877944        for (j=0; j<comp->cand_cnt; ++j) { 
    878945            pj_ice_strans_cand *cand = &comp->cand_list[j]; 
     946            pj_sockaddr_t *local_addr, *relay_addr; 
    879947 
    880948            /* Skip if candidate is not ready */ 
     
    886954            } 
    887955 
     956            if (cand->type == PJ_ICE_CAND_TYPE_RELAYED) { 
     957                local_addr = &cand->addr; 
     958                relay_addr = &cand->addr; 
     959            } else { 
     960                local_addr = &comp->local_addr; 
     961                relay_addr = NULL; 
     962            } 
    888963            status = pj_ice_sess_add_cand(ice_st->ice, comp->comp_id,  
    889964                                          cand->type, cand->local_pref,  
     
    9781053 
    9791054/* 
    980  * Send packet using non-ICE means (e.g. when ICE was not negotiated). 
     1055 * Application wants to send outgoing packet. 
    9811056 */ 
    9821057PJ_DEF(pj_status_t) pj_ice_strans_sendto( pj_ice_strans *ice_st, 
     
    9981073    /* If ICE is available, send data with ICE */ 
    9991074    if (ice_st->ice) { 
    1000         return pj_ice_sess_send_data(ice_st->ice, comp_id, data, data_len); 
     1075        if (comp->turn_relay) { 
     1076            pj_turn_sock_lock(comp->turn_relay); 
     1077        } 
     1078        status = pj_ice_sess_send_data(ice_st->ice, comp_id, data, data_len); 
     1079        if (comp->turn_relay) { 
     1080            pj_turn_sock_unlock(comp->turn_relay); 
     1081        } 
     1082        return status; 
    10011083    } 
    10021084 
     
    10291111static pj_status_t ice_tx_pkt(pj_ice_sess *ice,  
    10301112                              unsigned comp_id,  
     1113                              unsigned cand_id, 
    10311114                              const void *pkt, pj_size_t size, 
    10321115                              const pj_sockaddr_t *dst_addr, 
     
    10341117{ 
    10351118    pj_ice_strans *ice_st = (pj_ice_strans*)ice->user_data; 
    1036     pj_ice_strans_comp *comp = NULL; 
    1037     pj_ssize_t pkt_size; 
     1119    pj_ice_strans_comp *comp; 
     1120    pj_ice_strans_cand *cand; 
    10381121    pj_status_t status; 
    10391122 
    1040     PJ_TODO(TX_TO_RELAY); 
    1041  
    10421123    PJ_ASSERT_RETURN(comp_id && comp_id <= ice_st->comp_cnt, PJ_EINVAL); 
     1124 
    10431125    comp = ice_st->comp[comp_id-1]; 
     1126    cand = &comp->cand_list[cand_id]; 
    10441127 
    10451128    TRACE_PKT((comp->ice_st->obj_name,  
    1046               "Component %d TX packet to %s:%d", 
    1047               comp_id, 
     1129              "Component %d candidate %d TX packet to %s:%d", 
     1130              comp_id, cand_id, 
    10481131              pj_inet_ntoa(((pj_sockaddr_in*)dst_addr)->sin_addr), 
    10491132              (int)pj_ntohs(((pj_sockaddr_in*)dst_addr)->sin_port))); 
    10501133 
    1051     pkt_size = size; 
    1052     status = pj_ioqueue_sendto(comp->key, &comp->write_op,  
    1053                                pkt, &pkt_size, 0, 
    1054                                dst_addr, dst_addr_len); 
     1134    if (cand->type == PJ_ICE_CAND_TYPE_RELAYED) { 
     1135        if (comp->turn_relay) { 
     1136            status = pj_turn_sock_sendto(comp->turn_relay, pkt, size, 
     1137                                         dst_addr, dst_addr_len); 
     1138        } else { 
     1139            status = PJ_EINVALIDOP; 
     1140        } 
     1141    } else { 
     1142        pj_ssize_t pkt_size = size; 
     1143        status = pj_ioqueue_sendto(comp->key, &comp->write_op,  
     1144                                   pkt, &pkt_size, 0, 
     1145                                   dst_addr, dst_addr_len); 
     1146    } 
    10551147     
    10561148    return (status==PJ_SUCCESS||status==PJ_EPENDING) ? PJ_SUCCESS : status; 
     
    12071299} 
    12081300 
     1301 
     1302/* Callback when TURN client has received a packet */ 
     1303static void turn_on_rx_data(pj_turn_sock *turn_sock, 
     1304                            void *pkt, 
     1305                            unsigned pkt_len, 
     1306                            const pj_sockaddr_t *peer_addr, 
     1307                            unsigned addr_len) 
     1308{ 
     1309    pj_ice_strans_comp *comp; 
     1310    unsigned cand_id; 
     1311    pj_status_t status; 
     1312 
     1313    comp = (pj_ice_strans_comp*) pj_turn_sock_get_user_data(turn_sock); 
     1314    if (comp == NULL) { 
     1315        return; 
     1316    } 
     1317 
     1318    /* Find candidate ID for this packet */ 
     1319    for (cand_id=0; cand_id<comp->cand_cnt; ++cand_id) { 
     1320        if (comp->cand_list[cand_id].type == PJ_ICE_CAND_TYPE_RELAYED) 
     1321            break; 
     1322    } 
     1323    if (cand_id == comp->cand_cnt) { 
     1324        pj_assert(!"Missing relay candidate"); 
     1325        return; 
     1326    } 
     1327 
     1328    /* Hand over the packet to ICE */ 
     1329    status = pj_ice_sess_on_rx_pkt(comp->ice_st->ice, comp->comp_id,  
     1330                                   cand_id, pkt, pkt_len, 
     1331                                   peer_addr, addr_len); 
     1332 
     1333    if (status != PJ_SUCCESS) { 
     1334        ice_st_perror(comp->ice_st, "Error processing packet from TURN relay",  
     1335                      status); 
     1336    } 
     1337} 
     1338 
     1339 
     1340/* Callback when TURN client state has changed */ 
     1341static void turn_on_state(pj_turn_sock *turn_sock, pj_turn_state_t old_state, 
     1342                          pj_turn_state_t new_state) 
     1343{ 
     1344    pj_ice_strans_comp *comp; 
     1345 
     1346    comp = (pj_ice_strans_comp*) pj_turn_sock_get_user_data(turn_sock); 
     1347    if (comp == NULL) { 
     1348        /* Not interested in further state notification once the relay is 
     1349         * disconnecting. 
     1350         */ 
     1351        return; 
     1352    } 
     1353 
     1354    PJ_LOG(5,(comp->ice_st->obj_name, "TURN client state changed %s --> %s", 
     1355              pj_turn_state_name(old_state), pj_turn_state_name(new_state))); 
     1356 
     1357    if (old_state < PJ_TURN_STATE_READY && 
     1358        new_state >= PJ_TURN_STATE_READY) 
     1359    { 
     1360        pj_assert(comp->pending_cnt > 0); 
     1361        comp->pending_cnt--; 
     1362    } 
     1363 
     1364    if (new_state == PJ_TURN_STATE_READY) { 
     1365        pj_turn_session_info rel_info; 
     1366        char ipaddr[PJ_INET6_ADDRSTRLEN+8]; 
     1367        pj_ice_strans_cand *cand; 
     1368 
     1369        /* Get allocation info */ 
     1370        pj_turn_sock_get_info(turn_sock, &rel_info); 
     1371 
     1372        /* Add a relay candidate to this component */ 
     1373        pj_assert(comp->cand_cnt < PJ_ICE_ST_MAX_CAND); 
     1374        cand = &comp->cand_list[comp->cand_cnt++]; 
     1375 
     1376        /* Add new candidate to this component */ 
     1377        cand->type = PJ_ICE_CAND_TYPE_RELAYED; 
     1378        cand->status = PJ_SUCCESS; 
     1379        cand->ice_cand_id = -1; 
     1380        cand->local_pref = 65535; 
     1381        pj_sockaddr_cp(&cand->addr, &rel_info.relay_addr); 
     1382        pj_ice_calc_foundation(comp->ice_st->pool, &cand->foundation,  
     1383                               PJ_ICE_CAND_TYPE_RELAYED,  
     1384                               &rel_info.relay_addr); 
     1385 
     1386        PJ_LOG(4,(comp->ice_st->obj_name,  
     1387                  "Component %d cand %d: relay address: %s", 
     1388                  comp->comp_id, cand - comp->cand_list, 
     1389                  pj_sockaddr_print(&rel_info.relay_addr, ipaddr,  
     1390                                     sizeof(ipaddr), 3))); 
     1391 
     1392    } else if (new_state >= PJ_TURN_STATE_DEALLOCATING) { 
     1393        /* Unregister ourself from the TURN relay */ 
     1394        pj_turn_sock_set_user_data(turn_sock, NULL); 
     1395        comp->turn_relay = NULL; 
     1396 
     1397        PJ_LOG(4,(comp->ice_st->obj_name, "Relay destroyed")); 
     1398    } 
     1399} 
     1400 
  • pjproject/branches/projects/ice-turn07/pjnath/src/pjnath/turn_session.c

    r1914 r1926  
    6767    pj_turn_session_cb   cb; 
    6868    void                *user_data; 
     69    pj_stun_config       stun_cfg; 
    6970 
    7071    pj_lock_t           *lock; 
     
    177178 * Create TURN client session. 
    178179 */ 
    179 PJ_DEF(pj_status_t) pj_turn_session_create( pj_stun_config *cfg, 
     180PJ_DEF(pj_status_t) pj_turn_session_create( const pj_stun_config *cfg, 
    180181                                            const char *name, 
    181182                                            int af, 
     
    212213    sess->next_ch = PJ_TURN_CHANNEL_MIN; 
    213214 
     215    /* Copy STUN session */ 
     216    pj_memcpy(&sess->stun_cfg, cfg, sizeof(pj_stun_config)); 
     217 
    214218    /* Copy callback */ 
    215219    pj_memcpy(&sess->cb, cb, sizeof(*cb)); 
     
    234238    stun_cb.on_request_complete = &stun_on_request_complete; 
    235239    stun_cb.on_rx_indication = &stun_on_rx_indication; 
    236     status = pj_stun_session_create(cfg, sess->obj_name, &stun_cb, PJ_FALSE, 
    237                                     &sess->stun); 
     240    status = pj_stun_session_create(&sess->stun_cfg, sess->obj_name, &stun_cb, 
     241                                    PJ_FALSE, &sess->stun); 
    238242    if (status != PJ_SUCCESS) { 
    239243        do_destroy(sess); 
     
    850854 */ 
    851855PJ_DEF(pj_status_t) pj_turn_session_on_rx_pkt(pj_turn_session *sess, 
    852                                               const pj_uint8_t *pkt, 
     856                                              void *pkt, 
    853857                                              unsigned pkt_len, 
    854858                                              pj_bool_t is_datagram) 
     
    865869 
    866870    /* Quickly check if this is STUN message */ 
    867     is_stun = ((pkt[0] & 0xC0) == 0); 
     871    is_stun = ((((pj_uint8_t*)pkt)[0] & 0xC0) == 0); 
    868872 
    869873    if (is_stun) { 
     
    871875        unsigned options; 
    872876 
    873         options = PJ_STUN_CHECK_PACKET; 
     877        options = PJ_STUN_CHECK_PACKET | PJ_STUN_NO_FINGERPRINT_CHECK; 
    874878        if (is_datagram) 
    875879            options |= PJ_STUN_IS_DATAGRAM; 
     
    906910 
    907911        /* Notify application */ 
    908         (*sess->cb.on_rx_data)(sess, pkt+sizeof(cd), cd.length, 
    909                                &peer->addr, 
     912        (*sess->cb.on_rx_data)(sess, ((pj_uint8_t*)pkt)+sizeof(cd),  
     913                               cd.length, &peer->addr, 
    910914                               pj_sockaddr_get_len(&peer->addr)); 
    911915 
  • pjproject/branches/projects/ice-turn07/pjnath/src/pjnath/turn_sock.c

    r1914 r1926  
    7272                                  unsigned ch_num); 
    7373static void turn_on_rx_data(pj_turn_session *sess, 
    74                             const pj_uint8_t *pkt, 
     74                            void *pkt, 
    7575                            unsigned pkt_len, 
    7676                            const pj_sockaddr_t *peer_addr, 
     
    310310} 
    311311 
     312/** 
     313 * Lock the TURN socket. Application may need to call this function to 
     314 * synchronize access to other objects to avoid deadlock. 
     315 */ 
     316PJ_DEF(pj_status_t) pj_turn_sock_lock(pj_turn_sock *turn_sock) 
     317{ 
     318    return pj_lock_acquire(turn_sock->lock); 
     319} 
     320 
     321/** 
     322 * Unlock the TURN socket. 
     323 */ 
     324PJ_DEF(pj_status_t) pj_turn_sock_unlock(pj_turn_sock *turn_sock) 
     325{ 
     326    return pj_lock_release(turn_sock->lock); 
     327} 
     328 
     329 
    312330/* 
    313331 * Initialize. 
     
    525543 */ 
    526544static void turn_on_rx_data(pj_turn_session *sess, 
    527                             const pj_uint8_t *pkt, 
     545                            void *pkt, 
    528546                            unsigned pkt_len, 
    529547                            const pj_sockaddr_t *peer_addr, 
  • pjproject/branches/projects/ice-turn07/pjnath/src/pjturn-srv/auth.c

    r1924 r1926  
    3636    { "100", "100" }, 
    3737    { "700", "700" }, 
    38     { "701", "701" }, 
    39     { "702", "702" } 
     38    { "701", "701" } 
    4039}; 
    4140 
  • pjproject/branches/projects/ice-turn07/pjsip-apps/src/pjsua/pjsua_app.c

    r1921 r1926  
    2323#define NO_LIMIT        (int)0x7FFFFFFF 
    2424 
     25#if 1 
     26#define TURN_SERVER     "turn.pjsip.org" 
     27#define TURN_PORT       34780 
     28#define TURN_TCP        0 
     29#define TURN_REALM      "pjsip.org" 
     30#define TURN_USER       "700" 
     31#define TURN_PASSWD     "700" 
     32#endif 
     33 
     34 
    2535//#define STEREO_DEMO 
    2636 
     
    5565    pj_pool_t              *pool; 
    5666    /* Compatibility with older pjsua */ 
     67 
     68    pj_bool_t               use_turn; 
    5769 
    5870    unsigned                codec_cnt; 
     
    172184    puts  ("Media Options:"); 
    173185    puts  ("  --use-ice           Enable ICE (default:no)"); 
     186    puts  ("  --use-turn          Enable experimantal TURN (default:no)"); 
     187    puts  ("  --ice-no-host       Disable ICE host candidates"); 
     188    puts  ("  --ice-no-srflx      Disable ICE srflx candidates"); 
     189    puts  ("  --ice-no-rtcp       Disable RTCP in ICE"); 
    174190    puts  ("  --add-codec=name    Manually add codec (default is to enable all)"); 
    175191    puts  ("  --dis-codec=name    Disable codec (can be specified multiple times)"); 
     
    392408           OPT_AUTO_ANSWER, OPT_AUTO_HANGUP, OPT_AUTO_PLAY, OPT_AUTO_LOOP, 
    393409           OPT_AUTO_CONF, OPT_CLOCK_RATE, OPT_SND_CLOCK_RATE, OPT_STEREO, 
    394            OPT_USE_ICE, OPT_USE_SRTP, OPT_SRTP_SECURE, 
     410           OPT_USE_ICE, OPT_USE_TURN, OPT_ICE_NO_HOST, OPT_ICE_NO_SRFLX,  
     411           OPT_ICE_NO_RTCP, OPT_USE_SRTP, OPT_SRTP_SECURE, 
    395412           OPT_PLAY_FILE, OPT_PLAY_TONE, OPT_RTP_PORT, OPT_ADD_CODEC,  
    396413           OPT_ILBC_MODE, OPT_REC_FILE, OPT_AUTO_REC, 
     
    453470        { "rtp-port",   1, 0, OPT_RTP_PORT}, 
    454471        { "use-ice",    0, 0, OPT_USE_ICE}, 
     472        { "use-turn",   0, 0, OPT_USE_TURN}, 
     473        { "ice-no-host",0, 0, OPT_ICE_NO_HOST}, 
     474        { "ice-no-srflx",0,0, OPT_ICE_NO_SRFLX}, 
     475        { "ice-no-rtcp",0, 0, OPT_ICE_NO_RTCP}, 
    455476#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) 
    456477        { "use-srtp",   1, 0, OPT_USE_SRTP}, 
     
    826847            break; 
    827848 
     849        case OPT_USE_TURN: 
     850            cfg->use_turn = PJ_TRUE; 
     851            break; 
     852 
     853        case OPT_ICE_NO_HOST: 
     854            cfg->media_cfg.ice_options |= PJ_ICE_ST_OPT_DONT_ADD_CAND; 
     855            break; 
     856 
     857        case OPT_ICE_NO_SRFLX: 
     858            cfg->media_cfg.ice_options |= PJ_ICE_ST_OPT_DISABLE_STUN; 
     859            break; 
     860 
     861        case OPT_ICE_NO_RTCP: 
     862            cfg->media_cfg.ice_no_rtcp = PJ_TRUE; 
     863            break; 
     864 
    828865#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0) 
    829866        case OPT_USE_SRTP: 
     
    34673504    app_config.cfg.cb.on_nat_detect = &on_nat_detect; 
    34683505 
     3506    /* Init TURN settings */ 
     3507#ifdef TURN_SERVER 
     3508    if (app_config.use_turn) { 
     3509        app_config.cfg.turn_host = pj_str(TURN_SERVER); 
     3510        app_config.cfg.turn_port = TURN_PORT; 
     3511        app_config.cfg.turn_tcp = 0; 
     3512        app_config.cfg.turn_cred.type = PJ_STUN_AUTH_CRED_STATIC; 
     3513        app_config.cfg.turn_cred.data.static_cred.realm = pj_str(TURN_REALM); 
     3514        app_config.cfg.turn_cred.data.static_cred.username = pj_str(TURN_USER); 
     3515        app_config.cfg.turn_cred.data.static_cred.data_type = PJ_STUN_PASSWD_PLAIN; 
     3516        app_config.cfg.turn_cred.data.static_cred.data = pj_str(TURN_PASSWD); 
     3517    } 
     3518#endif 
     3519 
    34693520    /* Initialize pjsua */ 
    34703521    status = pjsua_init(&app_config.cfg, &app_config.log_cfg, 
  • pjproject/branches/projects/ice-turn07/pjsip/include/pjsua-lib/pjsua.h

    r1912 r1926  
    10441044 
    10451045    /** 
    1046      * Specify STUN relay server to be used. 
    1047      */ 
    1048     pj_str_t        stun_relay_host; 
     1046     * Specify TURN server to be used. 
     1047     */ 
     1048    pj_str_t        turn_host; 
     1049 
     1050    /** 
     1051     * Specify TURN server port number. 
     1052     */ 
     1053    pj_uint16_t     turn_port; 
     1054 
     1055    /** 
     1056     * Specify if TCP connection to TURN server should be used. 
     1057     */ 
     1058    pj_bool_t       turn_tcp; 
     1059 
     1060    /** 
     1061     * Specify STUN credential for the TURN connection. 
     1062     */ 
     1063    pj_stun_auth_cred turn_cred; 
    10491064 
    10501065    /** 
     
    38873902 
    38883903    /** 
    3889      * Enable ICE media relay. 
    3890      */ 
    3891     pj_bool_t           enable_relay; 
     3904     * ICE options. 
     3905     */ 
     3906    unsigned            ice_options; 
     3907 
     3908    /** 
     3909     * Disable RTCP in ICE. 
     3910     */ 
     3911    pj_bool_t           ice_no_rtcp; 
    38923912}; 
    38933913 
  • pjproject/branches/projects/ice-turn07/pjsip/src/pjsua-lib/pjsua_core.c

    r1898 r1926  
    114114    pj_strdup_with_null(pool, &dst->stun_domain, &src->stun_domain); 
    115115    pj_strdup_with_null(pool, &dst->stun_host, &src->stun_host); 
    116     pj_strdup_with_null(pool, &dst->stun_relay_host, &src->stun_relay_host); 
     116    pj_strdup_with_null(pool, &dst->turn_host, &src->turn_host); 
     117    pj_stun_auth_cred_dup(pool, &dst->turn_cred, &src->turn_cred); 
    117118} 
    118119 
  • pjproject/branches/projects/ice-turn07/pjsip/src/pjsua-lib/pjsua_media.c

    r1898 r1926  
    625625    unsigned i; 
    626626    pj_sockaddr_in addr; 
     627    pj_ice_strans_cfg ice_cfg; 
    627628    pj_status_t status; 
    628629 
     
    635636 
    636637    pj_sockaddr_in_init(&addr, 0, (pj_uint16_t)cfg->port); 
     638 
     639    /* Init ICE config */ 
     640    pj_bzero(&ice_cfg, sizeof(ice_cfg)); 
     641 
     642    /* Duplicate STUN config */ 
     643    pj_memcpy(&ice_cfg.stun_cfg, &pjsua_var.stun_cfg, sizeof(pj_stun_config)); 
     644 
     645    /* Set STUN server, if any */ 
     646    if (pj_sockaddr_has_addr(&pjsua_var.stun_srv)) 
     647        pj_sockaddr_cp(&ice_cfg.stun_srv, &pjsua_var.stun_srv); 
     648 
     649    if (pjsua_var.ua_cfg.turn_host.slen) { 
     650        /* Set TURN server. 
     651         * TODO: DNS SRV 
     652         */ 
     653        status = pj_sockaddr_in_init(&ice_cfg.turn_srv.ipv4,  
     654                                     &pjsua_var.ua_cfg.turn_host, 
     655                                     pjsua_var.ua_cfg.turn_port); 
     656        if (status != PJ_SUCCESS) { 
     657            pjsua_perror(THIS_FILE, "Error resolving TURN server", status); 
     658            return status; 
     659        } 
     660 
     661        /* Copy TURN credential */ 
     662        pj_memcpy(&ice_cfg.turn_cred, &pjsua_var.ua_cfg.turn_cred, 
     663                  sizeof(pjsua_var.ua_cfg.turn_cred)); 
     664 
     665        /* TURN connection type. */ 
     666        if (pjsua_var.ua_cfg.turn_tcp) 
     667            ice_cfg.turn_conn_type = PJ_TURN_TP_TCP; 
     668        else 
     669            ice_cfg.turn_conn_type = PJ_TURN_TP_UDP; 
     670    } 
    637671 
    638672    /* Create each media transport */ 
     
    642676        int next_port; 
    643677        char name[32]; 
    644 #if PJMEDIA_ADVERTISE_RTCP 
    645         enum { COMP_CNT=2 }; 
     678        unsigned options, comp_cnt; 
     679 
     680#if PJMEDIA_ADVERTISE_RTCP==0 
     681        comp_cnt = 1; 
    646682#else 
    647         enum { COMP_CNT=1 }; 
     683        if (pjsua_var.media_cfg.ice_no_rtcp) 
     684            comp_cnt = 1; 
     685        else 
     686            comp_cnt = 2; 
    648687#endif 
     688 
     689        options = pjsua_var.media_cfg.ice_options; 
    649690 
    650691        pj_bzero(&ice_cb, sizeof(pjmedia_ice_cb)); 
     
    653694        pj_ansi_snprintf(name, sizeof(name), "icetp%02d", i); 
    654695                          
    655         status = pjmedia_ice_create(pjsua_var.med_endpt, name, COMP_CNT, 
    656                                     &pjsua_var.stun_cfg, &ice_cb, 
     696        status = pjmedia_ice_create(pjsua_var.med_endpt, name, comp_cnt, 
     697                                    &ice_cfg, &ice_cb, 
    657698                                    &pjsua_var.calls[i].med_tp); 
    658699        if (status != PJ_SUCCESS) { 
     
    670711                                        pjsua_var.media_cfg.rx_drop_pct); 
    671712 
    672         status = pjmedia_ice_start_init(pjsua_var.calls[i].med_tp, 0, &addr, 
    673                                         &pjsua_var.stun_srv.ipv4, NULL); 
     713        status = pjmedia_ice_start_init(pjsua_var.calls[i].med_tp, options,  
     714                                        &addr); 
    674715        if (status != PJ_SUCCESS) { 
    675716            pjsua_perror(THIS_FILE, "Error starting ICE transport", 
Note: See TracChangeset for help on using the changeset viewer.