Ignore:
Timestamp:
Mar 23, 2007 7:09:54 PM (17 years ago)
Author:
bennylp
Message:

ICE (work in progress): implemented server reflexive candidate

File:
1 edited

Legend:

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

    r1098 r1099  
    4848static void destroy_ice_st(pj_ice_st *ice_st, pj_status_t reason); 
    4949 
     50/* STUN session callback */ 
     51static pj_status_t stun_on_send_msg(pj_stun_session *sess, 
     52                                    const void *pkt, 
     53                                    pj_size_t pkt_size, 
     54                                    const pj_sockaddr_t *dst_addr, 
     55                                    unsigned addr_len); 
     56static void stun_on_request_complete(pj_stun_session *sess, 
     57                                     pj_status_t status, 
     58                                     pj_stun_tx_data *tdata, 
     59                                     const pj_stun_msg *response); 
     60 
     61/* Utility: print error */ 
    5062static void ice_st_perror(pj_ice_st *ice_st, const char *title,  
    5163                          pj_status_t status) 
     
    161173    pj_ice_st_interface *is = (pj_ice_st_interface*)  
    162174                              pj_ioqueue_get_user_data(key); 
     175    pj_ice_st *ice_st = is->ice_st; 
    163176    pj_ssize_t pkt_size; 
    164177    pj_status_t status; 
     
    169182         * packets to the ICE session. Otherwise just drop the packet. 
    170183         */ 
    171         if (is->ice_st->ice) { 
    172             status = pj_ice_on_rx_pkt(is->ice_st->ice,  
     184        if (ice_st->ice) { 
     185            status = pj_ice_on_rx_pkt(ice_st->ice,  
    173186                                      is->comp_id, is->cand_id, 
    174187                                      is->pkt, bytes_read, 
    175188                                      &is->src_addr, is->src_addr_len); 
     189        } else if (is->stun_sess) { 
     190            status = pj_stun_msg_check(is->pkt, bytes_read, PJ_STUN_IS_DATAGRAM); 
     191            if (status == PJ_SUCCESS) { 
     192                status = pj_stun_session_on_rx_pkt(is->stun_sess, is->pkt,  
     193                                                   bytes_read,  
     194                                                   PJ_STUN_IS_DATAGRAM, NULL, 
     195                                                   &is->src_addr,  
     196                                                   is->src_addr_len); 
     197            } else { 
     198                (*ice_st->cb.on_rx_data)(ice_st, is->comp_id, is->cand_id,  
     199                                         is->pkt, bytes_read,  
     200                                         &is->src_addr, is->src_addr_len); 
     201 
     202            } 
     203        } else { 
     204            (*ice_st->cb.on_rx_data)(ice_st, is->comp_id, is->cand_id,  
     205                                     is->pkt, bytes_read,  
     206                                     &is->src_addr, is->src_addr_len); 
    176207        } 
    177208 
     
    196227static void destroy_ice_interface(pj_ice_st_interface *is) 
    197228{ 
     229    if (is->stun_sess) { 
     230        pj_stun_session_destroy(is->stun_sess); 
     231        is->stun_sess = NULL; 
     232    } 
     233 
    198234    if (is->key) { 
    199235        pj_ioqueue_unregister(is->key); 
     
    345381/* Add interface */ 
    346382static void add_interface(pj_ice_st *ice_st, pj_ice_st_interface *is, 
    347                           unsigned *p_itf_id, pj_bool_t notify, 
    348                           void *notify_data) 
     383                          unsigned *p_itf_id) 
    349384{ 
    350385    unsigned itf_id; 
     
    355390    if (p_itf_id) 
    356391        *p_itf_id = itf_id; 
    357  
    358     if (notify && ice_st->cb.on_interface_status) { 
    359         (*ice_st->cb.on_interface_status)(ice_st, notify_data,  
    360                                           PJ_SUCCESS, itf_id); 
    361     } 
    362392} 
    363393 
     
    369399                                                 pj_uint16_t local_pref, 
    370400                                                 const pj_sockaddr_in *addr, 
    371                                                  unsigned *p_itf_id, 
    372                                                  pj_bool_t notify, 
    373                                                  void *notify_data) 
     401                                                 unsigned *p_itf_id) 
    374402{ 
    375403    pj_ice_st_interface *is; 
     
    395423 
    396424    /* Store this interface */ 
    397     add_interface(ice_st, is, p_itf_id, notify, notify_data); 
     425    add_interface(ice_st, is, p_itf_id); 
    398426 
    399427    /* Set interface status to SUCCESS */ 
     
    408436PJ_DEF(pj_status_t) pj_ice_st_add_all_host_interfaces(pj_ice_st *ice_st, 
    409437                                                      unsigned comp_id, 
    410                                                       unsigned port, 
    411                                                       pj_bool_t notify, 
    412                                                       void *notify_data) 
     438                                                      unsigned port) 
    413439{ 
    414440    pj_sockaddr_in addr; 
     
    424450        return status; 
    425451 
    426     return pj_ice_st_add_host_interface(ice_st, comp_id, 65535, &addr,  
    427                                         NULL, notify, notify_data); 
     452    return pj_ice_st_add_host_interface(ice_st, comp_id, 65535, &addr, NULL); 
    428453} 
    429454 
     
    434459                                                 unsigned comp_id, 
    435460                                                 unsigned local_port, 
    436                                                  pj_bool_t notify, 
    437                                                  void *notify_data) 
    438 { 
    439     /* Yeah, TODO */ 
    440     PJ_UNUSED_ARG(ice_st); 
    441     PJ_UNUSED_ARG(comp_id); 
    442     PJ_UNUSED_ARG(local_port); 
    443     PJ_UNUSED_ARG(notify); 
    444     PJ_UNUSED_ARG(notify_data); 
    445     return -1; 
     461                                                 unsigned *p_itf_id) 
     462{ 
     463    pj_ice_st_interface *is; 
     464    pj_sockaddr_in local_addr; 
     465    pj_stun_session_cb sess_cb; 
     466    pj_stun_tx_data *tdata; 
     467    pj_status_t status; 
     468 
     469    PJ_ASSERT_RETURN(ice_st && comp_id, PJ_EINVAL); 
     470     
     471    /* STUN server must have been configured */ 
     472    PJ_ASSERT_RETURN(ice_st->stun_srv.sin_family != 0, PJ_EINVALIDOP); 
     473 
     474 
     475    /* Create interface */ 
     476    pj_sockaddr_in_init(&local_addr, NULL, (pj_uint16_t)local_port); 
     477    status = create_ice_interface(ice_st, PJ_ICE_CAND_TYPE_SRFLX, comp_id, 
     478                                  65535, &local_addr, &is); 
     479    if (status != PJ_SUCCESS) 
     480        return status; 
     481 
     482    /* Create STUN session */ 
     483    pj_bzero(&sess_cb, sizeof(sess_cb)); 
     484    sess_cb.on_request_complete = &stun_on_request_complete; 
     485    sess_cb.on_send_msg = &stun_on_send_msg; 
     486    status = pj_stun_session_create(&ice_st->stun_cfg, ice_st->obj_name, 
     487                                    &sess_cb, PJ_FALSE, &is->stun_sess); 
     488    if (status != PJ_SUCCESS) 
     489        goto on_error; 
     490 
     491    /* Associate interface with STUN session */ 
     492    pj_stun_session_set_user_data(is->stun_sess, (void*)is); 
     493 
     494    /* Create and send STUN binding request */ 
     495    status = pj_stun_session_create_req(is->stun_sess,  
     496                                        PJ_STUN_BINDING_REQUEST, &tdata); 
     497    if (status != PJ_SUCCESS) 
     498        goto on_error; 
     499 
     500    status = pj_stun_session_send_msg(is->stun_sess, PJ_FALSE,  
     501                                      &ice_st->stun_srv,  
     502                                      sizeof(pj_sockaddr_in), tdata); 
     503    if (status != PJ_SUCCESS) 
     504        goto on_error; 
     505 
     506    /* Mark interface as pending */ 
     507    is->status = PJ_EPENDING; 
     508 
     509    add_interface(ice_st, is, p_itf_id); 
     510 
     511    return PJ_SUCCESS; 
     512 
     513on_error: 
     514    destroy_ice_interface(is); 
     515    return status; 
    446516} 
    447517 
     
    625695 
    626696/* 
     697 * Send packet using non-ICE means (e.g. when ICE was not negotiated). 
     698 */ 
     699PJ_DEF(pj_status_t) pj_ice_st_sendto( pj_ice_st *ice_st, 
     700                                      unsigned comp_id, 
     701                                      unsigned itf_id, 
     702                                      const void *data, 
     703                                      pj_size_t data_len, 
     704                                      const pj_sockaddr_t *dst_addr, 
     705                                      int dst_addr_len) 
     706{ 
     707    pj_ssize_t pkt_size; 
     708    pj_ice_st_interface *is = ice_st->itfs[itf_id]; 
     709    pj_status_t status; 
     710 
     711    pkt_size = data_len; 
     712    status = pj_ioqueue_sendto(is->key, &is->write_op,  
     713                               data, &pkt_size, 0, 
     714                               dst_addr, dst_addr_len); 
     715     
     716    return (status==PJ_SUCCESS||status==PJ_EPENDING) ? PJ_SUCCESS : status; 
     717} 
     718 
     719/* 
    627720 * Callback called by ICE session when ICE processing is complete, either 
    628721 * successfully or with failure. 
     
    688781} 
    689782 
    690  
     783/* 
     784 * Callback called by STUN session to send outgoing packet. 
     785 */ 
     786static pj_status_t stun_on_send_msg(pj_stun_session *sess, 
     787                                    const void *pkt, 
     788                                    pj_size_t size, 
     789                                    const pj_sockaddr_t *dst_addr, 
     790                                    unsigned dst_addr_len) 
     791{ 
     792    pj_ice_st_interface *is; 
     793    pj_ssize_t pkt_size; 
     794    pj_status_t status; 
     795 
     796    is = (pj_ice_st_interface*) pj_stun_session_get_user_data(sess); 
     797    pkt_size = size; 
     798    status = pj_ioqueue_sendto(is->key, &is->write_op,  
     799                               pkt, &pkt_size, 0, 
     800                               dst_addr, dst_addr_len); 
     801     
     802    return (status==PJ_SUCCESS||status==PJ_EPENDING) ? PJ_SUCCESS : status; 
     803} 
     804 
     805/* 
     806 * Callback sent by STUN session when outgoing STUN request has 
     807 * completed. 
     808 */ 
     809static void stun_on_request_complete(pj_stun_session *sess, 
     810                                     pj_status_t status, 
     811                                     pj_stun_tx_data *tdata, 
     812                                     const pj_stun_msg *response) 
     813{ 
     814    pj_ice_st_interface *is; 
     815    pj_stun_xor_mapped_addr_attr *xa; 
     816    pj_stun_mapped_addr_attr *ma; 
     817    pj_sockaddr *mapped_addr; 
     818 
     819    PJ_UNUSED_ARG(tdata); 
     820 
     821    is = (pj_ice_st_interface*) pj_stun_session_get_user_data(sess); 
     822    if (status != PJ_SUCCESS) { 
     823        is->status = status; 
     824        ice_st_perror(is->ice_st, "STUN Binding request failed", is->status); 
     825        return; 
     826    } 
     827 
     828    xa = (pj_stun_xor_mapped_addr_attr*) 
     829         pj_stun_msg_find_attr(response, PJ_STUN_ATTR_XOR_MAPPED_ADDR, 0); 
     830    ma = (pj_stun_mapped_addr_attr*) 
     831         pj_stun_msg_find_attr(response, PJ_STUN_ATTR_MAPPED_ADDR, 0); 
     832 
     833    if (xa) 
     834        mapped_addr = &xa->sockaddr; 
     835    else if (ma) 
     836        mapped_addr = &ma->sockaddr; 
     837    else { 
     838        is->status = PJNATH_ESTUNNOMAPPEDADDR; 
     839        ice_st_perror(is->ice_st, "STUN Binding request failed", is->status); 
     840        return; 
     841    } 
     842 
     843    PJ_LOG(4,(is->ice_st->obj_name,  
     844              "STUN mapped address: %s:%d", 
     845              pj_inet_ntoa(mapped_addr->ipv4.sin_addr), 
     846              (int)pj_ntohs(mapped_addr->ipv4.sin_port))); 
     847    pj_memcpy(&is->addr, mapped_addr, sizeof(pj_sockaddr_in)); 
     848    is->status = PJ_SUCCESS; 
     849 
     850} 
     851 
Note: See TracChangeset for help on using the changeset viewer.