Changeset 1141


Ignore:
Timestamp:
Apr 3, 2007 7:15:10 PM (12 years ago)
Author:
bennylp
Message:

Added ICE-CONTROLLED and ICE-CONTROLLING attribute, handle ICE 487 error, and add response source address checking

Location:
pjproject/trunk/pjnath
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjnath/include/pjnath/errno.h

    r1110 r1141  
    145145/** 
    146146 * @hideinitializer 
     147 * Source address mismatch. This error occurs if the source address 
     148 * of the response for ICE connectivity check is different than 
     149 * the destination address of the request. 
     150 */ 
     151#define PJNATH_EICEINSRCADDR        (PJNATH_ERRNO_START+88) /* 370088 */ 
     152/** 
     153 * @hideinitializer 
    147154 * Missing ICE SDP attribute 
    148155 */ 
  • pjproject/trunk/pjnath/include/pjnath/ice_session.h

    r1140 r1141  
    401401typedef enum pj_ice_sess_role 
    402402{ 
     403    /** 
     404     * The ICE agent is in controlled role. 
     405     */ 
     406    PJ_ICE_SESS_ROLE_UNKNOWN, 
     407 
    403408    /** 
    404409     * The ICE agent is in controlled role. 
  • pjproject/trunk/pjnath/include/pjnath/stun_session.h

    r1140 r1141  
    110110     *                      or other error has occurred, and the response 
    111111     *                      argument may be NULL. 
     112     *                      Note that when the status is not success, the 
     113     *                      response may contain non-NULL value if the  
     114     *                      response contains STUN ERROR-CODE attribute. 
    112115     * @param request       The original STUN request. 
    113      * @param response      The response message, on successful transaction. 
     116     * @param response      The response message, on successful transaction, 
     117     *                      or otherwise MAY BE NULL if status is not success. 
     118     *                      Note that when the status is not success, this 
     119     *                      argument may contain non-NULL value if the  
     120     *                      response contains STUN ERROR-CODE attribute. 
     121     * @param src_addr      The source address where the response was  
     122     *                      received, or NULL if the response is NULL. 
     123     * @param src_addr_len  The length of the source  address. 
    114124     */ 
    115125    void (*on_request_complete)(pj_stun_session *sess, 
    116126                                pj_status_t status, 
    117127                                pj_stun_tx_data *tdata, 
    118                                 const pj_stun_msg *response); 
     128                                const pj_stun_msg *response, 
     129                                const pj_sockaddr_t *src_addr, 
     130                                unsigned src_addr_len); 
    119131 
    120132 
  • pjproject/trunk/pjnath/include/pjnath/stun_transaction.h

    r1140 r1141  
    7171     * @param response      The STUN response, which value may be NULL if 
    7272     *                      \a status is not PJ_SUCCESS. 
     73     * @param src_addr      The source address of the response, if response  
     74     *                      is not NULL. 
     75     * @param src_addr_len  The length of the source address. 
    7376     */ 
    7477    void        (*on_complete)(pj_stun_client_tsx *tsx, 
    7578                               pj_status_t status,  
    76                                const pj_stun_msg *response); 
     79                               const pj_stun_msg *response, 
     80                               const pj_sockaddr_t *src_addr, 
     81                               unsigned src_addr_len); 
    7782 
    7883    /** 
     
    229234 * @param tsx           The STUN client transaction instance. 
    230235 * @param msg           The incoming STUN message. 
     236 * @param src_addr      The source address of the packet. 
     237 * @param src_addr_len  The length of the source address. 
    231238 * 
    232239 * @return              PJ_SUCCESS on success or the appropriate error code. 
    233240 */ 
    234241PJ_DECL(pj_status_t) pj_stun_client_tsx_on_rx_msg(pj_stun_client_tsx *tsx, 
    235                                                   const pj_stun_msg *msg); 
     242                                                  const pj_stun_msg *msg, 
     243                                                  const pj_sockaddr_t*src_addr, 
     244                                                  unsigned src_addr_len); 
    236245 
    237246 
  • pjproject/trunk/pjnath/src/pjnath/errno.c

    r1126 r1141  
    5757    PJ_BUILD_ERR( PJNATH_EICEINCOMPID,      "Invalid ICE component ID"), 
    5858    PJ_BUILD_ERR( PJNATH_EICEINCANDID,      "Invalid ICE candidate ID"), 
     59    PJ_BUILD_ERR( PJNATH_EICEINSRCADDR,     "Source address mismatch"), 
    5960    PJ_BUILD_ERR( PJNATH_EICEMISSINGSDP,    "Missing ICE SDP attribute"), 
    6061    PJ_BUILD_ERR( PJNATH_EICEINCANDSDP,     "Invalid SDP \"candidate\" attribute"), 
  • pjproject/trunk/pjnath/src/pjnath/ice_session.c

    r1140 r1141  
    116116                                     pj_status_t status, 
    117117                                     pj_stun_tx_data *tdata, 
    118                                      const pj_stun_msg *response); 
     118                                     const pj_stun_msg *response, 
     119                                     const pj_sockaddr_t *src_addr, 
     120                                     unsigned src_addr_len); 
    119121static pj_status_t on_stun_rx_indication(pj_stun_session *sess, 
    120122                                         const pj_uint8_t *pkt, 
     
    12071209                              PJ_STUN_ATTR_PRIORITY, prio); 
    12081210 
    1209     /* Add USE-CANDIDATE and set this check to nominated */ 
     1211    /* Add USE-CANDIDATE and set this check to nominated. 
     1212     * Also add ICE-CONTROLLING or ICE-CONTROLLED 
     1213     */ 
    12101214    if (ice->role == PJ_ICE_SESS_ROLE_CONTROLLING) { 
    12111215        pj_stun_msg_add_empty_attr(check->tdata->pool, check->tdata->msg,  
    12121216                                   PJ_STUN_ATTR_USE_CANDIDATE); 
    12131217        check->nominated = PJ_TRUE; 
    1214     } 
     1218 
     1219        pj_stun_msg_add_uint64_attr(check->tdata->pool, check->tdata->msg,  
     1220                                    PJ_STUN_ATTR_ICE_CONTROLLING, 
     1221                                    &ice->tie_breaker); 
     1222 
     1223    } else { 
     1224        pj_stun_msg_add_uint64_attr(check->tdata->pool, check->tdata->msg,  
     1225                                    PJ_STUN_ATTR_ICE_CONTROLLED, 
     1226                                    &ice->tie_breaker); 
     1227    } 
     1228 
    12151229 
    12161230    /* Note that USERNAME and MESSAGE-INTEGRITY will be added by the  
     
    14291443                                     pj_status_t status, 
    14301444                                     pj_stun_tx_data *tdata, 
    1431                                      const pj_stun_msg *response) 
     1445                                     const pj_stun_msg *response, 
     1446                                     const pj_sockaddr_t *src_addr, 
     1447                                     unsigned src_addr_len) 
    14321448{ 
    14331449    struct req_data *rd = (struct req_data*) tdata->user_data; 
     
    14411457 
    14421458    PJ_UNUSED_ARG(stun_sess); 
     1459    PJ_UNUSED_ARG(src_addr_len); 
    14431460 
    14441461    ice = rd->ice; 
     
    14571474    lcand = NULL; 
    14581475 
    1459     LOG4((ice->obj_name,  
    1460          "Check %s%s: connectivity check %s", 
    1461          dump_check(buffer, sizeof(buffer), &ice->clist, check), 
    1462          (check->nominated ? " (nominated)" : " (not nominated)"), 
    1463          (status==PJ_SUCCESS ? "SUCCESS" : "FAILED"))); 
    1464  
    14651476    if (status != PJ_SUCCESS) { 
     1477        char errmsg[PJ_ERR_MSG_SIZE]; 
     1478 
     1479        if (status==PJ_STATUS_FROM_STUN_CODE(PJ_STUN_SC_ROLE_CONFLICT)) { 
     1480            /* Role conclict response. 
     1481             * 7.1.2.1.  Failure Cases: 
     1482             * If the request had contained the ICE-CONTROLLED attribute,  
     1483             * the agent MUST switch to the controlling role if it has not 
     1484             * already done so.  If the request had contained the  
     1485             * ICE-CONTROLLING attribute, the agent MUST switch to the  
     1486             * controlled role if it has not already done so.  Once it has 
     1487             * switched, the agent MUST immediately retry the request with 
     1488             * the ICE-CONTROLLING or ICE-CONTROLLED attribute reflecting  
     1489             * its new role. 
     1490             */ 
     1491            pj_ice_sess_role new_role = PJ_ICE_SESS_ROLE_UNKNOWN; 
     1492            pj_stun_msg *req = tdata->msg; 
     1493 
     1494            if (pj_stun_msg_find_attr(req, PJ_STUN_ATTR_ICE_CONTROLLING, 0)) { 
     1495                new_role = PJ_ICE_SESS_ROLE_CONTROLLED; 
     1496            } else if (pj_stun_msg_find_attr(req, PJ_STUN_ATTR_ICE_CONTROLLED,  
     1497                                             0)) { 
     1498                new_role = PJ_ICE_SESS_ROLE_CONTROLLING; 
     1499            } else { 
     1500                pj_assert(!"We should have put CONTROLLING/CONTROLLED attr!"); 
     1501                new_role = PJ_ICE_SESS_ROLE_CONTROLLED; 
     1502            } 
     1503 
     1504            if (new_role != ice->role) { 
     1505                LOG4((ice->obj_name,  
     1506                      "Changing role because of role conflict")); 
     1507                pj_ice_sess_change_role(ice, new_role); 
     1508            } 
     1509 
     1510            /* Resend request */ 
     1511            LOG4((ice->obj_name, "Resending check because of role conflict")); 
     1512            check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_WAITING, 0); 
     1513            perform_check(ice, clist, rd->ckid); 
     1514            pj_mutex_unlock(ice->mutex); 
     1515            return; 
     1516        } 
     1517 
     1518        pj_strerror(status, errmsg, sizeof(errmsg)); 
     1519        LOG4((ice->obj_name,  
     1520             "Check %s%s: connectivity check FAILED: %s", 
     1521             dump_check(buffer, sizeof(buffer), &ice->clist, check), 
     1522             (check->nominated ? " (nominated)" : " (not nominated)"), 
     1523             errmsg)); 
     1524 
    14661525        check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_FAILED, status); 
    14671526        on_check_complete(ice, check); 
     
    14691528        return; 
    14701529    } 
     1530 
    14711531 
    14721532    /* The agent MUST check that the source IP address and port of the 
     
    14761536     * Request was sent from. 
    14771537     */ 
    1478     PJ_TODO(ICE_CHECK_RESPONSE_SOURCE_ADDRESS); 
     1538    if (sockaddr_cmp(&check->rcand->addr, src_addr) != 0) { 
     1539        status = PJNATH_EICEINSRCADDR; 
     1540        LOG4((ice->obj_name,  
     1541             "Check %s%s: connectivity check FAILED: source address mismatch", 
     1542             dump_check(buffer, sizeof(buffer), &ice->clist, check), 
     1543             (check->nominated ? " (nominated)" : " (not nominated)"))); 
     1544        check_set_state(ice, check, PJ_ICE_SESS_CHECK_STATE_FAILED, status); 
     1545        on_check_complete(ice, check); 
     1546        pj_mutex_unlock(ice->mutex); 
     1547        return; 
     1548    } 
     1549 
     1550    LOG4((ice->obj_name,  
     1551         "Check %s%s: connectivity check SUCCESS", 
     1552         dump_check(buffer, sizeof(buffer), &ice->clist, check), 
     1553         (check->nominated ? " (nominated)" : " (not nominated)"))); 
    14791554 
    14801555    /* Get the STUN XOR-MAPPED-ADDRESS attribute. */ 
  • pjproject/trunk/pjnath/src/pjnath/ice_strans.c

    r1140 r1141  
    6767                                     pj_status_t status, 
    6868                                     pj_stun_tx_data *tdata, 
    69                                      const pj_stun_msg *response); 
     69                                     const pj_stun_msg *response, 
     70                                     const pj_sockaddr_t *src_addr, 
     71                                     unsigned src_addr_len); 
    7072 
    7173/* Keep-alive timer */ 
     
    10461048                                     pj_status_t status, 
    10471049                                     pj_stun_tx_data *tdata, 
    1048                                      const pj_stun_msg *response) 
     1050                                     const pj_stun_msg *response, 
     1051                                     const pj_sockaddr_t *src_addr, 
     1052                                     unsigned src_addr_len) 
    10491053{ 
    10501054    pj_ice_strans_comp *comp; 
     
    10561060    comp = (pj_ice_strans_comp*) pj_stun_session_get_user_data(sess); 
    10571061    cand = (pj_ice_strans_cand*) tdata->user_data; 
     1062 
     1063    PJ_UNUSED_ARG(src_addr); 
     1064    PJ_UNUSED_ARG(src_addr_len); 
    10581065 
    10591066    if (cand == NULL) { 
  • pjproject/trunk/pjnath/src/pjnath/stun_msg.c

    r1131 r1141  
    10961096 
    10971097    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_uint64_attr); 
    1098     INIT_ATTR(attr, attr_type, 4); 
     1098    INIT_ATTR(attr, attr_type, 8); 
    10991099 
    11001100    if (value) { 
     
    11551155 
    11561156    PUTVAL16H(buf, 0, ca->hdr.type); 
    1157     PUTVAL16H(buf, 2, ca->hdr.length); 
     1157    PUTVAL16H(buf, 2, (pj_uint16_t)8); 
    11581158    PUTVAL64H(buf, 4, &ca->value); 
    11591159 
  • pjproject/trunk/pjnath/src/pjnath/stun_session.c

    r1140 r1141  
    5252static void stun_tsx_on_complete(pj_stun_client_tsx *tsx, 
    5353                                 pj_status_t status,  
    54                                  const pj_stun_msg *response); 
     54                                 const pj_stun_msg *response, 
     55                                 const pj_sockaddr_t *src_addr, 
     56                                 unsigned src_addr_len); 
    5557static pj_status_t stun_tsx_on_send_msg(pj_stun_client_tsx *tsx, 
    5658                                        const void *stun_pkt, 
     
    326328static void stun_tsx_on_complete(pj_stun_client_tsx *tsx, 
    327329                                 pj_status_t status,  
    328                                  const pj_stun_msg *response) 
     330                                 const pj_stun_msg *response, 
     331                                 const pj_sockaddr_t *src_addr, 
     332                                 unsigned src_addr_len) 
    329333{ 
    330334    pj_stun_tx_data *tdata; 
     
    334338    if (tdata->sess->cb.on_request_complete) { 
    335339        (*tdata->sess->cb.on_request_complete)(tdata->sess, status, tdata,  
    336                                                response); 
     340                                               response,  
     341                                               src_addr, src_addr_len); 
    337342    } 
    338343} 
     
    697702 
    698703    if (notify) { 
    699         (sess->cb.on_request_complete)(sess, notify_status, tdata, NULL); 
     704        (sess->cb.on_request_complete)(sess, notify_status, tdata, NULL, 
     705                                       NULL, 0); 
    700706    } 
    701707 
     
    776782/* Handle incoming response */ 
    777783static pj_status_t on_incoming_response(pj_stun_session *sess, 
    778                                         pj_stun_msg *msg) 
     784                                        pj_stun_msg *msg, 
     785                                        const pj_sockaddr_t *src_addr, 
     786                                        unsigned src_addr_len) 
    779787{ 
    780788    pj_stun_tx_data *tdata; 
     
    793801     * and this will call the session callback too. 
    794802     */ 
    795     status = pj_stun_client_tsx_on_rx_msg(tdata->client_tsx, msg); 
     803    status = pj_stun_client_tsx_on_rx_msg(tdata->client_tsx, msg,  
     804                                          src_addr, src_addr_len); 
    796805    if (status != PJ_SUCCESS) { 
    797806        return status; 
     
    959968        PJ_STUN_IS_ERROR_RESPONSE(msg->hdr.type)) 
    960969    { 
    961         status = on_incoming_response(sess, msg); 
     970        status = on_incoming_response(sess, msg, src_addr, src_addr_len); 
    962971 
    963972    } else if (PJ_STUN_IS_REQUEST(msg->hdr.type)) { 
  • pjproject/trunk/pjnath/src/pjnath/stun_transaction.c

    r1140 r1141  
    276276            tsx->complete = PJ_TRUE; 
    277277            if (tsx->cb.on_complete) { 
    278                 tsx->cb.on_complete(tsx, PJNATH_ESTUNTIMEDOUT, NULL); 
     278                tsx->cb.on_complete(tsx, PJNATH_ESTUNTIMEDOUT, NULL, NULL, 0); 
    279279            } 
    280280        } 
     
    289289            tsx->complete = PJ_TRUE; 
    290290            if (tsx->cb.on_complete) { 
    291                 tsx->cb.on_complete(tsx, status, NULL); 
     291                tsx->cb.on_complete(tsx, status, NULL, NULL, 0); 
    292292            } 
    293293        } 
     
    314314 */ 
    315315PJ_DEF(pj_status_t) pj_stun_client_tsx_on_rx_msg(pj_stun_client_tsx *tsx, 
    316                                                  const pj_stun_msg *msg) 
     316                                                 const pj_stun_msg *msg, 
     317                                                 const pj_sockaddr_t *src_addr, 
     318                                                 unsigned src_addr_len) 
    317319{ 
    318320    pj_stun_errcode_attr *err_attr; 
     
    364366        tsx->complete = PJ_TRUE; 
    365367        if (tsx->cb.on_complete) { 
    366             tsx->cb.on_complete(tsx, status, msg); 
    367         } 
    368     } 
    369  
    370     return PJ_SUCCESS; 
    371  
    372 } 
    373  
     368            tsx->cb.on_complete(tsx, status, msg, src_addr, src_addr_len); 
     369        } 
     370    } 
     371 
     372    return PJ_SUCCESS; 
     373 
     374} 
     375 
Note: See TracChangeset for help on using the changeset viewer.