Changeset 996


Ignore:
Timestamp:
Feb 23, 2007 1:07:54 AM (13 years ago)
Author:
bennylp
Message:

Ticket #121 and #122: Initial implementation of generic STUN transaction, with Binding request as an example

Location:
pjproject/trunk
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib-util/include/pjlib-util/stun_endpoint.h

    r992 r996  
    6262 * Create a STUN endpoint instance. 
    6363 */ 
    64 PJ_DECL(pj_status_t) pj_stun_endpt_create(pj_pool_factory *factory, 
    65                                           unsigned options, 
    66                                           pj_ioqueue_t *ioqueue, 
    67                                           pj_timer_heap_t *timer_heap, 
    68                                           pj_stun_endpoint **p_endpt); 
     64PJ_DECL(pj_status_t) pj_stun_endpoint_create(pj_pool_factory *factory, 
     65                                             unsigned options, 
     66                                             pj_ioqueue_t *ioqueue, 
     67                                             pj_timer_heap_t *timer_heap, 
     68                                             pj_stun_endpoint **p_endpt); 
    6969 
    7070/** 
    7171 * Destroy STUN endpoint instance. 
    7272 */ 
    73 PJ_DECL(pj_status_t) pj_stun_endpt_destroy(pj_stun_endpoint *endpt); 
     73PJ_DECL(pj_status_t) pj_stun_endpoint_destroy(pj_stun_endpoint *endpt); 
    7474 
    7575 
  • pjproject/trunk/pjlib-util/include/pjlib-util/stun_msg.h

    r993 r996  
    11961196 * @param buffer        Buffer where the printable string output will 
    11971197 *                      be printed on. 
    1198  * @param length        On input, specify the maximum length of the buffer. 
    1199  *                      On output, it will be filled up with the actual 
    1200  *                      length of the output string. 
     1198 * @param length        Specify the maximum length of the buffer. 
     1199 * @param printed_len   Optional pointer, which on output will be filled 
     1200 *                      up with the actual length of the output string. 
    12011201 * 
    12021202 * @return              The message string output. 
     
    12041204PJ_DECL(char*) pj_stun_msg_dump(const pj_stun_msg *msg, 
    12051205                                char *buffer, 
    1206                                 unsigned *length); 
     1206                                unsigned length, 
     1207                                unsigned *printed_len); 
    12071208 
    12081209 
  • pjproject/trunk/pjlib-util/include/pjlib-util/stun_transaction.h

    r993 r996  
    103103 * @param endpt         The STUN endpoint, which will be used to retrieve 
    104104 *                      various settings for the transaction. 
     105 * @param pool          Pool to be used to allocate memory from. 
    105106 * @param cb            Callback structure, to be used by the transaction 
    106107 *                      to send message and to notify the application about 
     
    111112 */ 
    112113PJ_DECL(pj_status_t) pj_stun_client_tsx_create( pj_stun_endpoint *endpt, 
     114                                                pj_pool_t *pool, 
    113115                                                const pj_stun_tsx_cb *cb, 
    114116                                                pj_stun_client_tsx **p_tsx); 
     
    169171 * @param retransmit    Should this message be retransmitted by the 
    170172 *                      STUN transaction. 
    171  * @param msg           The STUN message. 
     173 * @param pkt           The STUN packet to send. 
     174 * @param pkt_len       Length of STUN packet. 
    172175 * 
    173176 * @return              PJ_SUCCESS on success or the appropriate error code. 
     
    175178PJ_DECL(pj_status_t) pj_stun_client_tsx_send_msg(pj_stun_client_tsx *tsx, 
    176179                                                 pj_bool_t retransmit, 
    177                                                  const pj_stun_msg *msg); 
     180                                                 void *pkt, 
     181                                                 unsigned pkt_len); 
     182 
    178183 
    179184 
     
    197202 * @return              PJ_SUCCESS on success or the appropriate error code. 
    198203 */ 
    199 PJ_DECL(pj_status_t) pj_stun_client_tsx_on_rx_pkt(pj_stun_client_tsx *tsx, 
    200                                                   const void *packet, 
    201                                                   pj_size_t pkt_size, 
    202                                                   unsigned *parsed_len); 
    203  
    204  
    205 /** 
    206  * Notify the STUN transaction about the arrival of STUN response. 
    207  * If the STUN response contains a final error (300 and greater), the 
    208  * transaction will be terminated and callback will be called. If the 
    209  * STUN response contains response code 100-299, retransmission 
    210  * will  cease, but application must still call this function again 
    211  * with a final response later to allow the transaction to complete. 
    212  * 
    213  * @param tsx           The STUN client transaction instance. 
    214  * @param packet        The incoming packet. 
    215  * @param pkt_size      Size of the incoming packet. 
    216  * @param parsed_len    Optional pointer to receive the number of bytes 
    217  *                      that have been parsed from the incoming packet 
    218  *                      for the STUN message. This is useful if the 
    219  *                      STUN transaction is running over stream oriented 
    220  *                      socket such as TCP or TLS. 
    221  * 
    222  * @return              PJ_SUCCESS on success or the appropriate error code. 
    223  */ 
    224204PJ_DECL(pj_status_t) pj_stun_client_tsx_on_rx_msg(pj_stun_client_tsx *tsx, 
    225205                                                  const pj_stun_msg *msg); 
  • pjproject/trunk/pjlib-util/src/pjlib-util/stun_endpoint.c

    r992 r996  
    2626 * Create a STUN endpoint instance. 
    2727 */ 
    28 PJ_DEF(pj_status_t) pj_stun_endpt_create( pj_pool_factory *factory, 
    29                                           unsigned options, 
    30                                           pj_ioqueue_t *ioqueue, 
    31                                           pj_timer_heap_t *timer_heap, 
    32                                           pj_stun_endpoint **p_endpt) 
     28PJ_DEF(pj_status_t) pj_stun_endpoint_create( pj_pool_factory *factory, 
     29                                             unsigned options, 
     30                                             pj_ioqueue_t *ioqueue, 
     31                                             pj_timer_heap_t *timer_heap, 
     32                                             pj_stun_endpoint **p_endpt) 
    3333{ 
    3434    pj_pool_t *pool; 
     
    5858 * Destroy STUN endpoint instance. 
    5959 */ 
    60 PJ_DEF(pj_status_t) pj_stun_endpt_destroy(pj_stun_endpoint *endpt) 
     60PJ_DEF(pj_status_t) pj_stun_endpoint_destroy(pj_stun_endpoint *endpt) 
    6161{ 
    6262    PJ_ASSERT_RETURN(endpt, PJ_EINVAL); 
  • pjproject/trunk/pjlib-util/src/pjlib-util/stun_msg.c

    r992 r996  
    13331333    pj_stun_msg_hdr *hdr; 
    13341334 
    1335     PJ_ASSERT_RETURN(pdu && pdu_len > sizeof(pj_stun_msg_hdr),  
    1336                      PJLIB_UTIL_ESTUNINMSGLEN); 
     1335    PJ_ASSERT_RETURN(pdu, PJ_EINVAL); 
     1336 
     1337    if (pdu_len < sizeof(pj_stun_msg_hdr)) 
     1338        return PJLIB_UTIL_ESTUNINMSGLEN; 
    13371339 
    13381340    PJ_UNUSED_ARG(options); 
  • pjproject/trunk/pjlib-util/src/pjlib-util/stun_msg_dump.c

    r993 r996  
    3333    int len; 
    3434 
    35     len = pj_ansi_snprintf(buffer, end-p, 
     35    len = pj_ansi_snprintf(p, end-p, 
    3636                           "  %s: length=%d", 
    3737                           pj_stun_get_attr_name(ahdr->type), 
     
    5959 
    6060            if (attr->addr.addr.sa_family == PJ_AF_INET) { 
    61                 len = pj_ansi_snprintf(buffer, end-p, 
     61                len = pj_ansi_snprintf(p, end-p, 
    6262                                       ", IPv4 addr=%s:%d\n", 
    6363                                       pj_inet_ntoa(attr->addr.ipv4.sin_addr), 
     
    6565 
    6666            } else if (attr->addr.addr.sa_family == PJ_AF_INET6) { 
    67                 len = pj_ansi_snprintf(buffer, end-p, 
     67                len = pj_ansi_snprintf(p, end-p, 
    6868                                       ", IPv6 addr present\n"); 
    6969            } else { 
    70                 len = pj_ansi_snprintf(buffer, end-p, 
     70                len = pj_ansi_snprintf(p, end-p, 
    7171                                       ", INVALID ADDRESS FAMILY!\n"); 
    7272            } 
     
    8888 
    8989            attr = (const pj_stun_generic_uint_attr*)ahdr; 
    90             len = pj_ansi_snprintf(buffer, end-p, 
    91                                    ", value=%d (%x)\n", 
     90            len = pj_ansi_snprintf(p, end-p, 
     91                                   ", value=%d (0x%x)\n", 
    9292                                   (pj_uint32_t)attr->value, 
    9393                                   (pj_uint32_t)attr->value); 
     
    104104 
    105105            attr = (pj_stun_generic_string_attr*)ahdr; 
    106             len = pj_ansi_snprintf(buffer, end-p, 
     106            len = pj_ansi_snprintf(p, end-p, 
    107107                                   ", value=\"%.*s\"\n", 
    108108                                   (int)attr->value.slen, 
     
    116116 
    117117            attr = (const pj_stun_error_code_attr*) ahdr; 
    118             len = pj_ansi_snprintf(buffer, end-p, 
     118            len = pj_ansi_snprintf(p, end-p, 
    119119                                   ", err_code=%d, reason=\"%.*s\"\n", 
    120120                                   attr->err_class*100 + attr->number, 
     
    131131            attr = (const pj_stun_unknown_attr*) ahdr; 
    132132 
    133             len = pj_ansi_snprintf(buffer, end-p, 
     133            len = pj_ansi_snprintf(p, end-p, 
    134134                                   ", unknown list:"); 
    135135            APPLY(); 
    136136 
    137137            for (j=0; j<attr->attr_count; ++j) { 
    138                 len = pj_ansi_snprintf(buffer, end-p, 
     138                len = pj_ansi_snprintf(p, end-p, 
    139139                                       " %d", 
    140140                                       (int)attr->attrs[j]); 
     
    148148    case PJ_STUN_ATTR_USE_CANDIDATE: 
    149149    default: 
    150         len = pj_ansi_snprintf(buffer, end-p, "\n"); 
     150        len = pj_ansi_snprintf(p, end-p, "\n"); 
    151151 
    152152        break; 
     
    167167PJ_DEF(char*) pj_stun_msg_dump(const pj_stun_msg *msg, 
    168168                               char *buffer, 
    169                                unsigned *length) 
     169                               unsigned length, 
     170                               unsigned *printed_len) 
    170171{ 
    171172    char *p, *end; 
     
    176177 
    177178    p = buffer; 
    178     end = buffer + (*length); 
     179    end = buffer + length; 
    179180 
    180181    len = pj_ansi_snprintf(p, end-p, "STUN %s %s\n", 
     
    184185 
    185186    len = pj_ansi_snprintf(p, end-p,  
    186                             " Hdr: length=%d, magic=%x, tsx_id=%x %x %x\n" 
    187                             " Attributes:\n", 
     187                           " Hdr: length=%d, magic=%08x, tsx_id=%08x %08x %08x\n" 
     188                           " Attributes:\n", 
    188189                           msg->hdr.length, 
    189190                           msg->hdr.magic, 
     
    200201on_return: 
    201202    *p = '\0'; 
    202     *length = (p-buffer); 
     203    if (printed_len) 
     204        *printed_len = (p-buffer); 
    203205    return buffer; 
    204206 
  • pjproject/trunk/pjlib-util/src/pjlib-util/stun_transaction.c

    r993 r996  
    3232{ 
    3333    char                 obj_name[PJ_MAX_OBJ_NAME]; 
    34     pj_pool_t           *pool; 
    3534    pj_stun_endpoint    *endpt; 
    3635    pj_stun_tsx_cb       cb; 
    3736    void                *user_data; 
    3837 
    39     pj_uint32_t          tsx_id[4]; 
    40  
     38    pj_bool_t            complete; 
     39    \ 
    4140    pj_bool_t            require_retransmit; 
    4241    pj_timer_entry       timer; 
     
    4443    pj_time_val          retransmit_time; 
    4544 
    46     pj_uint8_t           last_pkt[PJ_STUN_MAX_PKT_LEN]; 
     45    void                *last_pkt; 
    4746    unsigned             last_pkt_size; 
    4847}; 
     
    6665 */ 
    6766PJ_DEF(pj_status_t) pj_stun_client_tsx_create(pj_stun_endpoint *endpt, 
     67                                              pj_pool_t *pool, 
    6868                                              const pj_stun_tsx_cb *cb, 
    6969                                              pj_stun_client_tsx **p_tsx) 
    7070{ 
    71     pj_pool_t *pool; 
    7271    pj_stun_client_tsx *tsx; 
    7372 
     
    7574    PJ_ASSERT_RETURN(cb->on_send_msg, PJ_EINVAL); 
    7675 
    77     pool = pj_pool_create(endpt->pf, "tsx", 1000, 1000, NULL); 
    7876    tsx = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_client_tsx); 
    79     tsx->pool = pool; 
    8077    tsx->endpt = endpt; 
    8178    pj_memcpy(&tsx->cb, cb, sizeof(*cb)); 
     
    8481    tsx->timer.user_data = tsx; 
    8582 
    86     pj_ansi_snprintf(tsx->obj_name, sizeof(tsx->obj_name), "stuntsx%p", pool); 
     83    pj_ansi_snprintf(tsx->obj_name, sizeof(tsx->obj_name), "stuntsx%p", tsx); 
    8784 
    8885    *p_tsx = tsx; 
     
    104101        tsx->timer.id = 0; 
    105102    } 
    106     pj_pool_release(tsx->pool); 
    107103    return PJ_SUCCESS; 
     104} 
     105 
     106 
     107/* 
     108 * Check if transaction has completed. 
     109 */ 
     110PJ_DEF(pj_bool_t) pj_stun_client_tsx_is_complete(pj_stun_client_tsx *tsx) 
     111{ 
     112    PJ_ASSERT_RETURN(tsx, PJ_FALSE); 
     113    return tsx->complete; 
    108114} 
    109115 
     
    146152            tsx->retransmit_time.msec = tsx->endpt->rto_msec; 
    147153 
    148         } else if (tsx->transmit_count < PJ_STUN_MAX_RETRANSMIT_COUNT) { 
     154        } else if (tsx->transmit_count < PJ_STUN_MAX_RETRANSMIT_COUNT-1) { 
    149155            unsigned msec; 
    150156 
    151157            msec = PJ_TIME_VAL_MSEC(tsx->retransmit_time); 
    152             msec = (msec >> 1) + 100; 
     158            msec = (msec << 1) + 100; 
    153159            tsx->retransmit_time.sec = msec / 1000; 
    154             tsx->retransmit_time.msec = msec % 100; 
     160            tsx->retransmit_time.msec = msec % 1000; 
    155161 
    156162        } else { 
     
    162168         * cancel it (as opposed to when schedule_timer() failed we cannot 
    163169         * cancel transmission). 
    164          */ 
     170         */; 
    165171        status = pj_timer_heap_schedule(tsx->endpt->timer_heap, &tsx->timer, 
    166172                                        &tsx->retransmit_time); 
     
    169175            return status; 
    170176        } 
     177        tsx->timer.id = TIMER_ACTIVE; 
    171178    } 
    172179 
     
    196203PJ_DEF(pj_status_t) pj_stun_client_tsx_send_msg(pj_stun_client_tsx *tsx, 
    197204                                                pj_bool_t retransmit, 
    198                                                 const pj_stun_msg *msg) 
    199 { 
    200     pj_status_t status; 
    201  
    202     PJ_ASSERT_RETURN(tsx && msg, PJ_EINVAL); 
    203     PJ_ASSERT_RETURN(tsx->timer.id != 0, PJ_EBUSY); 
     205                                                void *pkt, 
     206                                                unsigned pkt_len) 
     207{ 
     208    PJ_ASSERT_RETURN(tsx && pkt && pkt_len, PJ_EINVAL); 
     209    PJ_ASSERT_RETURN(tsx->timer.id == 0, PJ_EBUSY); 
    204210 
    205211    /* Encode message */ 
    206     status = pj_stun_msg_encode(msg, tsx->last_pkt, sizeof(tsx->last_pkt),  
    207                                 0, &tsx->last_pkt_size); 
    208     if (status != PJ_SUCCESS) { 
    209         stun_perror(tsx, "STUN msg_encode() failed", status); 
    210         return status; 
    211     } 
    212  
    213     /* Update STUN transaction ID */ 
    214     tsx->tsx_id[0] = msg->hdr.magic; 
    215     pj_memcpy(&tsx->tsx_id[1], msg->hdr.tsx_id, 12); 
     212    tsx->last_pkt = pkt; 
     213    tsx->last_pkt_size = pkt_len; 
    216214 
    217215    /* Update STUN retransmit flag */ 
     
    236234        tsx->timer.id = 0; 
    237235        PJ_LOG(4,(tsx->obj_name, "STUN timeout waiting for response")); 
     236        tsx->complete = PJ_TRUE; 
    238237        if (tsx->cb.on_complete) { 
    239238            tsx->cb.on_complete(tsx, PJLIB_UTIL_ESTUNNOTRESPOND, NULL); 
     
    246245    if (status != PJ_SUCCESS) { 
    247246        tsx->timer.id = 0; 
     247        tsx->complete = PJ_TRUE; 
    248248        if (tsx->cb.on_complete) { 
    249249            tsx->cb.on_complete(tsx, status, NULL); 
     
    272272    } 
    273273 
    274     /* Compare response's transaction ID */ 
    275     if (msg->hdr.magic != tsx->tsx_id[0] || 
    276         pj_memcmp(msg->hdr.tsx_id, &tsx->tsx_id[1], 12) != 0) 
    277     { 
    278         return PJLIB_UTIL_ESTUNINVALIDID; 
    279     } 
    280274 
    281275    /* We have a response with matching transaction ID.  
     
    312306 
    313307    /* Call callback */ 
     308    tsx->complete = PJ_TRUE; 
    314309    if (tsx->cb.on_complete) { 
    315310        tsx->cb.on_complete(tsx, status, msg); 
     
    320315} 
    321316 
    322  
    323 /* 
    324  * Notify the STUN transaction about the arrival of STUN response. 
    325  */ 
    326 PJ_DEF(pj_status_t) pj_stun_client_tsx_on_rx_pkt(pj_stun_client_tsx *tsx, 
    327                                                  const void *packet, 
    328                                                  pj_size_t pkt_size, 
    329                                                  unsigned *parsed_len) 
    330 { 
    331     pj_stun_msg *msg; 
    332     pj_status_t status; 
    333  
    334     PJ_ASSERT_RETURN(tsx && packet && pkt_size, PJ_EINVAL); 
    335  
    336     /* Try to parse the message */ 
    337     status = pj_stun_msg_decode(tsx->pool, (const pj_uint8_t*)packet, 
    338                                 pkt_size, 0, &msg, parsed_len, 
    339                                 NULL, NULL, NULL); 
    340     if (status != PJ_SUCCESS) { 
    341         stun_perror(tsx, "STUN msg_decode() error", status); 
    342         return status; 
    343     } 
    344  
    345     return pj_stun_client_tsx_on_rx_msg(tsx, msg); 
    346 } 
    347  
  • pjproject/trunk/pjlib-util/src/pjstun-client/client_main.c

    r993 r996  
    1919#include <pjlib-util.h> 
    2020#include <pjlib.h> 
     21#include "stun_session.h" 
     22 
     23#include <conio.h> 
    2124 
    2225 
    2326#define THIS_FILE       "client_main.c" 
    24 #define MAX_THREADS     8 
    2527 
     28 
     29static my_perror(const char *title, pj_status_t status) 
     30{ 
     31    char errmsg[PJ_ERR_MSG_SIZE]; 
     32    pj_strerror(status, errmsg, sizeof(errmsg)); 
     33 
     34    PJ_LOG(3,(THIS_FILE, "%s: %s", title, errmsg)); 
     35} 
     36 
     37static pj_status_t on_send_msg(pj_stun_tx_data *tdata, 
     38                               const void *pkt, 
     39                               pj_size_t pkt_size, 
     40                               unsigned addr_len,  
     41                               const pj_sockaddr_t *dst_addr) 
     42{ 
     43    pj_sock_t sock; 
     44    pj_ssize_t len; 
     45    pj_status_t status; 
     46 
     47    sock = (pj_sock_t) pj_stun_session_get_user_data(tdata->sess); 
     48 
     49    len = pkt_size; 
     50    status = pj_sock_sendto(sock, pkt, &len, 0, dst_addr, addr_len); 
     51 
     52    if (status != PJ_SUCCESS) 
     53        my_perror("Error sending packet", status); 
     54 
     55    return status; 
     56} 
     57 
     58static void on_bind_response(pj_stun_session *sess,  
     59                             pj_status_t status,  
     60                             pj_stun_tx_data *request, 
     61                             const pj_stun_msg *response) 
     62{ 
     63    my_perror("on_bind_response()", status); 
     64} 
     65 
     66int main() 
     67{ 
     68    pj_stun_endpoint *endpt = NULL; 
     69    pj_pool_t *pool = NULL; 
     70    pj_caching_pool cp; 
     71    pj_timer_heap_t *th = NULL; 
     72    pj_stun_session *sess; 
     73    pj_sock_t sock = PJ_INVALID_SOCKET; 
     74    pj_sockaddr_in addr; 
     75    pj_stun_session_cb stun_cb; 
     76    pj_stun_tx_data *tdata; 
     77    pj_str_t s; 
     78    pj_status_t status; 
     79 
     80    status = pj_init(); 
     81    status = pjlib_util_init(); 
     82 
     83    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0); 
     84     
     85    pool = pj_pool_create(&cp.factory, NULL, 1000, 1000, NULL); 
     86 
     87    status = pj_timer_heap_create(pool, 1000, &th); 
     88    pj_assert(status == PJ_SUCCESS); 
     89 
     90    status = pj_stun_endpoint_create(&cp.factory, 0, NULL, th, &endpt); 
     91    pj_assert(status == PJ_SUCCESS); 
     92 
     93    status = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &sock); 
     94    pj_assert(status == PJ_SUCCESS); 
     95 
     96    status = pj_sockaddr_in_init(&addr, pj_cstr(&s, "127.0.0.1"), PJ_STUN_PORT); 
     97    pj_assert(status == PJ_SUCCESS); 
     98 
     99    pj_memset(&stun_cb, 0, sizeof(stun_cb)); 
     100    stun_cb.on_send_msg = &on_send_msg; 
     101    stun_cb.on_bind_response = &on_bind_response; 
     102 
     103    status = pj_stun_session_create(endpt, NULL, &stun_cb, &sess); 
     104    pj_assert(status == PJ_SUCCESS); 
     105 
     106    pj_stun_session_set_user_data(sess, (void*)sock); 
     107 
     108    status = pj_stun_session_create_bind_req(sess, &tdata); 
     109    pj_assert(status == PJ_SUCCESS); 
     110 
     111    status = pj_stun_session_send_msg(sess, 0, sizeof(addr), &addr, tdata); 
     112    pj_assert(status == PJ_SUCCESS); 
     113 
     114    while (1) { 
     115        pj_fd_set_t rset; 
     116        int n; 
     117        pj_time_val timeout; 
     118 
     119        if (kbhit()) { 
     120            if (_getch()==27) 
     121                break; 
     122        } 
     123 
     124        PJ_FD_ZERO(&rset); 
     125        PJ_FD_SET(sock, &rset); 
     126 
     127        timeout.sec = 0; timeout.msec = 100; 
     128 
     129        n = pj_sock_select(FD_SETSIZE, &rset, NULL, NULL, &timeout); 
     130 
     131        if (PJ_FD_ISSET(sock, &rset)) { 
     132            char pkt[512]; 
     133            pj_ssize_t len; 
     134 
     135            len = sizeof(pkt); 
     136            status = pj_sock_recv(sock, pkt, &len, 0); 
     137            if (status == PJ_SUCCESS) { 
     138                pj_stun_session_on_rx_pkt(sess, pkt, len, NULL); 
     139            } 
     140        } 
     141 
     142        pj_timer_heap_poll(th, NULL); 
     143    } 
     144 
     145on_return: 
     146    if (sock != PJ_INVALID_SOCKET) 
     147        pj_sock_close(sock); 
     148    if (endpt) 
     149        pj_stun_endpoint_destroy(endpt); 
     150    if (th) 
     151        pj_timer_heap_destroy(th); 
     152    if (pool) 
     153        pj_pool_release(pool); 
     154    pj_caching_pool_destroy(&cp); 
     155 
     156    return 0; 
     157} 
     158 
     159 
  • pjproject/trunk/pjlib-util/src/pjstun-client/stun_session.c

    r993 r996  
    2727    void                *user_data; 
    2828 
    29     pj_str_t             realm; 
    30     pj_str_t             username; 
    31     pj_str_t             password; 
    32  
    33     pj_bool_t            fingerprint_enabled; 
     29    /* Long term credential */ 
     30    pj_str_t             l_realm; 
     31    pj_str_t             l_username; 
     32    pj_str_t             l_password; 
     33 
     34    /* Short term credential */ 
     35    pj_str_t             s_username; 
     36    pj_str_t             s_password; 
    3437 
    3538    pj_stun_tx_data      pending_request_list; 
     
    6568 
    6669static void tsx_on_complete(pj_stun_client_tsx *tsx, 
    67                                pj_status_t status,  
    68                                const pj_stun_msg *response); 
     70                            pj_status_t status,  
     71                            const pj_stun_msg *response); 
    6972static pj_status_t tsx_on_send_msg(pj_stun_client_tsx *tsx, 
    7073                                   const void *stun_pkt, 
     
    165168static pj_status_t session_apply_req(pj_stun_session *sess, 
    166169                                     pj_pool_t *pool, 
     170                                     unsigned options, 
    167171                                     pj_stun_msg *msg) 
    168172{ 
     
    172176     * Section 8.3.1.  Formulating the Request Message 
    173177     */ 
    174     if (sess->realm.slen || sess->username.slen) { 
     178    if (options & PJ_STUN_USE_LONG_TERM_CRED) { 
    175179        pj_stun_generic_string_attr *auname; 
    176180        pj_stun_msg_integrity_attr *amsgi; 
     181        pj_stun_generic_string_attr *arealm; 
    177182 
    178183        /* Create and add USERNAME attribute */ 
    179184        status = pj_stun_generic_string_attr_create(sess->pool,  
    180185                                                    PJ_STUN_ATTR_USERNAME, 
    181                                                     &sess->username, 
     186                                                    &sess->l_username, 
    182187                                                    &auname); 
    183188        PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 
     
    186191        PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 
    187192 
    188         if (sess->realm.slen) { 
    189             /* Add REALM only when long term credential is used */ 
    190             pj_stun_generic_string_attr *arealm; 
    191             status = pj_stun_generic_string_attr_create(sess->pool,  
    192                                                         PJ_STUN_ATTR_REALM, 
    193                                                         &sess->realm, 
    194                                                         &arealm); 
    195             PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 
    196  
    197             status = pj_stun_msg_add_attr(msg, &arealm->hdr); 
    198             PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 
    199         } 
     193        /* Add REALM only when long term credential is used */ 
     194        status = pj_stun_generic_string_attr_create(sess->pool,  
     195                                                    PJ_STUN_ATTR_REALM, 
     196                                                    &sess->l_realm, 
     197                                                    &arealm); 
     198        PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 
     199 
     200        status = pj_stun_msg_add_attr(msg, &arealm->hdr); 
     201        PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 
    200202 
    201203        /* Add MESSAGE-INTEGRITY attribute */ 
     
    206208        PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 
    207209 
    208         PJ_TODO(COMPUTE_MESSAGE_INTEGRITY); 
    209  
     210        PJ_TODO(COMPUTE_MESSAGE_INTEGRITY1); 
     211 
     212    } else if (options & PJ_STUN_USE_SHORT_TERM_CRED) { 
     213        pj_stun_generic_string_attr *auname; 
     214        pj_stun_msg_integrity_attr *amsgi; 
     215 
     216        /* Create and add USERNAME attribute */ 
     217        status = pj_stun_generic_string_attr_create(sess->pool,  
     218                                                    PJ_STUN_ATTR_USERNAME, 
     219                                                    &sess->s_username, 
     220                                                    &auname); 
     221        PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 
     222 
     223        status = pj_stun_msg_add_attr(msg, &auname->hdr); 
     224        PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 
     225 
     226        /* Add MESSAGE-INTEGRITY attribute */ 
     227        status = pj_stun_msg_integrity_attr_create(sess->pool, &amsgi); 
     228        PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 
     229 
     230        status = pj_stun_msg_add_attr(msg, &amsgi->hdr); 
     231        PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 
     232 
     233        PJ_TODO(COMPUTE_MESSAGE_INTEGRITY2); 
    210234    } 
    211235 
    212236    /* Add FINGERPRINT attribute if necessary */ 
    213     if (sess->fingerprint_enabled) { 
     237    if (options & PJ_STUN_USE_FINGERPRINT) { 
    214238        pj_stun_fingerprint_attr *af; 
    215239 
     
    227251 
    228252 
    229  
    230  
    231  
     253static void tsx_on_complete(pj_stun_client_tsx *tsx, 
     254                            pj_status_t status,  
     255                            const pj_stun_msg *response) 
     256{ 
     257    pj_stun_tx_data *tdata; 
     258 
     259    tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx); 
     260 
     261    switch (PJ_STUN_GET_METHOD(tdata->msg->hdr.type)) { 
     262    case PJ_STUN_BINDING_METHOD: 
     263        tdata->sess->cb.on_bind_response(tdata->sess, status, tdata, response); 
     264        break; 
     265    case PJ_STUN_ALLOCATE_METHOD: 
     266        tdata->sess->cb.on_allocate_response(tdata->sess, status, 
     267                                             tdata, response); 
     268        break; 
     269    case PJ_STUN_SET_ACTIVE_DESTINATION_METHOD: 
     270        tdata->sess->cb.on_set_active_destination_response(tdata->sess, status, 
     271                                                           tdata, response); 
     272        break; 
     273    case PJ_STUN_CONNECT_METHOD: 
     274        tdata->sess->cb.on_connect_response(tdata->sess, status, tdata, 
     275                                            response); 
     276        break; 
     277    default: 
     278        pj_assert(!"Unknown method"); 
     279        break; 
     280    } 
     281} 
     282 
     283static pj_status_t tsx_on_send_msg(pj_stun_client_tsx *tsx, 
     284                                   const void *stun_pkt, 
     285                                   pj_size_t pkt_size) 
     286{ 
     287    pj_stun_tx_data *tdata; 
     288 
     289    tdata = (pj_stun_tx_data*) pj_stun_client_tsx_get_data(tsx); 
     290 
     291    return tdata->sess->cb.on_send_msg(tdata, stun_pkt, pkt_size, 
     292                                       tdata->addr_len, tdata->dst_addr); 
     293} 
     294 
     295/* **************************************************************************/ 
    232296 
    233297PJ_DEF(pj_status_t) pj_stun_session_create( pj_stun_endpoint *endpt, 
     
    261325{ 
    262326    PJ_ASSERT_RETURN(sess, PJ_EINVAL); 
     327 
    263328    pj_pool_release(sess->pool); 
    264329 
     
    281346} 
    282347 
    283 PJ_DEF(pj_status_t) pj_stun_session_set_credential( pj_stun_session *sess, 
    284                                                     const pj_str_t *realm, 
    285                                                     const pj_str_t *user, 
    286                                                     const pj_str_t *passwd) 
    287 { 
    288     pj_str_t empty = { NULL, 0 }; 
     348PJ_DEF(pj_status_t)  
     349pj_stun_session_set_long_term_credential(pj_stun_session *sess, 
     350                                         const pj_str_t *realm, 
     351                                         const pj_str_t *user, 
     352                                         const pj_str_t *passwd) 
     353{ 
     354    pj_str_t nil = { NULL, 0 }; 
    289355 
    290356    PJ_ASSERT_RETURN(sess, PJ_EINVAL); 
    291     pj_strdup_with_null(sess->pool, &sess->realm, realm ? realm : &empty); 
    292     pj_strdup_with_null(sess->pool, &sess->username, user ? user : &empty); 
    293     pj_strdup_with_null(sess->pool, &sess->password, passwd ? passwd : &empty); 
    294  
    295     return PJ_SUCCESS; 
    296 } 
    297  
    298 PJ_DEF(pj_status_t) pj_stun_session_enable_fingerprint(pj_stun_session *sess, 
    299                                                        pj_bool_t enabled) 
    300 { 
     357    pj_strdup_with_null(sess->pool, &sess->l_realm, realm ? realm : &nil); 
     358    pj_strdup_with_null(sess->pool, &sess->l_username, user ? user : &nil); 
     359    pj_strdup_with_null(sess->pool, &sess->l_password, passwd ? passwd : &nil); 
     360 
     361    return PJ_SUCCESS; 
     362} 
     363 
     364 
     365PJ_DEF(pj_status_t)  
     366pj_stun_session_set_short_term_credential(pj_stun_session *sess, 
     367                                          const pj_str_t *user, 
     368                                          const pj_str_t *passwd) 
     369{ 
     370    pj_str_t nil = { NULL, 0 }; 
     371 
    301372    PJ_ASSERT_RETURN(sess, PJ_EINVAL); 
    302     sess->fingerprint_enabled = enabled; 
     373    pj_strdup_with_null(sess->pool, &sess->s_username, user ? user : &nil); 
     374    pj_strdup_with_null(sess->pool, &sess->s_password, passwd ? passwd : &nil); 
     375 
    303376    return PJ_SUCCESS; 
    304377} 
     
    308381                                                    pj_stun_tx_data **p_tdata) 
    309382{ 
    310     pj_pool_t *pool; 
    311383    pj_stun_tx_data *tdata; 
    312384    pj_status_t status; 
     
    318390        return status; 
    319391 
    320     status = session_apply_req(sess, pool, tdata->msg); 
    321     if (status != PJ_SUCCESS) { 
    322         destroy_tdata(tdata); 
    323         return status; 
    324     } 
    325  
    326392    *p_tdata = tdata; 
    327393    return PJ_SUCCESS; 
     
    368434 
    369435PJ_DEF(pj_status_t) pj_stun_session_send_msg( pj_stun_session *sess, 
     436                                              unsigned options, 
    370437                                              unsigned addr_len, 
    371438                                              const pj_sockaddr_t *server, 
     
    376443    PJ_ASSERT_RETURN(sess && addr_len && server && tdata, PJ_EINVAL); 
    377444 
     445    /* Allocate packet */ 
     446    tdata->max_len = PJ_STUN_MAX_PKT_LEN; 
     447    tdata->pkt = pj_pool_alloc(tdata->pool, tdata->max_len); 
     448 
    378449    if (PJ_LOG_MAX_LEVEL >= 5) { 
    379         char buf[512]; 
    380         unsigned buflen = sizeof(buf); 
     450        char *buf = (char*) tdata->pkt; 
    381451        const char *dst_name; 
    382452        int dst_port; 
     
    398468        PJ_LOG(5,(SNAME(sess),  
    399469                  "Sending STUN message to %s:%d:\n" 
    400                   "%s\n", 
     470                  "--- begin STUN message ---\n" 
     471                  "%s" 
     472                  "--- end of STUN message ---\n", 
    401473                  dst_name, dst_port, 
    402                   pj_stun_msg_dump(tdata->msg, buf, &buflen))); 
    403     } 
    404  
     474                  pj_stun_msg_dump(tdata->msg, buf, tdata->max_len, NULL))); 
     475    } 
     476 
     477    /* Apply options */ 
     478    status = session_apply_req(sess, tdata->pool, options, tdata->msg); 
     479    if (status != PJ_SUCCESS) { 
     480        LOG_ERR_(sess, "Error applying options", status); 
     481        destroy_tdata(tdata); 
     482        return status; 
     483    } 
     484 
     485    /* Encode message */ 
     486    status = pj_stun_msg_encode(tdata->msg, tdata->pkt, tdata->max_len, 
     487                                0, &tdata->pkt_size); 
     488    if (status != PJ_SUCCESS) { 
     489        LOG_ERR_(sess, "STUN encode() error", status); 
     490        destroy_tdata(tdata); 
     491        return status; 
     492    } 
    405493 
    406494    /* If this is a STUN request message, then send the request with 
     
    410498 
    411499        /* Create STUN client transaction */ 
    412         status = pj_stun_client_tsx_create(sess->endpt, &tsx_cb,  
    413                                            &tdata->client_tsx); 
     500        status = pj_stun_client_tsx_create(sess->endpt, tdata->pool,  
     501                                           &tsx_cb, &tdata->client_tsx); 
    414502        PJ_ASSERT_RETURN(status==PJ_SUCCESS, status); 
    415503        pj_stun_client_tsx_set_data(tdata->client_tsx, (void*)tdata); 
     504 
     505        /* Save the remote address */ 
     506        tdata->addr_len = addr_len; 
     507        tdata->dst_addr = server; 
    416508 
    417509        /* Send the request! */ 
    418510        status = pj_stun_client_tsx_send_msg(tdata->client_tsx, PJ_TRUE, 
    419                                              tdata->msg); 
     511                                             tdata->pkt, tdata->pkt_size); 
    420512        if (status != PJ_SUCCESS && status != PJ_EPENDING) { 
    421513            LOG_ERR_(sess, "Error sending STUN request", status); 
     514            destroy_tdata(tdata); 
    422515            return status; 
    423516        } 
     
    428521    } else { 
    429522        /* Otherwise for non-request message, send directly to transport. */ 
    430         status = sess->cb.on_send_msg(tdata, addr_len, server); 
     523        status = sess->cb.on_send_msg(tdata, tdata->pkt, tdata->pkt_size, 
     524                                      addr_len, server); 
     525 
     526        if (status != PJ_SUCCESS && status != PJ_EPENDING) { 
     527            LOG_ERR_(sess, "Error sending STUN request", status); 
     528            destroy_tdata(tdata); 
     529            return status; 
     530        } 
    431531    } 
    432532 
     
    442542{ 
    443543    pj_stun_msg *msg; 
     544    pj_pool_t *tmp_pool; 
     545    char *dump; 
    444546    pj_status_t status; 
    445547 
    446548    PJ_ASSERT_RETURN(sess && packet && pkt_size, PJ_EINVAL); 
    447549 
     550    tmp_pool = pj_pool_create(sess->endpt->pf, "tmpstun", 1024, 1024, NULL); 
     551    if (!tmp_pool) 
     552        return PJ_ENOMEM; 
     553 
    448554    /* Try to parse the message */ 
    449     status = pj_stun_msg_decode(tsx->pool, (const pj_uint8_t*)packet, 
     555    status = pj_stun_msg_decode(tmp_pool, (const pj_uint8_t*)packet, 
    450556                                pkt_size, 0, &msg, parsed_len, 
    451557                                NULL, NULL, NULL); 
    452558    if (status != PJ_SUCCESS) { 
    453559        LOG_ERR_(sess, "STUN msg_decode() error", status); 
     560        pj_pool_release(tmp_pool); 
    454561        return status; 
    455562    } 
     563 
     564    dump = pj_pool_alloc(tmp_pool, PJ_STUN_MAX_PKT_LEN); 
     565 
     566    PJ_LOG(4,(SNAME(sess),  
     567              "RX STUN message:\n" 
     568              "--- begin STUN message ---" 
     569              "%s" 
     570              "--- end of STUN message ---\n", 
     571              pj_stun_msg_dump(msg, dump, PJ_STUN_MAX_PKT_LEN, NULL))); 
     572 
    456573 
    457574    if (PJ_STUN_IS_RESPONSE(msg->hdr.type) || 
     
    464581        if (tdata == NULL) { 
    465582            LOG_ERR_(sess, "STUN error finding transaction", PJ_ENOTFOUND); 
     583            pj_pool_release(tmp_pool); 
    466584            return PJ_ENOTFOUND; 
    467585        } 
     
    472590         */ 
    473591        status = pj_stun_client_tsx_on_rx_msg(tdata->client_tsx, msg); 
    474         if (status != PJ_SUCCESS) 
     592        if (status != PJ_SUCCESS) { 
     593            pj_pool_release(tmp_pool); 
    475594            return status; 
     595        } 
    476596 
    477597        /* If transaction has completed, destroy the transmit data. 
     
    483603        } 
    484604 
     605        pj_pool_release(tmp_pool); 
    485606        return PJ_SUCCESS; 
    486607 
    487608    } else if (PJ_STUN_IS_REQUEST(msg->hdr.type)) { 
    488609 
     610        PJ_TODO(HANDLE_INCOMING_STUN_REQUEST); 
    489611 
    490612    } else if (PJ_STUN_IS_INDICATION(msg->hdr.type)) { 
    491613 
     614        PJ_TODO(HANDLE_INCOMING_STUN_INDICATION); 
    492615 
    493616    } else { 
    494617        pj_assert(!"Unexpected!"); 
    495         return PJ_EBUG; 
    496     } 
    497  
    498 } 
    499  
     618    } 
     619 
     620    pj_pool_release(tmp_pool); 
     621    return PJ_ENOTSUP; 
     622} 
     623 
  • pjproject/trunk/pjlib-util/src/pjstun-client/stun_session.h

    r993 r996  
    2626 
    2727 
     28/** Forward declaration for pj_stun_tx_data */ 
    2829typedef struct pj_stun_tx_data pj_stun_tx_data; 
     30 
     31/** Forward declaration for pj_stun_session */ 
    2932typedef struct pj_stun_session pj_stun_session; 
    3033 
     34/** 
     35 * This is the callback to be registered to pj_stun_session, to send 
     36 * outgoing message and to receive various notifications from the STUN 
     37 * session. 
     38 */ 
    3139typedef struct pj_stun_session_cb 
    3240{ 
     41    /** 
     42     * Callback to be called by the STUN session to send outgoing message. 
     43     * 
     44     * @param tdata         The STUN transmit data containing the original 
     45     *                      STUN message 
     46     * @param pkt           Packet to be sent. 
     47     * @param pkt_size      Size of the packet to be sent. 
     48     * @param addr_len      Length of destination address. 
     49     * @param dst_addr      The destination address. 
     50     * 
     51     * @return              The callback should return the status of the 
     52     *                      packet sending. 
     53     */ 
    3354    pj_status_t (*on_send_msg)(pj_stun_tx_data *tdata, 
     55                               const void *pkt, 
     56                               pj_size_t pkt_size, 
    3457                               unsigned addr_len,  
    3558                               const pj_sockaddr_t *dst_addr); 
    3659 
    37     void (*on_bind_response)(void *user_data, pj_status_t status, pj_stun_msg *response); 
    38     void (*on_allocate_response)(void *user_data, pj_status_t status, pj_stun_msg *response); 
    39     void (*on_set_active_destination_response)(void *user_data, pj_status_t status, pj_stun_msg *response); 
    40     void (*on_connect_response)(void *user_data, pj_status_t status, pj_stun_msg *response); 
     60    /** 
     61     * Callback to be called when Binding response is received or the  
     62     * transaction has timed out. 
     63     * 
     64     * @param sess          The STUN session. 
     65     * @param status        Status of the request. If the value if not 
     66     *                      PJ_SUCCESS, the transaction has timed-out 
     67     *                      or other error has occurred, and the response 
     68     *                      argument may be NULL. 
     69     * @param request       The original STUN request. 
     70     * @param response      The response message, on successful transaction. 
     71     */ 
     72    void (*on_bind_response)(pj_stun_session *sess,  
     73                             pj_status_t status,  
     74                             pj_stun_tx_data *request, 
     75                             const pj_stun_msg *response); 
     76 
     77    /** 
     78     * Callback to be called when Allocate response is received or the  
     79     * transaction has timed out. 
     80     * 
     81     * @param sess          The STUN session. 
     82     * @param status        Status of the request. If the value if not 
     83     *                      PJ_SUCCESS, the transaction has timed-out 
     84     *                      or other error has occurred, and the response 
     85     *                      argument may be NULL. 
     86     * @param request       The original STUN request. 
     87     * @param response      The response message, on successful transaction. 
     88     */ 
     89    void (*on_allocate_response)(pj_stun_session *sess,  
     90                                 pj_status_t status,  
     91                                 pj_stun_tx_data *request, 
     92                                 const pj_stun_msg *response); 
     93 
     94    /** 
     95     * Callback to be called when Set Active Destination response is received 
     96     * or the transaction has timed out. 
     97     * 
     98     * @param sess          The STUN session. 
     99     * @param status        Status of the request. If the value if not 
     100     *                      PJ_SUCCESS, the transaction has timed-out 
     101     *                      or other error has occurred, and the response 
     102     *                      argument may be NULL. 
     103     * @param request       The original STUN request. 
     104     * @param response      The response message, on successful transaction. 
     105     */ 
     106    void (*on_set_active_destination_response)(pj_stun_session *sess,  
     107                                               pj_status_t status,  
     108                                               pj_stun_tx_data *request, 
     109                                               const pj_stun_msg *response); 
     110 
     111    /** 
     112     * Callback to be called when Connect response is received or the  
     113     * transaction has timed out. 
     114     * 
     115     * @param sess          The STUN session. 
     116     * @param status        Status of the request. If the value if not 
     117     *                      PJ_SUCCESS, the transaction has timed-out 
     118     *                      or other error has occurred, and the response 
     119     *                      argument may be NULL. 
     120     * @param request       The original STUN request. 
     121     * @param response      The response message, on successful transaction. 
     122     */ 
     123    void (*on_connect_response)( pj_stun_session *sess,  
     124                                 pj_status_t status,  
     125                                 pj_stun_tx_data *request, 
     126                                 const pj_stun_msg *response); 
    41127} pj_stun_session_cb; 
    42128 
    43129 
     130/** 
     131 * This structure describe the outgoing STUN transmit data to carry the 
     132 * message to be sent. 
     133 */ 
    44134struct pj_stun_tx_data 
    45135{ 
    46136    PJ_DECL_LIST_MEMBER(struct pj_stun_tx_data); 
    47137 
    48     pj_pool_t           *pool; 
    49     pj_stun_session     *sess; 
    50     pj_stun_msg         *msg; 
    51     void                *user_data; 
    52  
    53     pj_stun_client_tsx  *client_tsx; 
    54     pj_uint8_t           client_key[12]; 
     138    pj_pool_t           *pool;          /**< Pool.                          */ 
     139    pj_stun_session     *sess;          /**< The STUN session.              */ 
     140    pj_stun_msg         *msg;           /**< The STUN message.              */ 
     141    void                *user_data;     /**< Arbitrary user data.           */ 
     142 
     143    pj_stun_client_tsx  *client_tsx;    /**< Client STUN transaction.       */ 
     144    pj_uint8_t           client_key[12];/**< Client transaction key.        */ 
     145 
     146    void                *pkt;           /**< The STUN packet.               */ 
     147    unsigned             max_len;       /**< Length of packet buffer.       */ 
     148    unsigned             pkt_size;      /**< The actual length of STUN pkt. */ 
     149 
     150    unsigned             addr_len;      /**< Length of destination address. */ 
     151    const pj_sockaddr_t *dst_addr;      /**< Destination address.           */ 
    55152}; 
    56153 
    57154 
     155/** 
     156 * Options that can be specified when creating or sending outgoing STUN 
     157 * messages. These options may be specified as bitmask. 
     158 */ 
     159enum pj_stun_session_option 
     160{ 
     161    /** 
     162     * Add short term credential to the message. This option may not be used 
     163     * together with PJ_STUN_USE_LONG_TERM_CRED option. 
     164     */ 
     165    PJ_STUN_USE_SHORT_TERM_CRED = 1, 
     166 
     167    /** 
     168     * Add long term credential to the message. This option may not be used 
     169     * together with PJ_STUN_USE_SHORT_TERM_CRED option. 
     170     */ 
     171    PJ_STUN_USE_LONG_TERM_CRED  = 2, 
     172 
     173    /** 
     174     * Add STUN fingerprint to the message. 
     175     */ 
     176    PJ_STUN_USE_FINGERPRINT     = 4 
     177}; 
     178 
     179 
     180/** 
     181 * Create a STUN session. 
     182 * 
     183 * @param endpt     The STUN endpoint, to be used to register timers etc. 
     184 * @param name      Optional name to be associated with this instance. The 
     185 *                  name will be used for example for logging purpose. 
     186 * @param cb        Session callback. 
     187 * @param p_sess    Pointer to receive STUN session instance. 
     188 * 
     189 * @return          PJ_SUCCESS on success, or the appropriate error code. 
     190 */ 
    58191PJ_DECL(pj_status_t) pj_stun_session_create(pj_stun_endpoint *endpt, 
    59192                                            const char *name, 
     
    61194                                            pj_stun_session **p_sess); 
    62195 
     196/** 
     197 * Destroy the STUN session. 
     198 * 
     199 * @param sess      The STUN session instance. 
     200 * 
     201 * @return          PJ_SUCCESS on success, or the appropriate error code. 
     202 */ 
    63203PJ_DECL(pj_status_t) pj_stun_session_destroy(pj_stun_session *sess); 
    64204 
     205/** 
     206 * Associated an arbitrary data with this STUN session. The user data may 
     207 * be retrieved later with pj_stun_session_get_user_data() function. 
     208 * 
     209 * @param sess      The STUN session instance. 
     210 * 
     211 * @return          PJ_SUCCESS on success, or the appropriate error code. 
     212 */ 
    65213PJ_DECL(pj_status_t) pj_stun_session_set_user_data(pj_stun_session *sess, 
    66214                                                   void *user_data); 
    67215 
     216/** 
     217 * Retrieve the user data previously associated to this STUN session with 
     218 * pj_stun_session_set_user_data(). 
     219 * 
     220 * @param sess      The STUN session instance. 
     221 * 
     222 * @return          The user data associated with this STUN session. 
     223 */ 
    68224PJ_DECL(void*) pj_stun_session_get_user_data(pj_stun_session *sess); 
    69225 
    70 PJ_DECL(pj_status_t) pj_stun_session_set_credential(pj_stun_session *sess, 
    71                                                     const pj_str_t *realm, 
    72                                                     const pj_str_t *user, 
    73                                                     const pj_str_t *passwd); 
    74  
    75 PJ_DECL(pj_status_t) pj_stun_session_enable_fingerprint(pj_stun_session *sess, 
    76                                                         pj_bool_t enabled); 
    77  
     226/** 
     227 * Save a long term credential to be used by this STUN session when sending 
     228 * outgoing messages. After long term credential is configured, application 
     229 * may specify PJ_STUN_USE_LONG_TERM_CRED option when sending outgoing STUN 
     230 * message to send the long term credential in the message. 
     231 * 
     232 * @param sess      The STUN session instance. 
     233 * @param realm     Realm of the long term credential. 
     234 * @param user      The user name. 
     235 * @param passwd    The pain-text password. 
     236 * 
     237 * @return          PJ_SUCCESS on success, or the appropriate error code. 
     238 */ 
     239PJ_DECL(pj_status_t)  
     240pj_stun_session_set_long_term_credential(pj_stun_session *sess, 
     241                                         const pj_str_t *realm, 
     242                                         const pj_str_t *user, 
     243                                         const pj_str_t *passwd); 
     244 
     245 
     246/** 
     247 * Save a short term credential to be used by this STUN session when sending 
     248 * outgoing messages. After short term credential is configured, application 
     249 * may specify PJ_STUN_USE_SHORT_TERM_CRED option when sending outgoing STUN 
     250 * message to send the short term credential in the message. 
     251 * 
     252 * @param sess      The STUN session instance. 
     253 * @param user      The user name. 
     254 * @param passwd    The pain-text password. 
     255 * 
     256 * @return          PJ_SUCCESS on success, or the appropriate error code. 
     257 */ 
     258PJ_DECL(pj_status_t)  
     259pj_stun_session_set_short_term_credential(pj_stun_session *sess, 
     260                                          const pj_str_t *user, 
     261                                          const pj_str_t *passwd); 
     262 
     263/** 
     264 * Create a STUN Bind request message. After the message has been  
     265 * successfully created, application can send the message by calling  
     266 * pj_stun_session_send_msg(). 
     267 * 
     268 * @param sess      The STUN session instance. 
     269 * @param p_tdata   Pointer to receive STUN transmit data instance containing 
     270 *                  the request. 
     271 * 
     272 * @return          PJ_SUCCESS on success, or the appropriate error code. 
     273 */ 
    78274PJ_DECL(pj_status_t) pj_stun_session_create_bind_req(pj_stun_session *sess, 
    79275                                                     pj_stun_tx_data **p_tdata); 
    80276 
     277/** 
     278 * Create a STUN Allocate request message. After the message has been 
     279 * successfully created, application can send the message by calling   
     280 * pj_stun_session_send_msg(). 
     281 * 
     282 * @param sess      The STUN session instance. 
     283 * @param p_tdata   Pointer to receive STUN transmit data instance containing 
     284 *                  the request. 
     285 * 
     286 * @return          PJ_SUCCESS on success, or the appropriate error code. 
     287 */ 
    81288PJ_DECL(pj_status_t) pj_stun_session_create_allocate_req(pj_stun_session *sess, 
    82289                                                         pj_stun_tx_data **p_tdata); 
    83290 
     291/** 
     292 * Create a STUN Set Active Destination request message. After the message  
     293 * has been successfully created, application can send the message by calling 
     294 * pj_stun_session_send_msg(). 
     295 * 
     296 * @param sess      The STUN session instance. 
     297 * @param p_tdata   Pointer to receive STUN transmit data instance containing 
     298 *                  the request. 
     299 * 
     300 * @return          PJ_SUCCESS on success, or the appropriate error code. 
     301 */ 
    84302PJ_DECL(pj_status_t)  
    85303pj_stun_session_create_set_active_destination_req(pj_stun_session *sess, 
    86304                                                  pj_stun_tx_data **p_tdata); 
    87305 
     306/** 
     307 * Create a STUN Connect request message. After the message has been  
     308 * successfully created, application can send the message by calling  
     309 * pj_stun_session_send_msg(). 
     310 * 
     311 * @param sess      The STUN session instance. 
     312 * @param p_tdata   Pointer to receive STUN transmit data instance containing 
     313 *                  the request. 
     314 * 
     315 * @return          PJ_SUCCESS on success, or the appropriate error code. 
     316 */ 
    88317PJ_DECL(pj_status_t) pj_stun_session_create_connect_req(pj_stun_session *sess, 
    89318                                                        pj_stun_tx_data **p_tdata); 
    90319 
    91 PJ_DECL(pj_status_t)  
     320/** 
     321 * Create a STUN Connection Status Indication message. After the message  
     322 * has been successfully created, application can send the message by calling 
     323 * pj_stun_session_send_msg(). 
     324 * 
     325 * @param sess      The STUN session instance. 
     326 * @param p_tdata   Pointer to receive STUN transmit data instance containing 
     327 *                  the message. 
     328 * 
     329 * @return          PJ_SUCCESS on success, or the appropriate error code. 
     330 */ 
     331PJ_DECL(pj_status_t) 
    92332pj_stun_session_create_connection_status_ind(pj_stun_session *sess, 
    93333                                             pj_stun_tx_data **p_tdata); 
    94334 
     335/** 
     336 * Create a STUN Send Indication message. After the message has been  
     337 * successfully created, application can send the message by calling  
     338 * pj_stun_session_send_msg(). 
     339 * 
     340 * @param sess      The STUN session instance. 
     341 * @param p_tdata   Pointer to receive STUN transmit data instance containing 
     342 *                  the message. 
     343 * 
     344 * @return          PJ_SUCCESS on success, or the appropriate error code. 
     345 */ 
    95346PJ_DECL(pj_status_t) pj_stun_session_create_send_ind(pj_stun_session *sess, 
    96347                                                     pj_stun_tx_data **p_tdata); 
    97348 
     349/** 
     350 * Create a STUN Data Indication message. After the message has been  
     351 * successfully created, application can send the message by calling  
     352 * pj_stun_session_send_msg(). 
     353 * 
     354 * @param sess      The STUN session instance. 
     355 * @param p_tdata   Pointer to receive STUN transmit data instance containing 
     356 *                  the message. 
     357 * 
     358 * @return          PJ_SUCCESS on success, or the appropriate error code. 
     359 */ 
    98360PJ_DECL(pj_status_t) pj_stun_session_create_data_ind(pj_stun_session *sess, 
    99361                                                     pj_stun_tx_data **p_tdata); 
    100362 
     363/** 
     364 * Send STUN message to the specified destination. This function will encode 
     365 * the pj_stun_msg instance to a packet buffer, and add credential or 
     366 * fingerprint if necessary. If the message is a request, the session will 
     367 * also create and manage a STUN client transaction to be used to manage the 
     368 * retransmission of the request. After the message has been encoded and 
     369 * transaction is setup, the \a on_send_msg() callback of pj_stun_session_cb 
     370 * (which is registered when the STUN session is created) will be called 
     371 * to actually send the message to the wire. 
     372 * 
     373 * @param sess      The STUN session instance. 
     374 * @param options   Optional flags, from pj_stun_session_option. 
     375 * @param addr_len  Length of destination address. 
     376 * @param dst_addr  The destination socket address. 
     377 * @param tdata     The STUN transmit data containing the STUN message to 
     378 *                  be sent. 
     379 * 
     380 * @return          PJ_SUCCESS on success, or the appropriate error code. 
     381 */ 
    101382PJ_DECL(pj_status_t) pj_stun_session_send_msg(pj_stun_session *sess, 
     383                                              unsigned options, 
    102384                                              unsigned addr_len, 
    103                                               const pj_sockaddr_t *server, 
     385                                              const pj_sockaddr_t *dst_addr, 
    104386                                              pj_stun_tx_data *tdata); 
    105387 
     388/** 
     389 * Application must call this function to notify the STUN session about 
     390 * the arrival of STUN packet. The STUN packet MUST have been checked 
     391 * first with #pj_stun_msg_check() to verify that this is indeed a valid 
     392 * STUN packet. 
     393 * 
     394 * The STUN session will decode the packet into pj_stun_msg, and process 
     395 * the message accordingly. If the message is a response, it will search 
     396 * through the outstanding STUN client transactions for a matching 
     397 * transaction ID and hand over the response to the transaction. 
     398 * 
     399 * On successful message processing, application will be notified about 
     400 * the message via one of the pj_stun_session_cb callback. 
     401 * 
     402 * @param sess       The STUN session instance. 
     403 * @param packet     The packet containing STUN message. 
     404 * @param pkt_size   Size of the packet. 
     405 * @param parsed_len Optional pointer to receive the size of the parsed 
     406 *                   STUN message (useful if packet is received via a 
     407 *                   stream oriented protocol). 
     408 * 
     409 * @return           PJ_SUCCESS on success, or the appropriate error code. 
     410 */ 
    106411PJ_DECL(pj_status_t) pj_stun_session_on_rx_pkt(pj_stun_session *sess, 
    107412                                               const void *packet, 
  • pjproject/trunk/pjlib-util/src/pjstun-srv/server_main.c

    r992 r996  
    101101    pj_status_t status; 
    102102 
     103    /* Print to log */ 
     104    PJ_LOG(4,(THIS_FILE, "TX STUN message: \n" 
     105                         "--- begin STUN message ---\n" 
     106                         "%s" 
     107                         "--- end of STUN message ---\n",  
     108              pj_stun_msg_dump(msg, svc->tx_pkt, sizeof(svc->tx_pkt), NULL))); 
     109 
    103110    /* Encode packet */ 
    104111    tx_pkt_len = sizeof(svc->tx_pkt); 
     
    221228    unsigned uattr_cnt; 
    222229    pj_uint16_t uattr_types[16]; 
     230    char dump[512]; 
    223231    pj_status_t status; 
    224232 
     
    242250    } 
    243251 
    244     PJ_LOG(4,(THIS_FILE, "RX STUN %s %s message",  
    245               pj_stun_get_method_name(rx_msg->hdr.type), 
    246               pj_stun_get_class_name(rx_msg->hdr.type))); 
     252    PJ_LOG(4,(THIS_FILE, "RX STUN message: \n" 
     253                         "--- begin STUN message ---\n" 
     254                         "%s" 
     255                         "--- end of STUN message ---\n",  
     256              pj_stun_msg_dump(rx_msg, dump, sizeof(dump), NULL))); 
    247257 
    248258    if (PJ_STUN_IS_REQUEST(rx_msg->hdr.type)) { 
  • pjproject/trunk/pjlib/src/pj/errno.c

    r974 r996  
    153153    pj_assert(buf && bufsize); 
    154154 
    155     if (statcode < PJ_ERRNO_START + PJ_ERRNO_SPACE_SIZE) { 
     155    if (statcode == PJ_SUCCESS) { 
     156        len = pj_ansi_snprintf( buf, bufsize, "Success"); 
     157 
     158    } else if (statcode < PJ_ERRNO_START + PJ_ERRNO_SPACE_SIZE) { 
    156159        len = pj_ansi_snprintf( buf, bufsize, "Unknown error %d", statcode); 
    157160 
Note: See TracChangeset for help on using the changeset viewer.