Ignore:
Timestamp:
Mar 10, 2007 11:15:36 PM (17 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-client/client_main.c

    r1053 r1054  
    2222 
    2323#define THIS_FILE       "client_main.c" 
     24#define LOCAL_PORT      1998 
    2425#define BANDWIDTH       64                  /* -1 to disable */ 
    25 #define LIFETIME        30                  /* -1 to disable */ 
     26#define LIFETIME        600                 /* -1 to disable */ 
    2627#define REQ_TRANSPORT   -1                  /* 0: udp, 1: tcp, -1: disable */ 
    2728#define REQ_PORT_PROPS  -1                  /* -1 to disable */ 
     
    4041    pj_bool_t            quit; 
    4142    pj_sockaddr_in       peer_addr; 
    42     pj_sockaddr_in       srv_addr;  /**< server addr */ 
    43  
     43    pj_sockaddr_in       srv_addr; 
     44    pj_sockaddr_in       relay_addr; 
     45    char                 data_buf[256]; 
     46    char                *data; 
    4447} g; 
    4548 
     
    5255    char    *password; 
    5356    char    *nonce; 
     57    char    *peer_addr; 
    5458    pj_bool_t use_fingerprint; 
    5559} o; 
     60 
     61 
     62static pj_status_t parse_addr(const char *input, pj_sockaddr_in *addr); 
    5663 
    5764 
     
    8895{ 
    8996    if (status == PJ_SUCCESS) { 
    90         puts("Client transaction completes"); 
     97        switch (response->hdr.type) { 
     98        case PJ_STUN_ALLOCATE_RESPONSE: 
     99            { 
     100                pj_stun_relay_addr_attr *ar; 
     101 
     102                ar = (pj_stun_relay_addr_attr*) 
     103                     pj_stun_msg_find_attr(response,  
     104                                           PJ_STUN_ATTR_RELAY_ADDR, 0); 
     105                if (ar) { 
     106                    pj_memcpy(&g.relay_addr, &ar->addr.ipv4, 
     107                              sizeof(pj_sockaddr_in)); 
     108                    PJ_LOG(3,(THIS_FILE, "Relay address is %s:%d", 
     109                              pj_inet_ntoa(g.relay_addr.sin_addr), 
     110                              (int)pj_ntohs(g.relay_addr.sin_port))); 
     111                } else { 
     112                    pj_memset(&g.relay_addr, 0, sizeof(g.relay_addr)); 
     113                } 
     114            } 
     115            break; 
     116        } 
    91117    } else { 
    92118        my_perror("Client transaction error", status); 
     
    120146                addrlen = sizeof(addr); 
    121147                rc = pj_sock_recvfrom(g.sock, buffer, &len, 0, &addr, &addrlen); 
    122                 if (rc == PJ_SUCCESS && len > 0) { 
     148                if (rc != PJ_SUCCESS || len <= 0) 
     149                    continue; 
     150 
     151                if (pj_stun_msg_check(buffer, len, PJ_STUN_IS_DATAGRAM)==PJ_SUCCESS) { 
    123152                    rc = pj_stun_session_on_rx_pkt(g.sess, buffer, len,  
    124                                                    PJ_STUN_IS_DATAGRAM|PJ_STUN_CHECK_PACKET,  
     153                                                   0,  
    125154                                                   NULL, &addr, addrlen); 
    126155                    if (rc != PJ_SUCCESS) 
    127156                        my_perror("Error processing packet", rc); 
     157 
     158                } else { 
     159                    buffer[len] = '\0'; 
     160                    PJ_LOG(3,(THIS_FILE, "Received data: %s", (char*)buffer)); 
    128161                } 
    129162            } 
     
    139172    pj_sockaddr_in addr; 
    140173    pj_stun_session_cb stun_cb; 
     174    int len; 
    141175    pj_status_t status; 
    142176 
     
    182216    status = pj_sockaddr_in_init(&addr, NULL, 0); 
    183217    pj_assert(status == PJ_SUCCESS); 
     218 
     219    addr.sin_port = pj_htons((pj_uint16_t)LOCAL_PORT); 
     220    status = pj_sock_bind(g.sock, &addr, sizeof(addr)); 
     221    pj_assert(status == PJ_SUCCESS); 
     222 
     223    len = sizeof(addr); 
     224    status = pj_sock_getsockname(g.sock, &addr, &len); 
     225    pj_assert(status == PJ_SUCCESS); 
     226 
     227    PJ_LOG(3,(THIS_FILE, "Listening on port %d", (int)pj_ntohs(addr.sin_port))); 
     228 
     229    pj_memcpy(&g.peer_addr, &addr, sizeof(pj_sockaddr_in)); 
     230    if (g.peer_addr.sin_addr.s_addr == 0) 
     231        pj_gethostip(&g.peer_addr.sin_addr); 
    184232 
    185233    pj_memset(&stun_cb, 0, sizeof(stun_cb)); 
     
    207255    } else { 
    208256        puts("Credential not set"); 
     257    } 
     258 
     259    if (o.peer_addr) { 
     260        if (parse_addr(o.peer_addr, &g.peer_addr)!=PJ_SUCCESS) 
     261            return -1; 
    209262    } 
    210263 
     
    297350 
    298351            pj_sockaddr_in_init(&addr, pj_cstr(&tmp, REQ_IP), 0); 
    299             pj_stun_msg_add_ip_addr_attr(tdata->pool, tdata->msg, 
     352            pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg, 
    300353                                         PJ_STUN_ATTR_REQ_IP, PJ_FALSE, 
    301354                                         &addr, sizeof(addr)); 
     
    321374    } 
    322375 
    323     rc = pj_stun_session_create_req(g.sess, PJ_STUN_ALLOCATE_REQUEST, &tdata); 
     376    rc = pj_stun_session_create_req(g.sess, PJ_STUN_SET_ACTIVE_DESTINATION_REQUEST, &tdata); 
    324377    pj_assert(rc == PJ_SUCCESS); 
    325378 
    326379    if (set) { 
    327         pj_stun_msg_add_ip_addr_attr(tdata->pool, tdata->msg, 
     380        pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg, 
    328381                                     PJ_STUN_ATTR_REMOTE_ADDR, PJ_FALSE, 
    329382                                     &g.peer_addr, sizeof(g.peer_addr)); 
     
    338391static void send_send_ind(void) 
    339392{ 
    340 } 
    341  
    342 static void send_raw_data(void) 
    343 { 
     393    pj_stun_tx_data *tdata; 
     394    int len; 
     395    pj_status_t rc; 
     396 
     397    if (g.peer_addr.sin_addr.s_addr == 0 || 
     398        g.peer_addr.sin_port == 0) 
     399    { 
     400        puts("Error: peer address is not set"); 
     401        return; 
     402    } 
     403 
     404    len = strlen(g.data); 
     405    if (len==0) { 
     406        puts("Error: data is not set"); 
     407        return; 
     408    } 
     409 
     410    rc = pj_stun_session_create_ind(g.sess, PJ_STUN_SEND_INDICATION, &tdata); 
     411    pj_assert(rc == PJ_SUCCESS); 
     412 
     413    pj_stun_msg_add_sockaddr_attr(tdata->pool, tdata->msg, 
     414                                  PJ_STUN_ATTR_REMOTE_ADDR, PJ_FALSE, 
     415                                  &g.peer_addr, sizeof(g.peer_addr)); 
     416    pj_stun_msg_add_binary_attr(tdata->pool, tdata->msg, 
     417                                PJ_STUN_ATTR_DATA, g.data, len); 
     418 
     419    rc = pj_stun_session_send_msg(g.sess, PJ_FALSE,  
     420                                  &g.srv_addr, sizeof(g.srv_addr), 
     421                                  tdata); 
     422    pj_assert(rc == PJ_SUCCESS); 
     423 
     424} 
     425 
     426static void send_raw_data_to_srv(void) 
     427{ 
     428    pj_ssize_t len; 
     429 
     430    if (g.srv_addr.sin_addr.s_addr == 0 || 
     431        g.srv_addr.sin_port == 0) 
     432    { 
     433        puts("Error: server address is not set"); 
     434        return; 
     435    } 
     436 
     437    len = strlen(g.data); 
     438    if (len==0) { 
     439        puts("Error: data is not set"); 
     440        return; 
     441    } 
     442 
     443    len = strlen(g.data); 
     444    pj_sock_sendto(g.sock, g.data, &len, 0, &g.srv_addr, sizeof(g.srv_addr)); 
     445} 
     446 
     447static void send_raw_data_to_relay(void) 
     448{ 
     449    pj_ssize_t len; 
     450 
     451    if (g.relay_addr.sin_addr.s_addr == 0 || 
     452        g.relay_addr.sin_port == 0) 
     453    { 
     454        puts("Error: relay address is not set"); 
     455        return; 
     456    } 
     457 
     458    len = strlen(g.data); 
     459    if (len==0) { 
     460        puts("Error: data is not set"); 
     461        return; 
     462    } 
     463 
     464    len = strlen(g.data); 
     465    pj_sock_sendto(g.sock, g.data, &len, 0, &g.relay_addr, sizeof(g.relay_addr)); 
     466} 
     467 
     468static pj_status_t parse_addr(const char *input, 
     469                              pj_sockaddr_in *addr) 
     470{ 
     471    const char *pos; 
     472    pj_str_t ip; 
     473    pj_uint16_t port; 
     474    pj_sockaddr_in tmp_addr; 
     475 
     476    pos = pj_ansi_strchr(input, ':'); 
     477    if (pos==NULL) { 
     478        puts("Invalid format"); 
     479        return -1; 
     480    } 
     481 
     482    ip.ptr = (char*)input; 
     483    ip.slen = pos - input; 
     484    port = (pj_uint16_t)atoi(pos+1); 
     485 
     486    if (port==0) { 
     487        puts("Invalid port"); 
     488        return -1; 
     489    } 
     490 
     491    if (pj_sockaddr_in_init(&tmp_addr, &ip, port)!=PJ_SUCCESS) { 
     492        puts("Invalid address"); 
     493        return -1; 
     494    } 
     495 
     496    pj_memcpy(addr, &tmp_addr, sizeof(tmp_addr)); 
     497 
     498    return PJ_SUCCESS; 
    344499} 
    345500 
    346501static void set_peer_addr(void) 
    347502{ 
    348     char ip_addr[64]; 
    349     pj_str_t tmp; 
    350     pj_sockaddr_in addr; 
    351     int port; 
     503    char addr[64]; 
    352504 
    353505    printf("Current peer address: %s:%d\n",  
     
    357509    printf("Input peer address in IP:PORT format: "); 
    358510    fflush(stdout); 
    359  
    360     if (scanf("%s:%d", ip_addr, &port) != 2) { 
    361         puts("Error."); 
    362         return; 
    363     } 
    364  
    365     if (pj_sockaddr_in_init(&addr, pj_cstr(&tmp,ip_addr), (pj_uint16_t)port) != PJ_SUCCESS) { 
    366         puts("Error: invalid address"); 
    367         return; 
    368     } 
    369  
    370     g.peer_addr = addr; 
     511    gets(addr); 
     512 
     513    if (parse_addr(addr, &g.peer_addr) != PJ_SUCCESS) { 
     514        return; 
     515    } 
     516 
    371517} 
    372518 
     
    376522    printf("  pr      Set peer address (currently %s:%d)\n", 
    377523           pj_inet_ntoa(g.peer_addr.sin_addr), pj_ntohs(g.peer_addr.sin_port)); 
    378     puts(""); 
     524    printf("  dt      Set data (currently \"%s\")\n", g.data); 
    379525    puts("  br      Send Bind request"); 
    380526    puts("  ar      Send Allocate request"); 
    381527    puts("  dr      Send de-Allocate request"); 
    382     puts("  sr      Send Set Active Indication request"); 
    383     puts("  cr      Send clear Active Indication request"); 
     528    puts("  sr      Send Set Active Destination request"); 
     529    puts("  cr      Send clear Active Destination request"); 
    384530    puts("  si      Send data with Send Indication"); 
    385     puts("  rw      Send raw data"); 
     531    puts("  rw      Send raw data to TURN server"); 
     532    puts("  rW      Send raw data to relay address"); 
    386533    puts("  q       Quit"); 
    387534    puts(""); 
     
    399546        fgets(input, sizeof(input), stdin); 
    400547         
    401         if (input[0]=='b' && input[1]=='r') { 
     548        if (0) { 
     549 
     550        } else if (input[0]=='d' && input[1]=='t') { 
     551            printf("Input data: "); 
     552            gets(g.data); 
     553             
     554        } else if (input[0]=='p' && input[1]=='r') { 
     555            set_peer_addr(); 
     556             
     557        } else if (input[0]=='b' && input[1]=='r') { 
    402558            send_bind_request(); 
    403559             
     
    418574             
    419575        } else if (input[0]=='r' && input[1]=='w') { 
    420             send_raw_data(); 
    421              
    422         } else if (input[0]=='p' && input[1]=='r') { 
    423             set_peer_addr(); 
     576            send_raw_data_to_srv(); 
     577             
     578        } else if (input[0]=='r' && input[1]=='W') { 
     579            send_raw_data_to_relay(); 
    424580             
    425581        } else if (input[0]=='q') { 
     
    442598    puts(" --nonce, -N       Set NONCE");    
    443599    puts(" --fingerprint, -F Use fingerprint for outgoing requests"); 
     600    puts(" --peer, -P        Set peer address (address is in HOST:PORT format)"); 
     601    puts(" --data, -D        Set data"); 
    444602    puts(" --help, -h"); 
    445603} 
     
    453611        { "nonce",      1, 0, 'N'}, 
    454612        { "fingerprint",0, 0, 'F'}, 
     613        { "peer",       1, 0, 'P'}, 
     614        { "data",       1, 0, 'D'}, 
    455615        { "help",       0, 0, 'h'} 
    456616    }; 
     
    459619    pj_status_t status; 
    460620 
     621    g.data = g.data_buf; 
     622 
    461623    while((c=pj_getopt_long(argc,argv, "r:u:p:hF", long_options, &opt_id))!=-1) { 
    462624        switch (c) { 
     
    479641            o.use_fingerprint = PJ_TRUE; 
    480642            break; 
     643        case 'P': 
     644            o.peer_addr = pj_optarg; 
     645            break; 
     646        case 'D': 
     647            g.data = pj_optarg; 
     648            break; 
     649 
    481650        default: 
    482651            printf("Argument \"%s\" is not valid. Use -h to see help", 
Note: See TracChangeset for help on using the changeset viewer.