Ignore:
Timestamp:
Mar 10, 2007 11:15:36 PM (18 years ago)
Author:
bennylp
Message:

Completed and tested (simple test) the TURN server and command line STUN/TURN client

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib-util/src/pjstun-srv-test/turn_usage.c

    r1053 r1054  
    5050                                         unsigned src_addr_len); 
    5151 
     52static pj_status_t handle_binding_req(pj_stun_session *session, 
     53                                      const pj_stun_msg *msg, 
     54                                      const pj_sockaddr_t *src_addr, 
     55                                      unsigned src_addr_len); 
     56 
    5257static pj_status_t client_create(struct turn_usage *tu, 
    5358                                 const pj_sockaddr_t *src_addr, 
     
    9196    pj_mutex_t          *mutex; 
    9297 
     98    pj_sockaddr_in       client_src_addr; 
     99 
    93100    /* Socket and socket address of the allocated port */ 
    94101    int                  sock_type; 
    95102    pj_sock_t            sock; 
    96103    pj_ioqueue_key_t    *key; 
    97     pj_sockaddr_in       client_addr; 
     104    pj_sockaddr_in       alloc_addr; 
    98105 
    99106    /* Allocation properties */ 
     
    150157    pj_status_t status; 
    151158 
    152     PJ_ASSERT_RETURN(srv && (type==PJ_SOCK_DGRAM||type==PJ_SOCK_STREAM) && 
    153                      p_bu, PJ_EINVAL); 
     159    PJ_ASSERT_RETURN(srv && (type==PJ_SOCK_DGRAM||type==PJ_SOCK_STREAM), 
     160                     PJ_EINVAL); 
    154161    si = pj_stun_server_get_info(srv); 
    155162 
     
    160167    tu->pf = si->pf; 
    161168    tu->endpt = si->endpt; 
     169    tu->ioqueue = si->ioqueue; 
    162170    tu->timer_heap = si->timer_heap; 
    163171    tu->next_port = START_PORT; 
     172    tu->max_bw_kbps = 64; 
     173    tu->max_lifetime = 10 * 60; 
    164174 
    165175    status = pj_sockaddr_in_init(&local_addr, ip_addr, (pj_uint16_t)port); 
     
    206216    } 
    207217 
    208     *p_bu = tu->usage; 
     218    if (p_bu) { 
     219        *p_bu = tu->usage; 
     220    } 
    209221 
    210222    return PJ_SUCCESS; 
     
    224236 
    225237    /* Destroy all clients */ 
    226     it = pj_hash_first(tu->client_htable, &hit); 
    227     while (it) { 
    228         struct turn_client *client; 
    229  
    230         client = (struct turn_client *)pj_hash_this(tu->client_htable, it); 
    231         client_destroy(client, PJ_SUCCESS); 
    232  
    233         it = pj_hash_next(tu->client_htable, it); 
     238    if (tu->client_htable) { 
     239        it = pj_hash_first(tu->client_htable, &hit); 
     240        while (it) { 
     241            struct turn_client *client; 
     242 
     243            client = (struct turn_client *)pj_hash_this(tu->client_htable, it); 
     244            client_destroy(client, PJ_SUCCESS); 
     245 
     246            it = pj_hash_first(tu->client_htable, &hit); 
     247        } 
    234248    } 
    235249 
     
    392406        } 
    393407 
     408        *p_sock = sock; 
    394409        return PJ_SUCCESS; 
    395410    } 
     
    420435    pj_assert(sd->client == NULL); 
    421436 
    422     if (msg->hdr.type != PJ_STUN_ALLOCATE_REQUEST) { 
     437    if (msg->hdr.type == PJ_STUN_BINDING_REQUEST) { 
     438        return handle_binding_req(sess, msg, src_addr, src_addr_len); 
     439 
     440    } else if (msg->hdr.type != PJ_STUN_ALLOCATE_REQUEST) { 
    423441        if (PJ_STUN_IS_REQUEST(msg->hdr.type)) { 
    424442            status = pj_stun_session_create_response(sess, msg,  
     
    506524static const char *get_tp_type(int type) 
    507525{ 
    508     if (type==0) 
     526    if (type==PJ_SOCK_DGRAM) 
    509527        return "udp"; 
    510     else if (type==1) 
     528    else if (type==PJ_SOCK_STREAM) 
    511529        return "tcp"; 
    512530    else 
     
    520538 * the packet is handed over to the client. 
    521539 */ 
    522 static pj_status_t client_sess_on_rx_request(pj_stun_session *sess, 
    523                                              const pj_uint8_t *pkt, 
    524                                              unsigned pkt_len, 
    525                                              const pj_stun_msg *msg, 
    526                                              const pj_sockaddr_t *src_addr, 
    527                                              unsigned src_addr_len) 
     540static pj_status_t client_sess_on_rx_msg(pj_stun_session *sess, 
     541                                         const pj_uint8_t *pkt, 
     542                                         unsigned pkt_len, 
     543                                         const pj_stun_msg *msg, 
     544                                         const pj_sockaddr_t *src_addr, 
     545                                         unsigned src_addr_len) 
    528546{ 
    529547    struct session_data *sd; 
     
    577595    pj_status_t status; 
    578596 
     597    PJ_ASSERT_RETURN(src_addr_len==sizeof(pj_sockaddr_in), PJ_EINVAL); 
     598 
    579599    pool = pj_pool_create(tu->pf, "turnc%p", 4000, 4000, NULL); 
    580600    client = PJ_POOL_ZALLOC_T(pool, struct turn_client); 
     
    582602    client->tu = tu; 
    583603    client->sock = PJ_INVALID_SOCKET; 
     604 
     605    pj_memcpy(&client->client_src_addr, src_addr, 
     606              sizeof(client->client_src_addr)); 
    584607 
    585608    if (src_addr) { 
     
    596619    pj_bzero(&sess_cb, sizeof(sess_cb)); 
    597620    sess_cb.on_send_msg = &client_sess_on_send_msg; 
    598     sess_cb.on_rx_request = &client_sess_on_rx_request; 
     621    sess_cb.on_rx_request = &client_sess_on_rx_msg; 
     622    sess_cb.on_rx_indication = &client_sess_on_rx_msg; 
    599623    status = pj_stun_session_create(tu->endpt, client->obj_name,  
    600624                                    &sess_cb, PJ_FALSE, 
     
    668692    pj_mutex_lock(tu->mutex); 
    669693    pj_hash_set(NULL, tu->client_htable,  
    670                 &client->client_addr, sizeof(client->client_addr), 0, NULL); 
     694                &client->client_src_addr, sizeof(client->client_src_addr),  
     695                0, NULL); 
    671696    pj_mutex_unlock(tu->mutex); 
    672697 
     
    710735    /* Update address */ 
    711736    addrlen = sizeof(pj_sockaddr_in); 
    712     status = pj_sock_getsockname(client->sock, &client->client_addr,  
     737    status = pj_sock_getsockname(client->sock, &client->alloc_addr,  
    713738                                 &addrlen); 
    714739    if (status != PJ_SUCCESS) { 
     
    716741        client->sock = PJ_INVALID_SOCKET; 
    717742        return status; 
     743    } 
     744 
     745    if (client->alloc_addr.sin_addr.s_addr == 0) { 
     746        status = pj_gethostip(&client->alloc_addr.sin_addr); 
     747        if (status != PJ_SUCCESS) { 
     748            pj_sock_close(client->sock); 
     749            client->sock = PJ_INVALID_SOCKET; 
     750            return status; 
     751        } 
    718752    } 
    719753 
     
    741775              client->obj_name, 
    742776              get_tp_type(client->sock_type), 
    743               pj_inet_ntoa(client->client_addr.sin_addr), 
    744               (int)pj_ntohs(client->client_addr.sin_port))); 
     777              pj_inet_ntoa(client->alloc_addr.sin_addr), 
     778              (int)pj_ntohs(client->alloc_addr.sin_port))); 
    745779 
    746780    return PJ_SUCCESS; 
     
    767801              client->obj_name, 
    768802              get_tp_type(client->sock_type), 
    769               pj_inet_ntoa(client->client_addr.sin_addr), 
    770               (int)pj_ntohs(client->client_addr.sin_port))); 
     803              pj_inet_ntoa(client->alloc_addr.sin_addr), 
     804              (int)pj_ntohs(client->alloc_addr.sin_port))); 
    771805    return PJ_SUCCESS; 
    772806} 
     
    796830    peer = PJ_POOL_ZALLOC_T(client->pool, struct peer); 
    797831    peer->client = client; 
    798     pj_memcpy(&peer->addr, peer_addr, sizeof(*peer_addr)); 
     832    pj_memcpy(&peer->addr, peer_addr, sizeof(peer->addr)); 
    799833 
    800834    pj_hash_set(client->pool, client->peer_htable, 
    801                 peer_addr, sizeof(*peer_addr), hval, peer); 
     835                &peer->addr, sizeof(peer->addr), hval, peer); 
    802836 
    803837    PJ_LOG(4,(THIS_FILE, "TURN client %s: peer %s:%s:%d added", 
    804838              client->obj_name, get_tp_type(client->sock_type),  
    805               pj_inet_ntoa(peer_addr->sin_addr), 
    806               (int)pj_ntohs(peer_addr->sin_port))); 
     839              pj_inet_ntoa(peer->addr.sin_addr), 
     840              (int)pj_ntohs(peer->addr.sin_port))); 
    807841 
    808842    return peer; 
     
    9761010    timeout.msec = 0; 
    9771011    pj_timer_heap_schedule(client->tu->timer_heap, &client->expiry_timer, &timeout); 
    978  
     1012    client->expiry_timer.id = PJ_TRUE; 
    9791013 
    9801014    /* Done successfully, create and send success response */ 
     
    9891023    pj_stun_msg_add_uint_attr(response->pool, response->msg, 
    9901024                              PJ_STUN_ATTR_LIFETIME, client->lifetime); 
    991     pj_stun_msg_add_ip_addr_attr(response->pool, response->msg, 
     1025    pj_stun_msg_add_sockaddr_attr(response->pool, response->msg, 
    9921026                                 PJ_STUN_ATTR_MAPPED_ADDR, PJ_FALSE, 
    9931027                                 src_addr, src_addr_len); 
    994     pj_stun_msg_add_ip_addr_attr(response->pool, response->msg, 
     1028    pj_stun_msg_add_sockaddr_attr(response->pool, response->msg, 
    9951029                                 PJ_STUN_ATTR_XOR_MAPPED_ADDR, PJ_TRUE, 
    9961030                                 src_addr, src_addr_len); 
     
    9981032    addr_len = sizeof(req_addr); 
    9991033    pj_sock_getsockname(client->sock, &req_addr, &addr_len); 
    1000     pj_stun_msg_add_ip_addr_attr(response->pool, response->msg, 
     1034    pj_stun_msg_add_sockaddr_attr(response->pool, response->msg, 
    10011035                                 PJ_STUN_ATTR_RELAY_ADDR, PJ_FALSE, 
    1002                                  &req_addr, addr_len); 
     1036                                 &client->alloc_addr, addr_len); 
    10031037 
    10041038    PJ_LOG(4,(THIS_FILE, "TURN client %s: relay allocated or refreshed, " 
     
    10111045    return pj_stun_session_send_msg(client->session, PJ_TRUE,  
    10121046                                    src_addr, src_addr_len, response); 
     1047} 
     1048 
     1049 
     1050/* 
     1051 * Handle incoming Binding request. 
     1052 * This function is called by client_handle_stun_msg() below. 
     1053 */ 
     1054static pj_status_t handle_binding_req(pj_stun_session *session, 
     1055                                      const pj_stun_msg *msg, 
     1056                                      const pj_sockaddr_t *src_addr, 
     1057                                      unsigned src_addr_len) 
     1058{ 
     1059    pj_stun_tx_data *tdata; 
     1060    pj_status_t status; 
     1061 
     1062    /* Create response */ 
     1063    status = pj_stun_session_create_response(session, msg, 0, NULL,  
     1064                                             &tdata); 
     1065    if (status != PJ_SUCCESS) 
     1066        return status; 
     1067 
     1068    /* Create MAPPED-ADDRESS attribute */ 
     1069    pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg, 
     1070                                 PJ_STUN_ATTR_MAPPED_ADDR, 
     1071                                PJ_FALSE, 
     1072                                src_addr, src_addr_len); 
     1073 
     1074    /* On the presence of magic, create XOR-MAPPED-ADDRESS attribute */ 
     1075    if (msg->hdr.magic == PJ_STUN_MAGIC) { 
     1076        status =  
     1077            pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg, 
     1078                                         PJ_STUN_ATTR_XOR_MAPPED_ADDR, 
     1079                                         PJ_TRUE, 
     1080                                         src_addr, src_addr_len); 
     1081    } 
     1082 
     1083    /* Send */ 
     1084    status = pj_stun_session_send_msg(session, PJ_TRUE,  
     1085                                      src_addr, src_addr_len, tdata); 
     1086    return status; 
    10131087} 
    10141088 
     
    10591133    } 
    10601134 
    1061     PJ_LOG(4,(THIS_FILE, "TURN client %s: active destination set to %s:%d", 
    1062                          client->obj_name, 
    1063                          pj_inet_ntoa(client->active_peer->addr.sin_addr), 
    1064                          (int)pj_ntohs(client->active_peer->addr.sin_port))); 
     1135    if (client->active_peer) { 
     1136        PJ_LOG(4,(THIS_FILE,  
     1137                  "TURN client %s: active destination set to %s:%d", 
     1138                  client->obj_name, 
     1139                  pj_inet_ntoa(client->active_peer->addr.sin_addr), 
     1140                  (int)pj_ntohs(client->active_peer->addr.sin_port))); 
     1141    } else { 
     1142        PJ_LOG(4,(THIS_FILE, "TURN client %s: active destination cleared", 
     1143                  client->obj_name)); 
     1144    } 
    10651145 
    10661146    /* Respond with successful response */ 
     
    11631243    case PJ_STUN_SEND_INDICATION: 
    11641244        status = client_handle_send_ind(client, msg); 
     1245        break; 
    11651246 
    11661247    case PJ_STUN_SET_ACTIVE_DESTINATION_REQUEST: 
    11671248        status = client_handle_sad(client, msg, 
    11681249                                   src_addr, src_addr_len); 
     1250        break; 
     1251 
    11691252    case PJ_STUN_ALLOCATE_REQUEST: 
    11701253        status = client_handle_allocate_req(client, msg, 
    11711254                                            src_addr, src_addr_len); 
     1255        break; 
     1256 
     1257    case PJ_STUN_BINDING_REQUEST: 
     1258        status = handle_binding_req(client->session, msg, 
     1259                                    src_addr, src_addr_len); 
     1260        break; 
    11721261 
    11731262    default: 
    11741263        status = client_handle_unknown_msg(client, msg, 
    11751264                                           src_addr, src_addr_len); 
     1265        break; 
    11761266    } 
    11771267 
     
    12041294    if (peer == NULL) { 
    12051295        /* Nope. Discard packet */ 
     1296        PJ_LOG(5,(THIS_FILE,  
     1297                 "TURN client %s: discarded data from %s:%d", 
     1298                 client->obj_name, 
     1299                 pj_inet_ntoa(client->pkt_src_addr.sin_addr), 
     1300                 (int)pj_ntohs(client->pkt_src_addr.sin_port))); 
    12061301        return; 
    12071302    } 
     
    12261321            return; 
    12271322 
    1228         pj_stun_msg_add_ip_addr_attr(data_ind->pool, data_ind->msg,  
    1229                                      PJ_STUN_ATTR_REMOTE_ADDR, PJ_FALSE, 
    1230                                      &client->pkt_src_addr, 
    1231                                      client->pkt_src_addr_len); 
     1323        pj_stun_msg_add_sockaddr_attr(data_ind->pool, data_ind->msg,  
     1324                                      PJ_STUN_ATTR_REMOTE_ADDR, PJ_FALSE, 
     1325                                      &client->pkt_src_addr, 
     1326                                      client->pkt_src_addr_len); 
    12321327        pj_stun_msg_add_binary_attr(data_ind->pool, data_ind->msg, 
    12331328                                    PJ_STUN_ATTR_DATA,  
Note: See TracChangeset for help on using the changeset viewer.