Ignore:
Timestamp:
Dec 3, 2007 2:38:25 PM (12 years ago)
Author:
bennylp
Message:

Ticket #420: updated pjmedia SDP and media UDP transport to support IPv6

File:
1 edited

Legend:

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

    r1607 r1615  
    5252    void               *user_data;      /**< Only valid when attached       */ 
    5353    pj_bool_t           attached;       /**< Has attachment?                */ 
    54     pj_sockaddr_in      rem_rtp_addr;   /**< Remote RTP address             */ 
    55     pj_sockaddr_in      rem_rtcp_addr;  /**< Remote RTCP address            */ 
     54    pj_sockaddr         rem_rtp_addr;   /**< Remote RTP address             */ 
     55    pj_sockaddr         rem_rtcp_addr;  /**< Remote RTCP address            */ 
     56    int                 addr_len;       /**< Length of addresses.           */ 
    5657    void  (*rtp_cb)(    void*,          /**< To report incoming RTP.        */ 
    5758                        const void*, 
     
    6566 
    6667    pj_sock_t           rtp_sock;       /**< RTP socket                     */ 
    67     pj_sockaddr_in      rtp_addr_name;  /**< Published RTP address.         */ 
     68    pj_sockaddr         rtp_addr_name;  /**< Published RTP address.         */ 
    6869    pj_ioqueue_key_t   *rtp_key;        /**< RTP socket key in ioqueue      */ 
    6970    pj_ioqueue_op_key_t rtp_read_op;    /**< Pending read operation         */ 
    7071    unsigned            rtp_write_op_id;/**< Next write_op to use           */ 
    7172    pending_write       rtp_pending_write[MAX_PENDING];  /**< Pending write */ 
    72     pj_sockaddr_in      rtp_src_addr;   /**< Actual packet src addr.        */ 
     73    pj_sockaddr         rtp_src_addr;   /**< Actual packet src addr.        */ 
    7374    unsigned            rtp_src_cnt;    /**< How many pkt from this addr.   */ 
    7475    int                 rtp_addrlen;    /**< Address length.                */ 
     
    7677 
    7778    pj_sock_t           rtcp_sock;      /**< RTCP socket                    */ 
    78     pj_sockaddr_in      rtcp_addr_name; /**< Published RTCP address.        */ 
    79     pj_sockaddr_in      rtcp_src_addr;  /**< Actual source RTCP address.    */ 
     79    pj_sockaddr         rtcp_addr_name; /**< Published RTCP address.        */ 
     80    pj_sockaddr         rtcp_src_addr;  /**< Actual source RTCP address.    */ 
    8081    int                 rtcp_addr_len;  /**< Length of RTCP src address.    */ 
    8182    pj_ioqueue_key_t   *rtcp_key;       /**< RTCP socket key in ioqueue     */ 
     
    151152                                                  pjmedia_transport **p_tp) 
    152153{ 
     154    return pjmedia_transport_udp_create3(endpt, pj_AF_INET(), name, 
     155                                         addr, port, options, p_tp); 
     156} 
     157 
     158/** 
     159 * Create UDP stream transport. 
     160 */ 
     161PJ_DEF(pj_status_t) pjmedia_transport_udp_create3(pjmedia_endpt *endpt, 
     162                                                  int af, 
     163                                                  const char *name, 
     164                                                  const pj_str_t *addr, 
     165                                                  int port, 
     166                                                  unsigned options, 
     167                                                  pjmedia_transport **p_tp) 
     168{ 
    153169    pjmedia_sock_info si; 
    154170    pj_status_t status; 
     
    163179 
    164180    /* Create RTP socket */ 
    165     status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &si.rtp_sock); 
     181    status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &si.rtp_sock); 
    166182    if (status != PJ_SUCCESS) 
    167183        goto on_error; 
    168184 
    169185    /* Bind RTP socket */ 
    170     pj_sockaddr_in_init(&si.rtp_addr_name, addr, (pj_uint16_t)port); 
     186    status = pj_sockaddr_init(af, &si.rtp_addr_name, addr, (pj_uint16_t)port); 
     187    if (status != PJ_SUCCESS) 
     188        goto on_error; 
     189 
    171190    status = pj_sock_bind(si.rtp_sock, &si.rtp_addr_name,  
    172191                          sizeof(si.rtp_addr_name)); 
     
    176195 
    177196    /* Create RTCP socket */ 
    178     status = pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &si.rtcp_sock); 
     197    status = pj_sock_socket(af, pj_SOCK_DGRAM(), 0, &si.rtcp_sock); 
    179198    if (status != PJ_SUCCESS) 
    180199        goto on_error; 
    181200 
    182201    /* Bind RTCP socket */ 
    183     pj_sockaddr_in_init(&si.rtcp_addr_name, addr, (pj_uint16_t)(port+1)); 
     202    status = pj_sockaddr_init(af, &si.rtcp_addr_name, addr,  
     203                              (pj_uint16_t)(port+1)); 
     204    if (status != PJ_SUCCESS) 
     205        goto on_error; 
     206 
    184207    status = pj_sock_bind(si.rtcp_sock, &si.rtcp_addr_name, 
    185208                          sizeof(si.rtcp_addr_name)); 
     
    222245    PJ_ASSERT_RETURN(endpt && si && p_tp, PJ_EINVAL); 
    223246 
    224     /* Check name */ 
    225     if (!name) 
    226         name = "udpmedia"; 
    227  
    228247    /* Get ioqueue instance */ 
    229248    ioqueue = pjmedia_endpt_get_ioqueue(endpt); 
    230  
    231249 
    232250    /* Create transport structure */ 
     
    235253        return PJ_ENOMEM; 
    236254 
     255    if (!name) 
     256        name = pool->obj_name; 
     257 
    237258    tp = PJ_POOL_ZALLOC_T(pool, struct transport_udp); 
    238259    tp->pool = pool; 
    239260    tp->options = options; 
    240     pj_ansi_strcpy(tp->base.name, name); 
     261    pj_ansi_strncpy(tp->base.name, name, PJ_MAX_OBJ_NAME-1); 
    241262    tp->base.op = &transport_udp_op; 
    242263    tp->base.type = PJMEDIA_TRANSPORT_TYPE_UDP; 
     
    249270 
    250271    /* If address is 0.0.0.0, use host's IP address */ 
    251     if (tp->rtp_addr_name.sin_addr.s_addr == 0) { 
     272    if (!pj_sockaddr_has_addr(&tp->rtp_addr_name)) { 
    252273        pj_sockaddr hostip; 
    253274 
    254         status = pj_gethostip(pj_AF_INET(), &hostip); 
     275        status = pj_gethostip(tp->rtp_addr_name.addr.sa_family, &hostip); 
    255276        if (status != PJ_SUCCESS) 
    256277            goto on_error; 
    257278 
    258         tp->rtp_addr_name.sin_addr.s_addr = hostip.ipv4.sin_addr.s_addr; 
     279        pj_memcpy(pj_sockaddr_get_addr(&tp->rtp_addr_name),  
     280                  pj_sockaddr_get_addr(&hostip), 
     281                  pj_sockaddr_get_addr_len(&hostip)); 
    259282    } 
    260283 
    261284    /* Same with RTCP */ 
    262     if (tp->rtcp_addr_name.sin_addr.s_addr == 0) { 
    263         tp->rtcp_addr_name.sin_addr.s_addr = tp->rtp_addr_name.sin_addr.s_addr; 
     285    if (!pj_sockaddr_has_addr(&tp->rtcp_addr_name)) { 
     286        pj_memcpy(pj_sockaddr_get_addr(&tp->rtcp_addr_name), 
     287                  pj_sockaddr_get_addr(&tp->rtp_addr_name), 
     288                  pj_sockaddr_get_addr_len(&tp->rtp_addr_name)); 
    264289    } 
    265290 
     
    349374        pj_ioqueue_unregister(udp->rtp_key); 
    350375        udp->rtp_key = NULL; 
     376        udp->rtp_sock = PJ_INVALID_SOCKET; 
    351377    } else if (udp->rtp_sock != PJ_INVALID_SOCKET) { 
    352378        pj_sock_close(udp->rtp_sock); 
     
    357383        pj_ioqueue_unregister(udp->rtcp_key); 
    358384        udp->rtcp_key = NULL; 
     385        udp->rtcp_sock = PJ_INVALID_SOCKET; 
    359386    } else if (udp->rtcp_sock != PJ_INVALID_SOCKET) { 
    360387        pj_sock_close(udp->rtcp_sock); 
     
    409436            (udp->options & PJMEDIA_UDP_NO_SRC_ADDR_CHECKING)==0)  
    410437        { 
    411             if ((udp->rem_rtp_addr.sin_addr.s_addr !=  
    412                  udp->rtp_src_addr.sin_addr.s_addr) || 
    413                 (udp->rem_rtp_addr.sin_port !=  
    414                  udp->rtp_src_addr.sin_port)) 
    415             { 
     438            if (pj_sockaddr_cmp(&udp->rem_rtp_addr, &udp->rtp_src_addr) != 0) { 
     439 
    416440                udp->rtp_src_cnt++; 
    417441 
    418442                if (udp->rtp_src_cnt >= PJMEDIA_RTP_NAT_PROBATION_CNT) { 
    419443                 
     444                    char addr_text[80]; 
     445 
    420446                    /* Set remote RTP address to source address */ 
    421                     udp->rem_rtp_addr = udp->rtp_src_addr; 
     447                    pj_memcpy(&udp->rem_rtp_addr, &udp->rtp_src_addr, 
     448                              sizeof(pj_sockaddr)); 
    422449 
    423450                    /* Reset counter */ 
     
    425452 
    426453                    PJ_LOG(4,(udp->base.name, 
    427                               "Remote RTP address switched to %s:%d", 
    428                               pj_inet_ntoa(udp->rtp_src_addr.sin_addr), 
    429                               pj_ntohs(udp->rtp_src_addr.sin_port))); 
     454                              "Remote RTP address switched to %s", 
     455                              pj_sockaddr_print(&udp->rtp_src_addr, addr_text, 
     456                                                sizeof(addr_text), 3))); 
    430457 
    431458                    /* Also update remote RTCP address if actual RTCP source 
    432459                     * address is not heard yet. 
    433460                     */ 
    434                     if (udp->rtcp_src_addr.sin_addr.s_addr == 0) { 
     461                    if (!pj_sockaddr_has_addr(&udp->rtcp_src_addr)) { 
    435462                        pj_uint16_t port; 
    436463 
    437464                        pj_memcpy(&udp->rem_rtcp_addr, &udp->rem_rtp_addr,  
    438                                   sizeof(pj_sockaddr_in)); 
     465                                  sizeof(pj_sockaddr)); 
     466                        pj_sockaddr_copy_addr(&udp->rem_rtcp_addr, 
     467                                              &udp->rem_rtp_addr); 
    439468                        port = (pj_uint16_t) 
    440                                (pj_ntohs(udp->rem_rtp_addr.sin_port)+1); 
    441                         udp->rem_rtcp_addr.sin_port = pj_htons(port); 
     469                               (pj_sockaddr_get_port(&udp->rem_rtp_addr)+1); 
     470                        pj_sockaddr_set_port(&udp->rem_rtcp_addr, port); 
    442471 
    443472                        pj_memcpy(&udp->rtcp_src_addr, &udp->rem_rtcp_addr,  
    444                                   sizeof(pj_sockaddr_in)); 
     473                                  sizeof(pj_sockaddr)); 
    445474 
    446475                        PJ_LOG(4,(udp->base.name, 
    447                                   "Remote RTCP address switched to %s:%d", 
    448                                   pj_inet_ntoa(udp->rtcp_src_addr.sin_addr), 
    449                                   pj_ntohs(udp->rtcp_src_addr.sin_port))); 
     476                                  "Remote RTCP address switched to %s", 
     477                                  pj_sockaddr_print(&udp->rtcp_src_addr,  
     478                                                    addr_text, 
     479                                                    sizeof(addr_text), 3))); 
    450480 
    451481                    } 
     
    456486read_next_packet: 
    457487        bytes_read = sizeof(udp->rtp_pkt); 
    458         udp->rtp_addrlen = sizeof(pj_sockaddr_in); 
     488        udp->rtp_addrlen = sizeof(udp->rtp_src_addr); 
    459489        status = pj_ioqueue_recvfrom(udp->rtp_key, &udp->rtp_read_op, 
    460490                                     udp->rtp_pkt, &bytes_read, 0, 
     
    497527        if (bytes_read>0 && 
    498528            (udp->options & PJMEDIA_UDP_NO_SRC_ADDR_CHECKING)==0 && 
    499             ((udp->rem_rtcp_addr.sin_addr.s_addr !=  
    500                udp->rtcp_src_addr.sin_addr.s_addr) || 
    501              (udp->rem_rtcp_addr.sin_port !=  
    502                udp->rtcp_src_addr.sin_port))) 
     529            pj_sockaddr_cmp(&udp->rem_rtcp_addr, &udp->rtcp_src_addr) != 0) 
    503530        { 
     531            char addr_text[80]; 
     532 
    504533            pj_memcpy(&udp->rem_rtcp_addr, &udp->rtcp_src_addr, 
    505                       sizeof(pj_sockaddr_in)); 
     534                      sizeof(pj_sockaddr)); 
     535 
    506536            PJ_LOG(4,(udp->base.name, 
    507                       "Remote RTCP address switched to %s:%d", 
    508                       pj_inet_ntoa(udp->rtcp_src_addr.sin_addr), 
    509                       pj_ntohs(udp->rtcp_src_addr.sin_port))); 
     537                      "Remote RTCP address switched to %s", 
     538                      pj_sockaddr_print(&udp->rtcp_src_addr, addr_text, 
     539                                        sizeof(addr_text), 3))); 
    510540        } 
    511541 
     
    553583{ 
    554584    struct transport_udp *udp = (struct transport_udp*) tp; 
    555     const pj_sockaddr_in *rtcp_addr; 
     585    const pj_sockaddr *rtcp_addr; 
    556586 
    557587    /* Validate arguments */ 
     
    564594 
    565595    /* Copy remote RTP address */ 
    566     pj_memcpy(&udp->rem_rtp_addr, rem_addr, sizeof(pj_sockaddr_in)); 
     596    pj_memcpy(&udp->rem_rtp_addr, rem_addr, addr_len); 
    567597 
    568598    /* Copy remote RTP address, if one is specified. */ 
    569     rtcp_addr = (const pj_sockaddr_in*) rem_rtcp; 
    570     if (rtcp_addr && rtcp_addr->sin_addr.s_addr != 0) { 
    571         pj_memcpy(&udp->rem_rtcp_addr, rem_rtcp, sizeof(pj_sockaddr_in)); 
     599    rtcp_addr = (const pj_sockaddr*) rem_rtcp; 
     600    if (rtcp_addr && pj_sockaddr_has_addr(rtcp_addr)) { 
     601        pj_memcpy(&udp->rem_rtcp_addr, rem_rtcp, addr_len); 
    572602 
    573603    } else { 
    574         int rtcp_port; 
     604        unsigned rtcp_port; 
    575605 
    576606        /* Otherwise guess the RTCP address from the RTP address */ 
    577         pj_memcpy(&udp->rem_rtcp_addr, rem_addr, sizeof(pj_sockaddr_in)); 
    578         rtcp_port = pj_ntohs(udp->rem_rtp_addr.sin_port) + 1; 
    579         udp->rem_rtcp_addr.sin_port = pj_htons((pj_uint16_t)rtcp_port); 
     607        pj_memcpy(&udp->rem_rtcp_addr, rem_addr, addr_len); 
     608        rtcp_port = pj_sockaddr_get_port(&udp->rem_rtp_addr) + 1; 
     609        pj_sockaddr_set_port(&udp->rem_rtcp_addr, (pj_uint16_t)rtcp_port); 
    580610    } 
    581611 
     
    584614    udp->rtcp_cb = rtcp_cb; 
    585615    udp->user_data = user_data; 
     616 
     617    /* Save address length */ 
     618    udp->addr_len = addr_len; 
    586619 
    587620    /* Last, mark transport as attached */ 
     
    660693                                pw->buffer, &sent, 0, 
    661694                                &udp->rem_rtp_addr,  
    662                                 sizeof(pj_sockaddr_in)); 
     695                                udp->addr_len); 
    663696 
    664697    udp->rtp_write_op_id = (udp->rtp_write_op_id + 1) % 
     
    685718    status = pj_ioqueue_sendto( udp->rtcp_key, &udp->rtcp_write_op, 
    686719                                pkt, &sent, 0, 
    687                                 &udp->rem_rtcp_addr, sizeof(pj_sockaddr_in)); 
     720                                &udp->rem_rtcp_addr, udp->addr_len); 
    688721 
    689722    if (status==PJ_SUCCESS || status==PJ_EPENDING) 
Note: See TracChangeset for help on using the changeset viewer.