Changeset 1040 for pjproject


Ignore:
Timestamp:
Mar 5, 2007 12:58:24 AM (18 years ago)
Author:
bennylp
Message:

Implemented new STUN server framework

Location:
pjproject/trunk
Files:
4 added
7 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib-util/build/pjstun_srv_test.dsp

    r1039 r1040  
    4343# PROP Target_Dir "" 
    4444# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c 
    45 # ADD CPP /nologo /MD /W3 /GX /O2 /I "../include" /I "../../pjlib/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /YX /FD /c 
     45# ADD CPP /nologo /MD /W4 /GX /O2 /I "../include" /I "../../pjlib/include" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /YX /FD /c 
    4646# ADD BASE RSC /l 0x409 /d "NDEBUG" 
    4747# ADD RSC /l 0x409 /d "NDEBUG" 
     
    6767# PROP Target_Dir "" 
    6868# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c 
    69 # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /YX /FD /GZ /c 
     69# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "../include" /I "../../pjlib/include" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /YX /FD /GZ /c 
    7070# ADD BASE RSC /l 0x409 /d "_DEBUG" 
    7171# ADD RSC /l 0x409 /d "_DEBUG" 
     
    8888# Begin Source File 
    8989 
     90SOURCE="..\src\pjstun-srv-test\bind_usage.c" 
     91# End Source File 
     92# Begin Source File 
     93 
     94SOURCE="..\src\pjstun-srv-test\main.c" 
     95# End Source File 
     96# Begin Source File 
     97 
    9098SOURCE="..\src\pjstun-srv-test\server.c" 
     99# End Source File 
     100# Begin Source File 
     101 
     102SOURCE="..\src\pjstun-srv-test\usage.c" 
    91103# End Source File 
    92104# End Group 
     
    94106 
    95107# PROP Default_Filter "h;hpp;hxx;hm;inl" 
     108# Begin Source File 
     109 
     110SOURCE="..\src\pjstun-srv-test\server.h" 
     111# End Source File 
    96112# End Group 
    97113# Begin Group "Resource Files" 
  • pjproject/trunk/pjlib-util/src/pjlib-util/stun_endpoint.c

    r1034 r1040  
    4141        return PJ_ENOMEM; 
    4242     
    43     endpt = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_endpoint); 
     43    endpt = PJ_POOL_ZALLOC_T(pool, pj_stun_endpoint); 
    4444    endpt->pool = pool; 
    4545    endpt->pf = factory; 
  • pjproject/trunk/pjlib-util/src/pjlib-util/stun_msg.c

    r1039 r1040  
    527527                     addr_len == sizeof(pj_sockaddr_in6), PJ_EINVAL); 
    528528 
    529     attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_ip_addr_attr); 
     529    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_ip_addr_attr); 
    530530    INIT_ATTR(attr, attr_type, STUN_GENERIC_IP_ADDR_LEN); 
    531531 
     
    581581 
    582582    /* Create the attribute */ 
    583     attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_ip_addr_attr); 
     583    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_ip_addr_attr); 
    584584    pj_memcpy(attr, buf, ATTR_HDR_LEN); 
    585585 
     
    674674    PJ_ASSERT_RETURN(pool && value && p_attr, PJ_EINVAL); 
    675675 
    676     attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_string_attr); 
     676    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_string_attr); 
    677677    INIT_ATTR(attr, attr_type, value->slen); 
    678678    pj_strdup(pool, &attr->value, value); 
     
    713713 
    714714    /* Create the attribute */ 
    715     attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_string_attr); 
     715    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_string_attr); 
    716716 
    717717    /* Copy the header */ 
     
    787787    PJ_ASSERT_RETURN(pool && p_attr, PJ_EINVAL); 
    788788 
    789     attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_empty_attr); 
     789    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_empty_attr); 
    790790    INIT_ATTR(attr, attr_type, sizeof(pj_stun_empty_attr)); 
    791791 
     
    806806 
    807807    /* Create the attribute */ 
    808     attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_empty_attr); 
     808    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_empty_attr); 
    809809    pj_memcpy(attr, buf, ATTR_HDR_LEN); 
    810810 
     
    865865    PJ_ASSERT_RETURN(pool && p_attr, PJ_EINVAL); 
    866866 
    867     attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_uint_attr); 
     867    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_uint_attr); 
    868868    INIT_ATTR(attr, attr_type, STUN_UINT_LEN); 
    869869    attr->value = value; 
     
    905905 
    906906    /* Create the attribute */ 
    907     attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_uint_attr); 
     907    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_uint_attr); 
    908908    pj_memcpy(attr, buf, ATTR_LEN); 
    909909 
     
    968968    PJ_ASSERT_RETURN(pool && p_attr, PJ_EINVAL); 
    969969 
    970     attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_msgint_attr); 
     970    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_msgint_attr); 
    971971    INIT_ATTR(attr, PJ_STUN_ATTR_MESSAGE_INTEGRITY, STUN_MSG_INTEGRITY_LEN); 
    972972 
     
    10041004 
    10051005    /* Create attribute */ 
    1006     attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_msgint_attr); 
     1006    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_msgint_attr); 
    10071007    pj_memcpy(attr, buf, sizeof(pj_stun_msgint_attr)); 
    10081008    attr->hdr.type = pj_ntohs(attr->hdr.type); 
     
    10741074    } 
    10751075 
    1076     attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_errcode_attr); 
     1076    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_errcode_attr); 
    10771077    INIT_ATTR(attr, PJ_STUN_ATTR_ERROR_CODE, 4+err_reason->slen); 
    10781078    attr->err_class = (pj_uint8_t)(err_code / 100); 
     
    11101110 
    11111111    /* Create the attribute */ 
    1112     attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_errcode_attr); 
     1112    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_errcode_attr); 
    11131113 
    11141114    /* Copy the header */ 
     
    11871187    PJ_ASSERT_RETURN(pool && attr_cnt < PJ_STUN_MAX_ATTR && p_attr, PJ_EINVAL); 
    11881188 
    1189     attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_unknown_attr); 
     1189    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_unknown_attr); 
    11901190    INIT_ATTR(attr, PJ_STUN_ATTR_UNKNOWN_ATTRIBUTES, attr_cnt * 2); 
    11911191 
     
    12331233    unsigned i; 
    12341234 
    1235     attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_unknown_attr); 
     1235    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_unknown_attr); 
    12361236    pj_memcpy(attr, buf, ATTR_HDR_LEN); 
    12371237 
     
    13101310    PJ_ASSERT_RETURN(pool && attr_type && p_attr, PJ_EINVAL); 
    13111311 
    1312     attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_binary_attr); 
     1312    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_binary_attr); 
    13131313    INIT_ATTR(attr, attr_type, sizeof(pj_stun_binary_attr)); 
    13141314 
     
    13521352 
    13531353    /* Create the attribute */ 
    1354     attr = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_binary_attr); 
     1354    attr = PJ_POOL_ZALLOC_T(pool, pj_stun_binary_attr); 
    13551355 
    13561356    /* Copy the header */ 
     
    14191419    PJ_ASSERT_RETURN(pool && msg_type && p_msg, PJ_EINVAL); 
    14201420 
    1421     msg = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_msg); 
     1421    msg = PJ_POOL_ZALLOC_T(pool, pj_stun_msg); 
    14221422    msg->hdr.type = (pj_uint16_t) msg_type; 
    14231423    msg->hdr.magic = magic; 
     
    16061606 
    16071607    /* Create the message, copy the header, and convert to host byte order */ 
    1608     msg = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_msg); 
     1608    msg = PJ_POOL_ZALLOC_T(pool, pj_stun_msg); 
    16091609    pj_memcpy(&msg->hdr, pdu, sizeof(pj_stun_msg_hdr)); 
    16101610    msg->hdr.type = pj_ntohs(msg->hdr.type); 
  • pjproject/trunk/pjlib-util/src/pjlib-util/stun_session.c

    r1039 r1040  
    125125    PJ_ASSERT_RETURN(pool, PJ_ENOMEM); 
    126126 
    127     tdata = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_tx_data); 
     127    tdata = PJ_POOL_ZALLOC_T(pool, pj_stun_tx_data); 
    128128    tdata->pool = pool; 
    129129    tdata->sess = sess; 
     
    321321    PJ_ASSERT_RETURN(pool, PJ_ENOMEM); 
    322322 
    323     sess = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_session); 
     323    sess = PJ_POOL_ZALLOC_T(pool, pj_stun_session); 
    324324    sess->endpt = endpt; 
    325325    sess->pool = pool; 
  • pjproject/trunk/pjlib-util/src/pjlib-util/stun_transaction.c

    r1037 r1040  
    7474    PJ_ASSERT_RETURN(cb->on_send_msg, PJ_EINVAL); 
    7575 
    76     tsx = PJ_POOL_ZALLOC_TYPE(pool, pj_stun_client_tsx); 
     76    tsx = PJ_POOL_ZALLOC_T(pool, pj_stun_client_tsx); 
    7777    tsx->endpt = endpt; 
    7878    pj_memcpy(&tsx->cb, cb, sizeof(*cb)); 
  • pjproject/trunk/pjlib-util/src/pjstun-srv-test/server.c

    r1039 r1040  
    1717 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA  
    1818 */ 
    19 #include <pjlib-util.h> 
    20 #include <pjlib.h> 
    2119 
    22 #include <stdio.h> 
    23 #include <conio.h> 
     20#include "server.h" 
    2421 
     22#define THIS_FILE       "server.c" 
    2523 
    26 #define THIS_FILE       "server_main.c" 
    27 #define MAX_THREADS     8 
    28 #define MAX_SERVICE     16 
    29 #define MAX_PKT_LEN     512 
     24struct pj_stun_server 
     25{ 
     26    pj_stun_server_info si; 
    3027 
    31 struct service 
    32 { 
    33     unsigned             index; 
    34     pj_uint16_t          port; 
    35     pj_bool_t            is_stream; 
    36     pj_sock_t            sock; 
    37     pj_ioqueue_key_t    *key; 
    38     pj_ioqueue_op_key_t  recv_opkey, 
    39                          send_opkey; 
     28    pj_pool_t           *pool; 
    4029 
    41     pj_stun_session     *sess; 
    42  
    43     int                  src_addr_len; 
    44     pj_sockaddr_in       src_addr; 
    45     pj_ssize_t           rx_pkt_len; 
    46     pj_uint8_t           rx_pkt[MAX_PKT_LEN]; 
    47     pj_uint8_t           tx_pkt[MAX_PKT_LEN]; 
     30    pj_bool_t            thread_quit_flag; 
     31    pj_thread_t        **threads; 
    4832}; 
    4933 
    50 static struct stun_server 
    51 { 
    52     pj_caching_pool      cp; 
    53     pj_pool_t           *pool; 
    54     pj_stun_endpoint    *endpt; 
    55     pj_ioqueue_t        *ioqueue; 
    56     pj_timer_heap_t     *timer_heap; 
    57     unsigned             service_cnt; 
    58     struct service       services[MAX_SERVICE]; 
    59  
    60     pj_bool_t            thread_quit_flag; 
    61     unsigned             thread_cnt; 
    62     pj_thread_t         *threads[16]; 
    63  
    64  
    65 } server; 
    66  
    67 static struct options 
    68 { 
    69     char        *realm; 
    70     char        *user_name; 
    71     char        *password; 
    72     char        *nonce; 
    73     pj_bool_t    use_fingerprint; 
    74 } o; 
    75  
    76 static pj_status_t server_perror(const char *sender, const char *title,  
    77                                  pj_status_t status) 
     34PJ_DEF(pj_status_t) pj_stun_perror( const char *sender,  
     35                                    const char *title,  
     36                                    pj_status_t status) 
    7837{ 
    7938    char errmsg[PJ_ERR_MSG_SIZE]; 
     
    8140 
    8241    PJ_LOG(3,(sender, "%s: %s", title, errmsg)); 
    83  
    8442    return status; 
    8543} 
    8644 
    87  
    88 /* Callback to be called to send outgoing message */ 
    89 static pj_status_t on_send_msg(pj_stun_session *sess, 
    90                                const void *pkt, 
    91                                pj_size_t pkt_size, 
    92                                const pj_sockaddr_t *dst_addr, 
    93                                unsigned addr_len) 
    94 { 
    95     struct service *svc; 
    96     pj_ssize_t length; 
    97     pj_status_t status; 
    98  
    99     svc = (struct service*) pj_stun_session_get_user_data(sess); 
    100  
    101     /* Send packet */ 
    102     length = pkt_size; 
    103     if (svc->is_stream) { 
    104         status = pj_ioqueue_send(svc->key, &svc->send_opkey, pkt, &length, 0); 
    105     } else { 
    106 #if 0 
    107         pj_pool_t *pool; 
    108         char *buf; 
    109         pj_stun_msg *msg; 
    110  
    111         pool = pj_pool_create(&server.cp.factory, "", 4000, 4000, NULL); 
    112         status = pj_stun_msg_decode(pool, pkt, pkt_size, PJ_STUN_CHECK_PACKET, &msg, NULL, NULL); 
    113         buf = pj_pool_alloc(pool, 512); 
    114         PJ_LOG(3,("", "%s", pj_stun_msg_dump(msg, buf, 512, NULL))); 
    115 #endif 
    116         status = pj_ioqueue_sendto(svc->key, &svc->send_opkey, pkt, &length,  
    117                                    0, dst_addr, addr_len); 
    118     } 
    119  
    120     return (status == PJ_SUCCESS || status == PJ_EPENDING) ?  
    121             PJ_SUCCESS : status; 
    122 } 
    123  
    124  
    125 /* Handle STUN binding request */ 
    126 static pj_status_t on_rx_binding_request(pj_stun_session *sess, 
    127                                          const pj_uint8_t *pkt, 
    128                                          unsigned pkt_len, 
    129                                          const pj_stun_msg *msg, 
    130                                          const pj_sockaddr_t *src_addr, 
    131                                          unsigned src_addr_len) 
    132 { 
    133     struct service *svc = (struct service *) pj_stun_session_get_user_data(sess); 
    134     pj_stun_tx_data *tdata; 
    135     pj_status_t status; 
    136  
    137     /* Create response */ 
    138     status = pj_stun_session_create_response(sess, msg, 0, NULL, &tdata); 
    139     if (status != PJ_SUCCESS) 
    140         return status; 
    141  
    142     /* Create MAPPED-ADDRESS attribute */ 
    143     status = pj_stun_msg_add_ip_addr_attr(tdata->pool, tdata->msg, 
    144                                           PJ_STUN_ATTR_MAPPED_ADDR, 
    145                                           PJ_FALSE, 
    146                                           src_addr, src_addr_len); 
    147     if (status != PJ_SUCCESS) { 
    148         server_perror(THIS_FILE, "Error creating response", status); 
    149         pj_stun_msg_destroy_tdata(sess, tdata); 
    150         return status; 
    151     } 
    152  
    153     /* On the presence of magic, create XOR-MAPPED-ADDRESS attribute */ 
    154     if (msg->hdr.magic == PJ_STUN_MAGIC) { 
    155         status =  
    156             pj_stun_msg_add_ip_addr_attr(tdata->pool, tdata->msg, 
    157                                          PJ_STUN_ATTR_XOR_MAPPED_ADDRESS, 
    158                                          PJ_TRUE, 
    159                                          src_addr, src_addr_len); 
    160         if (status != PJ_SUCCESS) { 
    161             server_perror(THIS_FILE, "Error creating response", status); 
    162             pj_stun_msg_destroy_tdata(sess, tdata); 
    163             return status; 
    164         } 
    165     } 
    166  
    167     /* Send */ 
    168     status = pj_stun_session_send_msg(sess, PJ_TRUE,  
    169                                       src_addr, src_addr_len, tdata); 
    170     return status; 
    171 } 
    172  
    173  
    174 /* Handle unknown request */ 
    175 static pj_status_t on_rx_unknown_request(pj_stun_session *sess, 
    176                                          const pj_uint8_t *pkt, 
    177                                          unsigned pkt_len, 
    178                                          const pj_stun_msg *msg, 
    179                                          const pj_sockaddr_t *src_addr, 
    180                                          unsigned src_addr_len) 
    181 { 
    182     pj_stun_tx_data *tdata; 
    183     pj_status_t status; 
    184  
    185     /* Create response */ 
    186     status = pj_stun_session_create_response(sess, msg,  
    187                                              PJ_STUN_STATUS_BAD_REQUEST, 
    188                                              NULL, &tdata); 
    189     if (status != PJ_SUCCESS) 
    190         return status; 
    191  
    192     /* Send */ 
    193     status = pj_stun_session_send_msg(sess, 0, src_addr, src_addr_len, tdata); 
    194     return status; 
    195 } 
    196  
    197 /* Callback to be called by STUN session on incoming STUN requests */ 
    198 static pj_status_t on_rx_request(pj_stun_session *sess, 
    199                                  const pj_uint8_t *pkt, 
    200                                  unsigned pkt_len, 
    201                                  const pj_stun_msg *msg, 
    202                                  const pj_sockaddr_t *src_addr, 
    203                                  unsigned src_addr_len) 
    204 { 
    205     switch (PJ_STUN_GET_METHOD(msg->hdr.type)) { 
    206     case PJ_STUN_BINDING_METHOD: 
    207         return on_rx_binding_request(sess, pkt, pkt_len, msg,  
    208                                      src_addr, src_addr_len); 
    209     default: 
    210         return on_rx_unknown_request(sess, pkt, pkt_len, msg, 
    211                                      src_addr, src_addr_len); 
    212     } 
    213 } 
    214  
    215  
    216 /* Callback on ioqueue read completion */ 
    217 static void on_read_complete(pj_ioqueue_key_t *key,  
    218                              pj_ioqueue_op_key_t *op_key,  
    219                              pj_ssize_t bytes_read) 
    220 { 
    221     struct service *svc = (struct service *) pj_ioqueue_get_user_data(key); 
    222     pj_status_t status; 
    223  
    224     if (bytes_read <= 0) 
    225         goto next_read; 
    226  
    227     /* Handle packet to session */ 
    228     status = pj_stun_session_on_rx_pkt(svc->sess, svc->rx_pkt, bytes_read, 
    229                                        PJ_STUN_IS_DATAGRAM | PJ_STUN_CHECK_PACKET, 
    230                                        NULL, &svc->src_addr, svc->src_addr_len); 
    231     if (status != PJ_SUCCESS) { 
    232         server_perror(THIS_FILE, "Error processing incoming packet", status); 
    233     } 
    234  
    235 next_read: 
    236     if (bytes_read < 0) { 
    237         server_perror(THIS_FILE, "on_read_complete()", -bytes_read); 
    238     } 
    239  
    240     svc->rx_pkt_len = sizeof(svc->rx_pkt); 
    241     svc->src_addr_len = sizeof(svc->src_addr); 
    242  
    243     status = pj_ioqueue_recvfrom(svc->key, &svc->recv_opkey,  
    244                                  svc->rx_pkt, &svc->rx_pkt_len,  
    245                                  PJ_IOQUEUE_ALWAYS_ASYNC, 
    246                                  &svc->src_addr, &svc->src_addr_len); 
    247     if (status != PJ_EPENDING) 
    248         server_perror(THIS_FILE, "error starting async read", status); 
    249 } 
    250  
    251  
    252 static pj_status_t init_service(struct service *svc) 
    253 { 
    254     pj_status_t status; 
    255     pj_ioqueue_callback service_callback; 
    256     pj_stun_session_cb sess_cb; 
    257     pj_sockaddr_in addr; 
    258  
    259     status = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &svc->sock); 
    260     if (status != PJ_SUCCESS) 
    261         return status; 
    262  
    263     status = pj_sockaddr_in_init(&addr, NULL, svc->port); 
    264     if (status != PJ_SUCCESS) 
    265         goto on_error; 
    266      
    267     status = pj_sock_bind(svc->sock, &addr, sizeof(addr)); 
    268     if (status != PJ_SUCCESS) 
    269         goto on_error; 
    270  
    271     pj_bzero(&sess_cb, sizeof(sess_cb)); 
    272     sess_cb.on_send_msg = &on_send_msg; 
    273     sess_cb.on_rx_request = &on_rx_request; 
    274     status = pj_stun_session_create(server.endpt, "session",  
    275                                     &sess_cb,  
    276                                     o.use_fingerprint!=0,  
    277                                     &svc->sess); 
    278     if (status != PJ_SUCCESS) 
    279         goto on_error; 
    280  
    281     pj_stun_session_set_user_data(svc->sess, (void*)svc); 
    282  
    283     if (o.user_name) { 
    284         pj_stun_auth_cred cred; 
    285  
    286         pj_bzero(&cred, sizeof(cred)); 
    287  
    288         cred.type = PJ_STUN_AUTH_CRED_STATIC; 
    289         cred.data.static_cred.realm = pj_str(o.realm); 
    290         cred.data.static_cred.username = pj_str(o.user_name); 
    291         cred.data.static_cred.data_type = 0; 
    292         cred.data.static_cred.data = pj_str(o.password); 
    293         cred.data.static_cred.nonce = pj_str(o.nonce); 
    294  
    295         pj_stun_session_set_credential(svc->sess, &cred); 
    296         puts("Session credential set"); 
    297     } else { 
    298         puts("Credential not set"); 
    299     } 
    300  
    301     pj_bzero(&service_callback, sizeof(service_callback)); 
    302     service_callback.on_read_complete = &on_read_complete; 
    303  
    304     status = pj_ioqueue_register_sock(server.pool, server.ioqueue, svc->sock, 
    305                                       svc, &service_callback, &svc->key); 
    306     if (status != PJ_SUCCESS) 
    307         goto on_error; 
    308  
    309  
    310     pj_ioqueue_op_key_init(&svc->recv_opkey, sizeof(svc->recv_opkey)); 
    311     pj_ioqueue_op_key_init(&svc->send_opkey, sizeof(svc->send_opkey)); 
    312  
    313     on_read_complete(svc->key, &svc->recv_opkey, 0); 
    314  
    315     PJ_LOG(4,(THIS_FILE, "Service started on port %d", svc->port)); 
    316     return PJ_SUCCESS; 
    317  
    318 on_error: 
    319     if (svc->key != NULL) { 
    320         pj_ioqueue_unregister(svc->key); 
    321         svc->key = NULL; 
    322         svc->sock = PJ_INVALID_SOCKET; 
    323     } else if (svc->sock != 0 && svc->sock != PJ_INVALID_SOCKET) { 
    324         pj_sock_close(svc->sock); 
    325         svc->sock = PJ_INVALID_SOCKET; 
    326     } 
    327  
    328     return status; 
    329 } 
    330  
    331  
    33245static int worker_thread(void *p) 
    33346{ 
    334     PJ_UNUSED_ARG(p); 
     47    pj_stun_server *srv = (pj_stun_server*)p; 
    33548 
    336     while (!server.thread_quit_flag) { 
     49    while (!srv->thread_quit_flag) { 
    33750        pj_time_val timeout = { 0, 50 }; 
    338         pj_timer_heap_poll(server.timer_heap, NULL); 
    339         pj_ioqueue_poll(server.ioqueue, &timeout); 
     51        pj_timer_heap_poll(srv->si.timer_heap, NULL); 
     52        pj_ioqueue_poll(srv->si.ioqueue, &timeout); 
    34053    } 
    34154 
     
    34457 
    34558 
    346 pj_status_t server_init(void) 
     59PJ_DEF(pj_status_t) pj_stun_server_create(pj_pool_factory *pf, 
     60                                          unsigned thread_cnt, 
     61                                          pj_stun_server **p_srv) 
    34762{ 
     63    pj_pool_t *pool; 
     64    pj_stun_server *srv; 
     65    unsigned i; 
    34866    pj_status_t status; 
    34967 
    350     status = pj_init(); 
     68    pool = pj_pool_create(pf, "server%p", 4000, 4000, NULL); 
     69 
     70    srv = PJ_POOL_ZALLOC_T(pool, pj_stun_server); 
     71    srv->pool = pool; 
     72    srv->si.pf = pf; 
     73 
     74    status = pj_ioqueue_create(srv->pool, PJ_IOQUEUE_MAX_HANDLES,  
     75                               &srv->si.ioqueue); 
    35176    if (status != PJ_SUCCESS) 
    352         return server_perror(THIS_FILE, "pj_init() error", status); 
     77        goto on_error; 
    35378 
    354     status = pjlib_util_init(); 
     79    status = pj_timer_heap_create(srv->pool, 1024, &srv->si.timer_heap); 
    35580    if (status != PJ_SUCCESS) 
    356         return server_perror(THIS_FILE, "pjlib_util_init() error", status); 
     81        goto on_error; 
    35782 
    358     pj_caching_pool_init(&server.cp,  
    359                          &pj_pool_factory_default_policy, 0); 
     83    status = pj_stun_endpoint_create(srv->si.pf, 0, srv->si.ioqueue,  
     84                                     srv->si.timer_heap, &srv->si.endpt); 
     85    if (status != PJ_SUCCESS) 
     86        goto on_error; 
     87 
     88    srv->si.thread_cnt = thread_cnt; 
     89    srv->threads = pj_pool_calloc(pool, thread_cnt, sizeof(pj_thread_t*)); 
     90    for (i=0; i<thread_cnt; ++i) { 
     91        status = pj_thread_create(pool, "worker%p", &worker_thread, 
     92                                  srv, 0, 0, &srv->threads[i]); 
     93        if (status != PJ_SUCCESS) 
     94            goto on_error; 
     95    } 
     96 
     97    *p_srv = srv; 
     98    return PJ_SUCCESS; 
     99 
     100on_error: 
     101    pj_stun_server_destroy(srv); 
     102    return status; 
     103} 
    360104 
    361105 
    362     server.pool = pj_pool_create(&server.cp.factory, "server", 4000, 4000, 
    363                                  NULL); 
     106PJ_DEF(pj_stun_server_info*) pj_stun_server_get_info(pj_stun_server *srv) 
     107{ 
     108    return &srv->si; 
     109} 
    364110 
    365     status = pj_ioqueue_create(server.pool, PJ_IOQUEUE_MAX_HANDLES,  
    366                                &server.ioqueue); 
    367     if (status != PJ_SUCCESS) 
    368         return server_perror(THIS_FILE, "pj_ioqueue_create()", status); 
    369111 
    370     status = pj_timer_heap_create(server.pool, 1024, &server.timer_heap); 
    371     if (status != PJ_SUCCESS) 
    372         return server_perror(THIS_FILE, "Error creating timer heap", status); 
     112PJ_DEF(pj_status_t) pj_stun_server_destroy(pj_stun_server *srv) 
     113{ 
     114    unsigned i; 
    373115 
    374     status = pj_stun_endpoint_create(&server.cp.factory, 0,  
    375                                      server.ioqueue, server.timer_heap,  
    376                                      &server.endpt); 
    377     if (status != PJ_SUCCESS) 
    378         return server_perror(THIS_FILE, "Error creating endpoint", status); 
     116    srv->thread_quit_flag = PJ_TRUE; 
     117    for (i=0; i<srv->si.thread_cnt; ++i) { 
     118        pj_thread_join(srv->threads[i]); 
     119        srv->threads[i] = NULL; 
     120    } 
    379121 
    380     server.service_cnt = 1; 
    381     server.services[0].index = 0; 
    382     server.services[0].port = PJ_STUN_PORT; 
    383  
    384     status = init_service(&server.services[0]); 
    385     if (status != PJ_SUCCESS) 
    386         return server_perror(THIS_FILE, "init_service() error", status); 
     122    pj_stun_endpoint_destroy(srv->si.endpt); 
     123    pj_timer_heap_destroy(srv->si.timer_heap); 
     124    pj_ioqueue_destroy(srv->si.ioqueue); 
     125    pj_pool_release(srv->pool); 
    387126 
    388127    return PJ_SUCCESS; 
     
    390129 
    391130 
    392 pj_status_t server_main(void) 
    393 { 
    394 #if 0 
    395     for (;;) { 
    396         pj_time_val timeout = { 0, 50 }; 
    397         pj_timer_heap_poll(server.timer_heap, NULL); 
    398         pj_ioqueue_poll(server.ioqueue, &timeout); 
    399  
    400         if (kbhit() && _getch()==27) 
    401             break; 
    402     } 
    403 #else 
    404     pj_status_t status; 
    405  
    406     status = pj_thread_create(server.pool, "stun_server", &worker_thread, NULL, 
    407                               0, 0, &server.threads[0]); 
    408     if (status != PJ_SUCCESS) 
    409         return server_perror(THIS_FILE, "create_thread() error", status); 
    410  
    411     while (!server.thread_quit_flag) { 
    412         char line[10]; 
    413  
    414         printf("Menu:\n" 
    415                "  q     Quit\n" 
    416                "Choice:"); 
    417  
    418         fgets(line, sizeof(line), stdin); 
    419         if (line[0] == 'q') 
    420             server.thread_quit_flag = 1; 
    421     } 
    422  
    423 #endif 
    424  
    425     return PJ_SUCCESS; 
    426 } 
    427  
    428  
    429 pj_status_t server_destroy(void) 
    430 { 
    431     unsigned i; 
    432  
    433     for (i=0; i<PJ_ARRAY_SIZE(server.services); ++i) { 
    434         struct service *svc = &server.services[i]; 
    435  
    436         if (svc->key != NULL) { 
    437             pj_ioqueue_unregister(svc->key); 
    438             svc->key = NULL; 
    439             svc->sock = PJ_INVALID_SOCKET; 
    440         } else if (svc->sock != 0 && svc->sock != PJ_INVALID_SOCKET) { 
    441             pj_sock_close(svc->sock); 
    442             svc->sock = PJ_INVALID_SOCKET; 
    443         } 
    444     } 
    445  
    446     server.thread_quit_flag = PJ_TRUE; 
    447     for (i=0; i<PJ_ARRAY_SIZE(server.threads); ++i) { 
    448         if (server.threads[i]) { 
    449             pj_thread_join(server.threads[i]); 
    450             pj_thread_destroy(server.threads[i]); 
    451             server.threads[i] = NULL; 
    452         } 
    453     } 
    454  
    455     pj_stun_session_destroy(server.services[0].sess); 
    456     pj_stun_endpoint_destroy(server.endpt); 
    457     pj_ioqueue_destroy(server.ioqueue); 
    458     pj_pool_release(server.pool); 
    459  
    460     pj_pool_factory_dump(&server.cp.factory, PJ_TRUE); 
    461     pj_caching_pool_destroy(&server.cp); 
    462  
    463     pj_shutdown(); 
    464  
    465     return PJ_SUCCESS; 
    466 } 
    467  
    468  
    469 static void usage(void) 
    470 { 
    471     puts("Usage: pjstun_srv_test [OPTIONS]"); 
    472     puts(""); 
    473     puts("where OPTIONS:"); 
    474     puts(" --realm, -r       Set realm of the credential"); 
    475     puts(" --username, -u    Set username of the credential"); 
    476     puts(" --password, -p    Set password of the credential"); 
    477     puts(" --nonce, -N       Set NONCE");       
    478     puts(" --fingerprint, -F Use fingerprint for outgoing requests"); 
    479     puts(" --help, -h"); 
    480 } 
    481  
    482  
    483 int main(int argc, char *argv[]) 
    484 { 
    485     struct pj_getopt_option long_options[] = { 
    486         { "realm",      1, 0, 'r'}, 
    487         { "username",   1, 0, 'u'}, 
    488         { "password",   1, 0, 'p'}, 
    489         { "nonce",      1, 0, 'N'}, 
    490         { "fingerprint",0, 0, 'F'}, 
    491         { "help",       0, 0, 'h'} 
    492     }; 
    493     int c, opt_id; 
    494  
    495     while((c=pj_getopt_long(argc,argv, "r:u:p:hF", long_options, &opt_id))!=-1) { 
    496         switch (c) { 
    497         case 'r': 
    498             o.realm = pj_optarg; 
    499             break; 
    500         case 'u': 
    501             o.user_name = pj_optarg; 
    502             break; 
    503         case 'p': 
    504             o.password = pj_optarg; 
    505             break; 
    506         case 'N': 
    507             o.nonce = pj_optarg; 
    508             break; 
    509         case 'h': 
    510             usage(); 
    511             return 0; 
    512         case 'F': 
    513             o.use_fingerprint = PJ_TRUE; 
    514             break; 
    515         default: 
    516             printf("Argument \"%s\" is not valid. Use -h to see help", 
    517                    argv[pj_optind]); 
    518             return 1; 
    519         } 
    520     } 
    521  
    522     if (pj_optind != argc) { 
    523         puts("Error: invalid arguments"); 
    524         return 1; 
    525     } 
    526  
    527  
    528     if (server_init()) { 
    529         server_destroy(); 
    530         return 1; 
    531     } 
    532  
    533     server_main(); 
    534     server_destroy(); 
    535  
    536     return 0; 
    537 } 
  • pjproject/trunk/pjlib/include/pj/pool.h

    r992 r1040  
    443443 * @return pointer to the allocated memory. 
    444444 * 
    445  * @see PJ_POOL_ALLOC_TYPE 
     445 * @see PJ_POOL_ALLOC_T 
    446446 */ 
    447447PJ_IDECL(void*) pj_pool_alloc( pj_pool_t *pool, pj_size_t size); 
     
    470470 * @return          Pointer to the allocated memory. 
    471471 * 
    472  * @see PJ_POOL_ZALLOC_TYPE 
     472 * @see PJ_POOL_ZALLOC_T 
    473473 */ 
    474474PJ_INLINE(void*) pj_pool_zalloc(pj_pool_t *pool, pj_size_t size) 
     
    489489 * @return          Memory buffer of the specified type. 
    490490 */ 
    491 #define PJ_POOL_ALLOC_TYPE(pool,type) \ 
     491#define PJ_POOL_ALLOC_T(pool,type) \ 
    492492            ((type*)pj_pool_alloc(pool, sizeof(type))) 
    493493 
     
    503503 * @return          Memory buffer of the specified type. 
    504504 */ 
    505 #define PJ_POOL_ZALLOC_TYPE(pool,type) \ 
     505#define PJ_POOL_ZALLOC_T(pool,type) \ 
    506506            ((type*)pj_pool_zalloc(pool, sizeof(type))) 
    507507 
Note: See TracChangeset for help on using the changeset viewer.