Changeset 2040 for pjproject


Ignore:
Timestamp:
Jun 21, 2008 10:18:49 AM (16 years ago)
Author:
bennylp
Message:

Peers use STUN mapped address instead of local address in TURN client sample

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjnath/src/pjturn-client/client_main.c

    r1988 r2040  
    3636struct peer 
    3737{ 
    38     pj_sock_t   sock; 
    39     pj_sockaddr addr; 
     38    pj_stun_sock   *stun_sock; 
     39    pj_sockaddr     mapped_addr; 
    4040}; 
    4141 
     
    6464    char        *password; 
    6565    pj_bool_t    use_fingerprint; 
     66    char        *stun_server; 
    6667} o; 
    6768 
     
    7576static void turn_on_state(pj_turn_sock *relay, pj_turn_state_t old_state, 
    7677                          pj_turn_state_t new_state); 
     78static pj_bool_t stun_sock_on_status(pj_stun_sock *stun_sock,  
     79                                     pj_stun_sock_op op, 
     80                                     pj_status_t status); 
     81static pj_bool_t stun_sock_on_rx_data(pj_stun_sock *stun_sock, 
     82                                      void *pkt, 
     83                                      unsigned pkt_len, 
     84                                      const pj_sockaddr_t *src_addr, 
     85                                      unsigned addr_len); 
    7786 
    7887 
     
    123132     */ 
    124133    for (i=0; i<(int)PJ_ARRAY_SIZE(g.peer); ++i) { 
    125         int len; 
    126         pj_sockaddr addr; 
    127         pj_uint16_t port; 
    128  
    129         CHECK( pj_sock_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, &g.peer[i].sock) ); 
    130         CHECK( pj_sock_bind_in(g.peer[i].sock, 0, 0) ); 
    131  
    132         len = sizeof(addr); 
    133         CHECK( pj_sock_getsockname(g.peer[i].sock, &addr, &len) ); 
    134         port = pj_sockaddr_get_port(&addr); 
    135  
    136         CHECK( pj_gethostip(pj_AF_INET(), &g.peer[i].addr) ); 
    137         pj_sockaddr_set_port(&g.peer[i].addr, port); 
    138  
     134        pj_stun_sock_cb stun_sock_cb; 
     135        char name[] = "peer0"; 
     136        pj_str_t server; 
     137 
     138        pj_bzero(&stun_sock_cb, sizeof(stun_sock_cb)); 
     139        stun_sock_cb.on_rx_data = &stun_sock_on_rx_data; 
     140        stun_sock_cb.on_status = &stun_sock_on_status; 
     141 
     142        g.peer[i].mapped_addr.addr.sa_family = pj_AF_INET(); 
     143 
     144        name[strlen(name)-1] = '0'+i; 
     145        status = pj_stun_sock_create(&g.stun_config, name, pj_AF_INET(),  
     146                                     &stun_sock_cb, NULL, 
     147                                     &g.peer[i], &g.peer[i].stun_sock); 
     148        if (status != PJ_SUCCESS) { 
     149            my_perror("pj_stun_sock_create()", status); 
     150            return status; 
     151        } 
     152 
     153        if (o.stun_server) 
     154            server = pj_str(o.stun_server); 
     155        else 
     156            server = pj_str(o.srv_addr); 
     157        status = pj_stun_sock_start(g.peer[i].stun_sock, &server,  
     158                                    (pj_uint16_t)(o.srv_port?atoi(o.srv_port):PJ_STUN_PORT),  
     159                                    NULL); 
     160        if (status != PJ_SUCCESS) { 
     161            my_perror("pj_stun_sock_start()", status); 
     162            return status; 
     163        } 
    139164    } 
    140165 
     
    162187    } 
    163188    for (i=0; i<PJ_ARRAY_SIZE(g.peer); ++i) { 
    164         if (g.peer[i].sock) { 
    165             pj_sock_close(g.peer[i].sock); 
    166             g.peer[i].sock = 0; 
     189        if (g.peer[i].stun_sock) { 
     190            pj_stun_sock_destroy(g.peer[i].stun_sock); 
     191            g.peer[i].stun_sock = NULL; 
    167192        } 
    168193    } 
     
    192217    while (!g.quit) { 
    193218        const pj_time_val delay = {0, 10}; 
    194         int i, n=0; 
    195         pj_fd_set_t readset; 
    196219 
    197220        /* Poll ioqueue for the TURN client */ 
     
    201224        pj_timer_heap_poll(g.stun_config.timer_heap, NULL); 
    202225 
    203         /* Poll peer sockets */ 
    204         PJ_FD_ZERO(&readset); 
    205         for (i=0; i<(int)PJ_ARRAY_SIZE(g.peer); ++i) { 
    206             PJ_FD_SET(g.peer[i].sock, &readset); 
    207             if (g.peer[i].sock > n) 
    208                 n = g.peer[i].sock; 
    209         } 
    210  
    211         if (pj_sock_select(n+1, &readset, NULL, NULL, &delay) <= 0) 
    212             continue; 
    213  
    214         /* Handle incoming data on peer socket */ 
    215         for (i=0; i<(int)PJ_ARRAY_SIZE(g.peer); ++i) { 
    216             char buf[128]; 
    217             pj_ssize_t len; 
    218             pj_sockaddr src_addr; 
    219             int src_addr_len; 
    220             pj_status_t status; 
    221  
    222             if (!PJ_FD_ISSET(g.peer[i].sock, &readset)) 
    223                 continue; 
    224  
    225             len = sizeof(buf); 
    226             src_addr_len = sizeof(src_addr); 
    227  
    228             status = pj_sock_recvfrom(g.peer[i].sock, buf, &len, 0,  
    229                                       &src_addr, &src_addr_len); 
    230             if (status != PJ_SUCCESS) { 
    231                 my_perror("recvfrom error", status); 
    232             } else { 
    233                 char addrinfo[80]; 
    234                 pj_sockaddr_print(&src_addr, addrinfo, sizeof(addrinfo), 3); 
    235                 PJ_LOG(3,(THIS_FILE, "Peer%d received %d bytes from %s: %.*s", 
    236                           i, len, addrinfo, len, buf)); 
    237             } 
    238         } 
    239226    } 
    240227 
     
    325312} 
    326313 
     314static pj_bool_t stun_sock_on_status(pj_stun_sock *stun_sock,  
     315                                     pj_stun_sock_op op, 
     316                                     pj_status_t status) 
     317{ 
     318    struct peer *peer = (struct peer*) pj_stun_sock_get_user_data(stun_sock); 
     319 
     320    if (status == PJ_SUCCESS) { 
     321        PJ_LOG(4,(THIS_FILE, "peer%d: %s success", peer-g.peer, 
     322                  pj_stun_sock_op_name(op))); 
     323    } else { 
     324        char errmsg[PJ_ERR_MSG_SIZE]; 
     325        pj_strerror(status, errmsg, sizeof(errmsg)); 
     326        PJ_LOG(1,(THIS_FILE, "peer%d: %s error: %s", peer-g.peer, 
     327                  pj_stun_sock_op_name(op), errmsg)); 
     328        return PJ_FALSE; 
     329    } 
     330 
     331    if (op==PJ_STUN_SOCK_BINDING_OP || op==PJ_STUN_SOCK_KEEP_ALIVE_OP) { 
     332        pj_stun_sock_info info; 
     333        int cmp; 
     334 
     335        pj_stun_sock_get_info(stun_sock, &info); 
     336        cmp = pj_sockaddr_cmp(&info.mapped_addr, &peer->mapped_addr); 
     337 
     338        if (cmp) { 
     339            char straddr[PJ_INET6_ADDRSTRLEN+10]; 
     340 
     341            pj_sockaddr_cp(&peer->mapped_addr, &info.mapped_addr); 
     342            pj_sockaddr_print(&peer->mapped_addr, straddr, sizeof(straddr), 3); 
     343            PJ_LOG(3,(THIS_FILE, "peer%d: STUN mapped address is %s", 
     344                      peer-g.peer, straddr)); 
     345        } 
     346    } 
     347 
     348    return PJ_TRUE; 
     349} 
     350 
     351static pj_bool_t stun_sock_on_rx_data(pj_stun_sock *stun_sock, 
     352                                      void *pkt, 
     353                                      unsigned pkt_len, 
     354                                      const pj_sockaddr_t *src_addr, 
     355                                      unsigned addr_len) 
     356{ 
     357    struct peer *peer = (struct peer*) pj_stun_sock_get_user_data(stun_sock); 
     358    char straddr[PJ_INET6_ADDRSTRLEN+10]; 
     359 
     360    ((char*)pkt)[pkt_len] = '\0'; 
     361 
     362    pj_sockaddr_print(src_addr, straddr, sizeof(straddr), 3); 
     363    PJ_LOG(3,(THIS_FILE, "peer%d: received %d bytes data from %s: %s", 
     364              peer-g.peer, pkt_len, straddr, (char*)pkt)); 
     365 
     366    return PJ_TRUE; 
     367} 
     368 
     369 
    327370static void menu(void) 
    328371{ 
     
    342385    } 
    343386 
    344     pj_sockaddr_print(&g.peer[0].addr, peer0_addr, sizeof(peer0_addr), 3); 
    345     pj_sockaddr_print(&g.peer[1].addr, peer1_addr, sizeof(peer1_addr), 3); 
     387    pj_sockaddr_print(&g.peer[0].mapped_addr, peer0_addr, sizeof(peer0_addr), 3); 
     388    pj_sockaddr_print(&g.peer[1].mapped_addr, peer1_addr, sizeof(peer1_addr), 3); 
    346389 
    347390 
     
    373416        char input[32]; 
    374417        struct peer *peer; 
    375         pj_ssize_t len; 
    376418        pj_status_t status; 
    377419 
     
    400442            status = pj_turn_sock_sendto(g.relay, (const pj_uint8_t*)input,  
    401443                                        strlen(input)+1,  
    402                                         &peer->addr,  
    403                                         pj_sockaddr_get_len(&peer->addr)); 
     444                                        &peer->mapped_addr,  
     445                                        pj_sockaddr_get_len(&peer->mapped_addr)); 
    404446            if (status != PJ_SUCCESS) 
    405447                my_perror("turn_udp_sendto() failed", status); 
     
    415457                peer = &g.peer[1]; 
    416458 
    417             status = pj_turn_sock_bind_channel(g.relay, &peer->addr, 
    418                                               pj_sockaddr_get_len(&peer->addr)); 
     459            status = pj_turn_sock_bind_channel(g.relay, &peer->mapped_addr, 
     460                                              pj_sockaddr_get_len(&peer->mapped_addr)); 
    419461            if (status != PJ_SUCCESS) 
    420462                my_perror("turn_udp_bind_channel() failed", status); 
     
    435477            peer = &g.peer[input[0]-'0']; 
    436478            sprintf(input, "Hello from peer%d", input[0]-'0'); 
    437             len = strlen(input)+1; 
    438             pj_sock_sendto(peer->sock, input, &len, 0, &g.relay_addr,  
    439                            pj_sockaddr_get_len(&g.relay_addr)); 
     479            pj_stun_sock_sendto(peer->stun_sock, NULL, input, strlen(input)+1, 0, 
     480                                &g.relay_addr, pj_sockaddr_get_len(&g.relay_addr)); 
    440481            break; 
    441482        case 'q': 
     
    449490static void usage(void) 
    450491{ 
    451     puts("Usage: pjturn_client TARGET [OPTIONS]"); 
     492    puts("Usage: pjturn_client TURN-SERVER [OPTIONS]"); 
    452493    puts(""); 
    453     puts("where TARGET is \"host[:port]\""); 
     494    puts("where TURN-SERVER is \"host[:port]\""); 
    454495    puts(""); 
    455496    puts("and OPTIONS:"); 
     
    459500    puts(" --password, -p PASSWD Set password of the credential to PASSWD"); 
    460501    puts(" --fingerprint, -F     Use fingerprint for outgoing requests"); 
     502    puts(" --stun-srv, -S        Use this STUN srv instead of TURN for Binding discovery"); 
    461503    puts(" --help, -h"); 
    462504} 
     
    470512        { "fingerprint",0, 0, 'F'}, 
    471513        { "tcp",        0, 0, 'T'}, 
    472         { "help",       0, 0, 'h'} 
     514        { "help",       0, 0, 'h'}, 
     515        { "stun-srv",   1, 0, 'S'} 
    473516    }; 
    474517    int c, opt_id; 
     
    476519    pj_status_t status; 
    477520 
    478     while((c=pj_getopt_long(argc,argv, "r:u:p:N:hFT", long_options, &opt_id))!=-1) { 
     521    while((c=pj_getopt_long(argc,argv, "r:u:p:S:hFT", long_options, &opt_id))!=-1) { 
    479522        switch (c) { 
    480523        case 'r': 
     
    496539            o.use_tcp = PJ_TRUE; 
    497540            break; 
    498  
     541        case 'S': 
     542            o.stun_server = pj_optarg; 
     543            break; 
    499544        default: 
    500545            printf("Argument \"%s\" is not valid. Use -h to see help", 
Note: See TracChangeset for help on using the changeset viewer.