Changeset 6004


Ignore:
Timestamp:
May 24, 2019 3:32:17 AM (5 years ago)
Author:
riza
Message:

Close #1017: TURN TLS transport implementation.

Location:
pjproject/trunk
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib/include/pj/ssl_sock.h

    r5938 r6004  
    299299                                                 const char *error_strings[], 
    300300                                                 unsigned *count); 
     301 
     302/**  
     303 * Wipe out the keys in the SSL certificate.  
     304 * 
     305 * @param cert          The SSL certificate.  
     306 * 
     307 */ 
     308PJ_DECL(void) pj_ssl_cert_wipe_keys(pj_ssl_cert_t *cert); 
    301309 
    302310 
     
    10501058 
    10511059/** 
     1060 * The parameter for pj_ssl_sock_start_connect2(). 
     1061 */ 
     1062typedef struct pj_ssl_start_connect_param { 
     1063    /** 
     1064     * The pool to allocate some internal data for the operation. 
     1065     */ 
     1066    pj_pool_t *pool; 
     1067 
     1068    /** 
     1069     * Local address. 
     1070     */ 
     1071    const pj_sockaddr_t *localaddr; 
     1072 
     1073    /** 
     1074     * Port range for socket binding, relative to the start port number 
     1075     * specified in \a localaddr. This is only applicable when the start port 
     1076     * number is non zero. 
     1077     */ 
     1078    pj_uint16_t local_port_range; 
     1079 
     1080    /** 
     1081     * Remote address. 
     1082     */ 
     1083    const pj_sockaddr_t *remaddr; 
     1084 
     1085    /** 
     1086     * Length of buffer containing above addresses. 
     1087     */ 
     1088    int addr_len; 
     1089 
     1090} pj_ssl_start_connect_param; 
     1091 
     1092 
     1093/** 
    10521094 * Initialize the secure socket parameters for its creation with  
    10531095 * the default values. 
     
    13691411                                               int addr_len); 
    13701412 
     1413/** 
     1414 * Same as #pj_ssl_sock_start_connect(), but application can provide a  
     1415 * \a port_range parameter, which will be used to bind the socket to  
     1416 * random port. 
     1417 * 
     1418 * @param ssock         The secure socket. 
     1419 * 
     1420 * @param connect_param The parameter, refer to \a pj_ssl_start_connect_param. 
     1421 * 
     1422 * @return              PJ_SUCCESS if connection can be established immediately 
     1423 *                      or PJ_EPENDING if connection cannot be established  
     1424 *                      immediately. In this case the \a on_connect_complete() 
     1425 *                      callback will be called when connection is complete.  
     1426 *                      Any other return value indicates error condition. 
     1427 */ 
     1428PJ_DECL(pj_status_t) pj_ssl_sock_start_connect2( 
     1429                              pj_ssl_sock_t *ssock, 
     1430                              pj_ssl_start_connect_param *connect_param); 
    13711431 
    13721432/** 
     
    13861446PJ_DECL(pj_status_t) pj_ssl_sock_renegotiate(pj_ssl_sock_t *ssock); 
    13871447 
    1388  
    13891448/** 
    13901449 * @} 
  • pjproject/trunk/pjlib/src/pj/ssl_sock_imp_common.c

    r5990 r6004  
    3131#   define PJ_SSL_SOCK_DELAYED_CLOSE_TIMEOUT    500 
    3232#endif 
     33 
     34enum { MAX_BIND_RETRY = 100 }; 
    3335 
    3436#ifdef SSL_SOCK_IMP_USE_CIRC_BUF 
     
    597599} 
    598600 
    599  
    600 static void wipe_buf(pj_str_t *buf) 
    601 { 
    602     volatile char *p = buf->ptr; 
    603     pj_ssize_t len = buf->slen; 
    604     while (len--) *p++ = 0; 
    605     buf->slen = 0; 
    606 } 
    607  
    608 static void wipe_cert_buffer(pj_ssl_cert_t *cert) 
    609 { 
    610     wipe_buf(&cert->CA_file); 
    611     wipe_buf(&cert->CA_path); 
    612     wipe_buf(&cert->cert_file); 
    613     wipe_buf(&cert->privkey_file); 
    614     wipe_buf(&cert->privkey_pass); 
    615     wipe_buf(&cert->CA_buf); 
    616     wipe_buf(&cert->cert_buf); 
    617     wipe_buf(&cert->privkey_buf); 
    618 } 
    619  
    620601static void ssl_on_destroy(void *arg) 
    621602{ 
     
    633614        ssock->circ_buf_output_mutex = NULL; 
    634615        ssock->write_mutex = NULL; 
    635     } 
    636  
    637     /* Wipe out cert & key buffer, note that they may not be allocated 
    638      * using SSL socket memory pool. 
    639      */ 
    640     if (ssock->cert) { 
    641         wipe_cert_buffer(ssock->cert); 
    642616    } 
    643617 
     
    13631337 
    13641338    ssl_reset_sock_state(ssock); 
     1339 
     1340    /* Wipe out cert & key buffer. */ 
     1341    if (ssock->cert) { 
     1342        pj_ssl_cert_wipe_keys(ssock->cert); 
     1343        ssock->cert = NULL; 
     1344    } 
     1345 
    13651346    if (ssock->param.grp_lock) { 
    13661347        pj_grp_lock_dec_ref(ssock->param.grp_lock); 
     
    18831864 * Starts asynchronous socket connect() operation. 
    18841865 */ 
    1885 PJ_DEF(pj_status_t) pj_ssl_sock_start_connect( pj_ssl_sock_t *ssock, 
    1886                                                pj_pool_t *pool, 
    1887                                                const pj_sockaddr_t *localaddr, 
    1888                                                const pj_sockaddr_t *remaddr, 
    1889                                                int addr_len) 
     1866PJ_DEF(pj_status_t) pj_ssl_sock_start_connect(pj_ssl_sock_t *ssock, 
     1867                                              pj_pool_t *pool, 
     1868                                              const pj_sockaddr_t *localaddr, 
     1869                                              const pj_sockaddr_t *remaddr, 
     1870                                              int addr_len) 
     1871{ 
     1872    pj_ssl_start_connect_param param;     
     1873    param.pool = pool; 
     1874    param.localaddr = localaddr; 
     1875    param.local_port_range = 0; 
     1876    param.remaddr = remaddr; 
     1877    param.addr_len = addr_len; 
     1878 
     1879    return pj_ssl_sock_start_connect2(ssock, &param); 
     1880} 
     1881 
     1882PJ_DEF(pj_status_t) pj_ssl_sock_start_connect2( 
     1883                               pj_ssl_sock_t *ssock, 
     1884                               pj_ssl_start_connect_param *connect_param) 
    18901885{ 
    18911886    pj_activesock_cb asock_cb; 
    18921887    pj_activesock_cfg asock_cfg; 
    18931888    pj_status_t status; 
     1889     
     1890    pj_pool_t *pool = connect_param->pool; 
     1891    const pj_sockaddr_t *localaddr = connect_param->localaddr; 
     1892    pj_uint16_t port_range = connect_param->local_port_range; 
     1893    const pj_sockaddr_t *remaddr = connect_param->remaddr; 
     1894    int addr_len = connect_param->addr_len; 
    18941895 
    18951896    PJ_ASSERT_RETURN(ssock && pool && localaddr && remaddr && addr_len, 
     
    19191920 
    19201921    /* Bind socket */ 
    1921     status = pj_sock_bind(ssock->sock, localaddr, addr_len); 
     1922    if (port_range) { 
     1923        pj_uint16_t max_bind_retry = MAX_BIND_RETRY; 
     1924        if (port_range && port_range < max_bind_retry) 
     1925        { 
     1926            max_bind_retry = port_range; 
     1927        } 
     1928        status = pj_sock_bind_random(ssock->sock, localaddr, port_range, 
     1929                                     max_bind_retry); 
     1930    } else { 
     1931        status = pj_sock_bind(ssock->sock, localaddr, addr_len); 
     1932    } 
     1933 
    19221934    if (status != PJ_SUCCESS) 
    19231935        goto on_error; 
     
    20132025} 
    20142026 
     2027static void wipe_buf(pj_str_t *buf) 
     2028{ 
     2029    volatile char *p = buf->ptr; 
     2030    pj_ssize_t len = buf->slen; 
     2031    while (len--) *p++ = 0; 
     2032    buf->slen = 0; 
     2033} 
     2034 
     2035PJ_DEF(void) pj_ssl_cert_wipe_keys(pj_ssl_cert_t *cert) 
     2036{     
     2037    if (cert) { 
     2038        wipe_buf(&cert->CA_file); 
     2039        wipe_buf(&cert->CA_path); 
     2040        wipe_buf(&cert->cert_file); 
     2041        wipe_buf(&cert->privkey_file); 
     2042        wipe_buf(&cert->privkey_pass); 
     2043        wipe_buf(&cert->CA_buf); 
     2044        wipe_buf(&cert->cert_buf); 
     2045        wipe_buf(&cert->privkey_buf); 
     2046    } 
     2047} 
     2048 
    20152049/* Load credentials from files. */ 
    20162050PJ_DEF(pj_status_t) pj_ssl_cert_load_from_files (pj_pool_t *pool, 
  • pjproject/trunk/pjlib/src/pj/ssl_sock_ossl.c

    r5990 r6004  
    10571057     */ 
    10581058    if (cert && (!ssock->is_server || ssock->parent)) { 
    1059         wipe_cert_buffer(cert); 
     1059        pj_ssl_cert_wipe_keys(cert);     
    10601060    } 
    10611061 
  • pjproject/trunk/pjnath/include/pjnath/turn_session.h

    r5987 r6004  
    152152     * TLS transport. The TLS transport will only be used as the connection 
    153153     * type to reach the server and never as the allocation transport type. 
    154      */ 
    155     PJ_TURN_TP_TLS = 255 
     154     * The value corresponds to IANA protocol number. 
     155     */ 
     156    PJ_TURN_TP_TLS = 56 
    156157 
    157158} pj_turn_tp_type; 
  • pjproject/trunk/pjnath/include/pjnath/turn_sock.h

    r5987 r6004  
    2727#include <pjnath/turn_session.h> 
    2828#include <pj/sock_qos.h> 
     29#include <pj/ssl_sock.h> 
    2930 
    3031 
     
    146147 
    147148/** 
     149 * The default enabled SSL proto to be used. 
     150 * Default is all protocol above TLSv1 (TLSv1 & TLS v1.1 & TLS v1.2). 
     151 */ 
     152#ifndef PJ_TURN_TLS_DEFAULT_PROTO 
     153#   define PJ_TURN_TLS_DEFAULT_PROTO  (PJ_SSL_SOCK_PROTO_TLS1 | \ 
     154                                       PJ_SSL_SOCK_PROTO_TLS1_1 | \ 
     155                                       PJ_SSL_SOCK_PROTO_TLS1_2) 
     156#endif 
     157 
     158/** 
     159 * TLS transport settings. 
     160 */ 
     161typedef struct pj_turn_sock_tls_cfg 
     162{ 
     163    /** 
     164     * Certificate of Authority (CA) list file. 
     165     */ 
     166    pj_str_t    ca_list_file; 
     167 
     168    /** 
     169     * Certificate of Authority (CA) list directory path. 
     170     */ 
     171    pj_str_t    ca_list_path; 
     172 
     173    /** 
     174     * Public endpoint certificate file, which will be used as client- 
     175     * side  certificate for outgoing TLS connection. 
     176     */ 
     177    pj_str_t    cert_file; 
     178 
     179    /** 
     180     * Optional private key of the endpoint certificate to be used. 
     181     */ 
     182    pj_str_t    privkey_file; 
     183 
     184    /** 
     185     * Certificate of Authority (CA) buffer. If ca_list_file, ca_list_path, 
     186     * cert_file or privkey_file are set, this setting will be ignored. 
     187     */ 
     188    pj_ssl_cert_buffer ca_buf; 
     189 
     190    /** 
     191     * Public endpoint certificate buffer, which will be used as client- 
     192     * side  certificate for outgoing TLS connection, and server-side 
     193     * certificate for incoming TLS connection. If ca_list_file, ca_list_path, 
     194     * cert_file or privkey_file are set, this setting will be ignored. 
     195     */ 
     196    pj_ssl_cert_buffer cert_buf; 
     197 
     198    /** 
     199     * Optional private key buffer of the endpoint certificate to be used.  
     200     * If ca_list_file, ca_list_path, cert_file or privkey_file are set,  
     201     * this setting will be ignored. 
     202     */ 
     203    pj_ssl_cert_buffer privkey_buf; 
     204 
     205    /** 
     206     * Password to open private key. 
     207     */ 
     208    pj_str_t    password; 
     209 
     210    /** 
     211     * The ssl socket parameter. 
     212     * These fields are used by TURN TLS: 
     213     * - proto 
     214     * - ciphers_num 
     215     * - ciphers 
     216     * - curves_num 
     217     * - curves 
     218     * - sigalgs 
     219     * - entropy_type 
     220     * - entropy_path 
     221     * - timeout 
     222     * - sockopt_params 
     223     * - sockopt_ignore_error 
     224     */ 
     225    pj_ssl_sock_param ssock_param; 
     226 
     227} pj_turn_sock_tls_cfg; 
     228 
     229/** 
     230 * Initialize TLS setting with default values. 
     231 * 
     232 * @param tls_cfg   The TLS setting to be initialized. 
     233 */ 
     234 PJ_DECL(void) pj_turn_sock_tls_cfg_default(pj_turn_sock_tls_cfg *tls_cfg); 
     235 
     236/** 
     237 * Duplicate TLS setting. 
     238 * 
     239 * @param pool      The pool to duplicate strings etc. 
     240 * @param dst       Destination structure. 
     241 * @param src       Source structure. 
     242 */ 
     243 PJ_DECL(void) pj_turn_sock_tls_cfg_dup(pj_pool_t *pool, 
     244                                        pj_turn_sock_tls_cfg *dst, 
     245                                        const pj_turn_sock_tls_cfg *src); 
     246 
     247/** 
     248 * Wipe out certificates and keys in the TLS setting. 
     249 * 
     250 * @param tls_cfg   The TLS setting. 
     251 */ 
     252PJ_DECL(void) pj_turn_sock_tls_cfg_wipe_keys(pj_turn_sock_tls_cfg *tls_cfg); 
     253 
     254 
     255/** 
    148256 * This structure describes options that can be specified when creating 
    149257 * the TURN socket. Application should call #pj_turn_sock_cfg_default() 
     
    229337     */ 
    230338    unsigned so_sndbuf_size; 
     339 
     340    /** 
     341     * This specifies TLS settings for TLS transport. It is only be used 
     342     * when this TLS is used to connect to the TURN server. 
     343     */ 
     344    pj_turn_sock_tls_cfg tls_cfg; 
    231345 
    232346} pj_turn_sock_cfg; 
  • pjproject/trunk/pjnath/src/pjnath-test/server.c

    r5534 r6004  
    2424#define MAX_STUN_PKT    1500 
    2525#define TURN_NONCE      "thenonce" 
     26#define CERT_DIR                    "../../pjlib/build/" 
     27#define CERT_CA_FILE                CERT_DIR "cacert.pem" 
     28#define CERT_FILE                   CERT_DIR "cacert.pem" 
     29#define CERT_PRIVKEY_FILE           CERT_DIR "privkey.pem" 
     30#define CERT_PRIVKEY_PASS           "" 
    2631 
    2732static pj_bool_t stun_on_data_recvfrom(pj_activesock_t *asock, 
     
    3136                                       int addr_len, 
    3237                                       pj_status_t status); 
    33 static pj_bool_t turn_on_data_recvfrom(pj_activesock_t *asock, 
     38static pj_bool_t turn_tcp_on_data_read(pj_activesock_t *asock, 
    3439                                       void *data, 
    3540                                       pj_size_t size, 
    36                                        const pj_sockaddr_t *src_addr, 
    37                                        int addr_len, 
    38                                        pj_status_t status); 
     41                                       pj_status_t status, 
     42                                       pj_size_t *remainder); 
     43static pj_bool_t turn_tls_on_data_read(pj_ssl_sock_t *ssock, 
     44                                       void *data, 
     45                                       pj_size_t size, 
     46                                       pj_status_t status, 
     47                                       pj_size_t *remainder); 
     48static pj_bool_t turn_udp_on_data_recvfrom(pj_activesock_t *asock, 
     49                                           void *data, 
     50                                           pj_size_t size, 
     51                                           const pj_sockaddr_t *src_addr, 
     52                                           int addr_len, 
     53                                           pj_status_t status); 
     54static pj_bool_t turn_on_data_read(test_server *asock, 
     55                                   void *data, 
     56                                   pj_size_t size, 
     57                                   const pj_sockaddr_t *src_addr, 
     58                                   int addr_len, 
     59                                   pj_status_t status); 
     60static pj_bool_t turn_tcp_on_accept_complete(pj_activesock_t *asock, 
     61                                             pj_sock_t newsock, 
     62                                             const pj_sockaddr_t *src_addr, 
     63                                             int src_addr_len, 
     64                                             pj_status_t status); 
     65#if USE_TLS 
     66static pj_bool_t turn_tls_on_accept_complete2(pj_ssl_sock_t *ssock, 
     67                                              pj_ssl_sock_t *newsock, 
     68                                              const pj_sockaddr_t *src_addr, 
     69                                              int src_addr_len, 
     70                                              pj_status_t status); 
     71#endif 
    3972static pj_bool_t alloc_on_data_recvfrom(pj_activesock_t *asock, 
    4073                                       void *data, 
     
    5386    pj_sockaddr hostip; 
    5487    char strbuf[100]; 
    55     pj_status_t status; 
     88    pj_status_t status = PJ_EINVAL; 
    5689    pj_bool_t use_ipv6 = flags & SERVER_IPV6; 
    5790 
     
    169202 
    170203    if (flags & CREATE_TURN_SERVER) { 
    171         pj_activesock_cb turn_sock_cb; 
     204         
    172205        pj_sockaddr bound_addr; 
    173  
    174         pj_bzero(&turn_sock_cb, sizeof(turn_sock_cb)); 
    175         turn_sock_cb.on_data_recvfrom = &turn_on_data_recvfrom; 
    176  
     206        pj_turn_tp_type tp_type = get_turn_tp_type(flags); 
     207         
    177208        pj_sockaddr_init(GET_AF(use_ipv6), &bound_addr, NULL, TURN_SERVER_PORT); 
    178209 
    179         status = pj_activesock_create_udp(pool, &bound_addr, NULL,  
    180                                           test_srv->stun_cfg->ioqueue, 
    181                                           &turn_sock_cb, test_srv, 
    182                                           &test_srv->turn_sock, NULL); 
    183         if (status != PJ_SUCCESS) { 
    184             destroy_test_server(test_srv); 
    185             return status; 
    186         } 
    187  
    188         status = pj_activesock_start_recvfrom(test_srv->turn_sock, pool, 
    189                                               MAX_STUN_PKT, 0); 
     210        if (tp_type == PJ_TURN_TP_UDP) { 
     211            pj_activesock_cb turn_sock_cb; 
     212 
     213            pj_bzero(&turn_sock_cb, sizeof(turn_sock_cb)); 
     214            turn_sock_cb.on_data_recvfrom = &turn_udp_on_data_recvfrom; 
     215 
     216            status = pj_activesock_create_udp(pool, &bound_addr, NULL, 
     217                                              test_srv->stun_cfg->ioqueue, 
     218                                              &turn_sock_cb, test_srv, 
     219                                              &test_srv->turn_sock, NULL); 
     220 
     221            if (status != PJ_SUCCESS) { 
     222                destroy_test_server(test_srv); 
     223                return status; 
     224            } 
     225 
     226            status = pj_activesock_start_recvfrom(test_srv->turn_sock, pool, 
     227                                                  MAX_STUN_PKT, 0); 
     228        } else if (tp_type == PJ_TURN_TP_TCP) { 
     229            pj_sock_t sock_fd; 
     230            pj_activesock_cb turn_sock_cb; 
     231 
     232            pj_bzero(&turn_sock_cb, sizeof(turn_sock_cb)); 
     233            turn_sock_cb.on_accept_complete2 = &turn_tcp_on_accept_complete; 
     234            status = pj_sock_socket(GET_AF(use_ipv6), pj_SOCK_STREAM(), 0, 
     235                                    &sock_fd); 
     236            if (status != PJ_SUCCESS) { 
     237                return status; 
     238            } 
     239 
     240            status = pj_sock_bind(sock_fd, &bound_addr,  
     241                                  pj_sockaddr_get_len(&bound_addr)); 
     242            if (status != PJ_SUCCESS) { 
     243                pj_sock_close(sock_fd); 
     244                return status; 
     245            } 
     246 
     247            status = pj_sock_listen(sock_fd, 4); 
     248            if (status != PJ_SUCCESS) { 
     249                pj_sock_close(sock_fd); 
     250                return status; 
     251            } 
     252 
     253            status = pj_activesock_create(pool, sock_fd, pj_SOCK_STREAM(),  
     254                                          NULL, 
     255                                          test_srv->stun_cfg->ioqueue,  
     256                                          &turn_sock_cb, test_srv,  
     257                                          &test_srv->turn_sock); 
     258            if (status != PJ_SUCCESS) { 
     259                pj_sock_close(sock_fd); 
     260                return status; 
     261            } 
     262 
     263            status = pj_activesock_start_accept(test_srv->turn_sock, 
     264                                                pool); 
     265        }  
     266#if USE_TLS      
     267        else if (tp_type == PJ_TURN_TP_TLS) { 
     268            pj_ssl_sock_t *ssock_serv = NULL; 
     269            pj_ssl_sock_param ssl_param; 
     270            pj_ssl_cert_t *cert = NULL; 
     271            pj_str_t ca_file = pj_str(CERT_CA_FILE); 
     272            pj_str_t cert_file = pj_str(CERT_FILE); 
     273            pj_str_t privkey_file = pj_str(CERT_PRIVKEY_FILE); 
     274            pj_str_t privkey_pass = pj_str(CERT_PRIVKEY_PASS); 
     275 
     276            pj_ssl_sock_param_default(&ssl_param); 
     277            ssl_param.cb.on_accept_complete2 = &turn_tls_on_accept_complete2; 
     278            ssl_param.cb.on_data_read = &turn_tls_on_data_read; 
     279            ssl_param.ioqueue = test_srv->stun_cfg->ioqueue; 
     280            ssl_param.timer_heap = test_srv->stun_cfg->timer_heap; 
     281            ssl_param.user_data = test_srv; 
     282            ssl_param.sock_af = GET_AF(use_ipv6); 
     283 
     284            status = pj_ssl_sock_create(pool, &ssl_param, &ssock_serv); 
     285            if (status != PJ_SUCCESS) { 
     286                if (ssock_serv) 
     287                    pj_ssl_sock_close(ssock_serv); 
     288            } 
     289 
     290            status = pj_ssl_cert_load_from_files(pool, &ca_file, &cert_file,  
     291                                                 &privkey_file, &privkey_pass, 
     292                                                 &cert); 
     293            if (status != PJ_SUCCESS) { 
     294                if (ssock_serv) 
     295                    pj_ssl_sock_close(ssock_serv); 
     296            } 
     297 
     298            status = pj_ssl_sock_set_certificate(ssock_serv, pool, cert); 
     299            if (status != PJ_SUCCESS) { 
     300                if (ssock_serv) 
     301                    pj_ssl_sock_close(ssock_serv); 
     302            } 
     303            test_srv->ssl_srv_sock = ssock_serv; 
     304            status = pj_ssl_sock_start_accept(ssock_serv, pool, &bound_addr,  
     305                                             pj_sockaddr_get_len(&bound_addr)); 
     306        } 
     307#endif 
    190308        if (status != PJ_SUCCESS) { 
    191309            destroy_test_server(test_srv); 
     
    201319             *  turn.domain IN A 127.0.0.1 
    202320             */ 
    203             pj_ansi_snprintf(strbuf, sizeof(strbuf), 
    204                              "_turn._udp.%s", domain); 
     321            switch (tp_type) { 
     322            case PJ_TURN_TP_TCP: 
     323                pj_ansi_snprintf(strbuf, sizeof(strbuf), 
     324                                 "_turn._tcp.%s", domain); 
     325                break; 
     326            case PJ_TURN_TP_TLS: 
     327                pj_ansi_snprintf(strbuf, sizeof(strbuf), 
     328                                 "_turns._tcp.%s", domain); 
     329                break; 
     330            default: 
     331                pj_ansi_snprintf(strbuf, sizeof(strbuf), 
     332                                 "_turn._udp.%s", domain); 
     333                 
     334            } 
    205335            pj_strdup2(pool, &res_name, strbuf); 
    206336            pj_ansi_snprintf(strbuf, sizeof(strbuf), 
     
    244374        test_srv->turn_sock = NULL; 
    245375    } 
     376 
     377    if (test_srv->cl_turn_sock) { 
     378        pj_activesock_close(test_srv->cl_turn_sock); 
     379        test_srv->cl_turn_sock = NULL; 
     380    } 
     381 
     382#if USE_TLS 
     383    if (test_srv->ssl_srv_sock) { 
     384        pj_ssl_sock_close(test_srv->ssl_srv_sock); 
     385        test_srv->ssl_srv_sock = NULL; 
     386    } 
     387    if (test_srv->ssl_cl_sock) { 
     388        pj_ssl_sock_close(test_srv->ssl_cl_sock); 
     389        test_srv->ssl_cl_sock = NULL; 
     390    } 
     391#endif 
    246392 
    247393    if (test_srv->stun_sock) { 
     
    350496} 
    351497 
    352  
    353 static pj_bool_t turn_on_data_recvfrom(pj_activesock_t *asock, 
     498static pj_bool_t turn_tcp_on_data_read(pj_activesock_t *asock, 
    354499                                       void *data, 
    355500                                       pj_size_t size, 
    356                                        const pj_sockaddr_t *src_addr, 
    357                                        int addr_len, 
    358                                        pj_status_t status) 
     501                                       pj_status_t status, 
     502                                       pj_size_t *remainder) 
     503{ 
     504    test_server *test_srv = (test_server *)pj_activesock_get_user_data(asock); 
     505 
     506    PJ_UNUSED_ARG(remainder); 
     507    return turn_on_data_read(test_srv, data, size, &test_srv->remote_addr,  
     508                            sizeof(test_srv->remote_addr), status); 
     509} 
     510 
     511static pj_bool_t turn_tls_on_data_read(pj_ssl_sock_t *ssl_sock, 
     512                                       void *data, 
     513                                       pj_size_t size, 
     514                                       pj_status_t status, 
     515                                       pj_size_t *remainder) 
     516{ 
     517    test_server *test_srv = (test_server *)pj_ssl_sock_get_user_data(ssl_sock); 
     518 
     519    PJ_UNUSED_ARG(remainder); 
     520    return turn_on_data_read(test_srv, data, size,  
     521                             &test_srv->remote_addr,  
     522                             sizeof(test_srv->remote_addr),  
     523                             status); 
     524} 
     525 
     526static pj_bool_t turn_udp_on_data_recvfrom(pj_activesock_t *asock, 
     527                                           void *data, 
     528                                           pj_size_t size, 
     529                                           const pj_sockaddr_t *src_addr, 
     530                                           int addr_len, 
     531                                           pj_status_t status) 
    359532{ 
    360533    test_server *test_srv; 
     534    test_srv = (test_server*) pj_activesock_get_user_data(asock); 
     535    return turn_on_data_read(test_srv, data, size, src_addr, addr_len, status); 
     536} 
     537 
     538static pj_bool_t turn_on_data_read(test_server *test_srv, 
     539                                   void *data, 
     540                                   pj_size_t size, 
     541                                   const pj_sockaddr_t *src_addr, 
     542                                   int addr_len, 
     543                                   pj_status_t status) 
     544{ 
     545     
    361546    pj_pool_t *pool; 
    362547    turn_allocation *alloc; 
     
    372557 
    373558    pj_sockaddr_print(src_addr, client_info, sizeof(client_info), 3); 
    374  
    375     test_srv = (test_server*) pj_activesock_get_user_data(asock); 
     559     
    376560    use_ipv6 = test_srv->flags & SERVER_IPV6; 
    377561    pool = pj_pool_create(test_srv->stun_cfg->pf, NULL, 512, 512, NULL); 
     
    383567    } 
    384568 
    385  
    386     if (pj_stun_msg_check((pj_uint8_t*)data, size, PJ_STUN_NO_FINGERPRINT_CHECK)!=PJ_SUCCESS)  { 
     569    if (pj_stun_msg_check((pj_uint8_t*)data, size,  
     570                          PJ_STUN_NO_FINGERPRINT_CHECK)!=PJ_SUCCESS)   
     571{ 
    387572        /* Not STUN message, this probably is a ChannelData */ 
    388573        pj_turn_channel_data cd; 
     
    703888send_pkt: 
    704889    if (resp) { 
     890        pj_turn_tp_type tp_type = get_turn_tp_type(test_srv->flags); 
     891 
    705892        status = pj_stun_msg_encode(resp, (pj_uint8_t*)data, MAX_STUN_PKT,  
    706893                                    0, &auth_key, &size); 
     
    709896 
    710897        len = size; 
    711         status = pj_activesock_sendto(asock, &test_srv->send_key, data, &len, 
    712                                       0, src_addr, addr_len); 
     898        switch (tp_type) { 
     899        case PJ_TURN_TP_TCP: 
     900            status = pj_activesock_send(test_srv->cl_turn_sock,  
     901                                        &test_srv->send_key, data, &len, 0); 
     902            break; 
     903#if USE_TLS 
     904        case PJ_TURN_TP_TLS: 
     905            status = pj_ssl_sock_send(test_srv->ssl_cl_sock,  
     906                                      &test_srv->send_key, data, &len, 0); 
     907            break; 
     908#endif 
     909        default: 
     910            status = pj_activesock_sendto(test_srv->turn_sock,  
     911                                          &test_srv->send_key, data,  
     912                                          &len, 0, src_addr, addr_len);      
     913        } 
    713914    } 
    714915 
     
    717918    return PJ_TRUE; 
    718919} 
     920 
     921static pj_bool_t turn_tcp_on_accept_complete(pj_activesock_t *asock, 
     922                                             pj_sock_t newsock, 
     923                                             const pj_sockaddr_t *src_addr, 
     924                                             int src_addr_len, 
     925                                             pj_status_t status) 
     926{ 
     927    pj_status_t sstatus; 
     928    pj_activesock_cb asock_cb; 
     929    test_server *test_srv = (test_server *) pj_activesock_get_user_data(asock); 
     930     
     931    PJ_UNUSED_ARG(src_addr_len); 
     932 
     933    if (status != PJ_SUCCESS && status != PJ_EPENDING) { 
     934        return PJ_FALSE; 
     935    } 
     936 
     937    pj_sockaddr_cp(&test_srv->remote_addr, src_addr); 
     938    pj_bzero(&asock_cb, sizeof(asock_cb)); 
     939    asock_cb.on_data_read = &turn_tcp_on_data_read; 
     940 
     941    sstatus = pj_activesock_create(test_srv->pool, newsock, pj_SOCK_STREAM(), 
     942                                   NULL, test_srv->stun_cfg->ioqueue, 
     943                                   &asock_cb, test_srv,  
     944                                   &test_srv->cl_turn_sock); 
     945    if (sstatus != PJ_SUCCESS) {         
     946        goto on_exit; 
     947    } 
     948 
     949    sstatus = pj_activesock_start_read(test_srv->cl_turn_sock,  
     950                                       test_srv->pool, MAX_STUN_PKT, 0); 
     951    if (sstatus != PJ_SUCCESS) { 
     952        goto on_exit; 
     953    } 
     954 
     955    pj_ioqueue_op_key_init(&test_srv->send_key, sizeof(test_srv->send_key)); 
     956 
     957    return PJ_TRUE; 
     958 
     959on_exit: 
     960    if (test_srv->cl_turn_sock) 
     961        pj_activesock_close(test_srv->turn_sock); 
     962    else     
     963        pj_sock_close(newsock); 
     964 
     965    return PJ_FALSE; 
     966 
     967} 
     968 
     969#if USE_TLS 
     970static pj_bool_t turn_tls_on_accept_complete2(pj_ssl_sock_t *ssock, 
     971                                              pj_ssl_sock_t *newsock, 
     972                                              const pj_sockaddr_t *src_addr, 
     973                                              int src_addr_len, 
     974                                              pj_status_t status) 
     975{ 
     976    pj_status_t sstatus; 
     977    test_server *test_srv = (test_server *) pj_ssl_sock_get_user_data(ssock); 
     978 
     979    PJ_UNUSED_ARG(src_addr_len); 
     980 
     981    if (status != PJ_SUCCESS && status != PJ_EPENDING) { 
     982        return PJ_FALSE; 
     983    } 
     984 
     985    pj_ssl_sock_set_user_data(newsock, test_srv); 
     986    pj_sockaddr_cp(&test_srv->remote_addr, src_addr); 
     987    test_srv->ssl_cl_sock = newsock; 
     988 
     989    sstatus = pj_ssl_sock_start_read(newsock, test_srv->pool, MAX_STUN_PKT, 0); 
     990    if (sstatus != PJ_SUCCESS) { 
     991        pj_ssl_sock_close(newsock); 
     992        test_srv->ssl_cl_sock = NULL; 
     993 
     994    } 
     995    return PJ_TRUE; 
     996} 
     997#endif 
    719998 
    720999/* On received data from peer */ 
  • pjproject/trunk/pjnath/src/pjnath-test/server.h

    r5350 r6004  
    4747 
    4848    SERVER_IPV4                 = (1 << 12), 
    49     SERVER_IPV6                 = (1 << 13) 
     49    SERVER_IPV6                 = (1 << 13), 
     50 
     51    TURN_UDP                    = (1 << 16), 
     52    TURN_TCP                    = (1 << 17), 
     53    TURN_TLS                    = (1 << 18) 
    5054}; 
    5155 
     
    8387 
    8488    pj_activesock_t     *turn_sock; 
     89 
     90    pj_ssl_sock_t       *ssl_srv_sock; 
     91 
     92    pj_ssl_sock_t       *ssl_cl_sock; 
     93 
     94    pj_activesock_t     *cl_turn_sock; 
     95 
     96    pj_sockaddr          remote_addr; 
    8597    unsigned             turn_alloc_cnt; 
    8698    turn_allocation      turn_alloc[MAX_TURN_ALLOC]; 
  • pjproject/trunk/pjnath/src/pjnath-test/test.h

    r5388 r6004  
    3636#endif 
    3737 
     38#if defined(PJ_HAS_SSL_SOCK) && PJ_HAS_SSL_SOCK 
     39#   define USE_TLS      1 
     40#else 
     41#   define USE_TLS      0 
     42#endif 
     43 
    3844int stun_test(void); 
    3945int sess_auth_test(void); 
     
    7177                      const struct pjlib_state *initial_st); 
    7278 
     79pj_turn_tp_type get_turn_tp_type(pj_uint32_t flag); 
    7380 
    7481#define ERR_MEMORY_LEAK     1 
  • pjproject/trunk/pjnath/src/pjnath-test/turn_sock_test.c

    r5350 r6004  
    9191} 
    9292 
    93  
     93pj_turn_tp_type get_turn_tp_type(pj_uint32_t flag) { 
     94    if (flag & TURN_TCP) { 
     95        return PJ_TURN_TP_TCP; 
     96    } else if (flag & TURN_TLS) { 
     97        return PJ_TURN_TP_TLS; 
     98    }  
     99    return PJ_TURN_TP_UDP; 
     100} 
    94101 
    95102static int create_test_session(pj_stun_config  *stun_cfg, 
     
    104111    pj_status_t status; 
    105112    pj_bool_t use_ipv6 = cfg->srv.flags & SERVER_IPV6; 
     113    pj_turn_tp_type tp_type = get_turn_tp_type(cfg->srv.flags); 
    106114 
    107115    /* Create client */ 
     
    117125    status = pj_turn_sock_create(sess->stun_cfg, 
    118126                                 GET_AF(use_ipv6), 
    119                                  PJ_TURN_TP_UDP,  
     127                                 tp_type,  
    120128                                 &turn_sock_cb,  
    121129                                 0,  
     
    258266 
    259267static void set_server_flag(struct test_session_cfg *test_cfg,  
    260                             pj_bool_t use_ipv6) 
    261 { 
    262     test_cfg->srv.flags &= ~(SERVER_IPV4+SERVER_IPV6); 
    263     test_cfg->srv.flags |= (use_ipv6)?SERVER_IPV6:SERVER_IPV4; 
     268                            pj_bool_t use_ipv6, 
     269                            pj_turn_tp_type tp_type) 
     270{ 
     271    pj_uint32_t flag = TURN_UDP; 
     272    test_cfg->srv.flags &= ~(SERVER_IPV4+SERVER_IPV6+ 
     273                             TURN_UDP+TURN_TCP+TURN_TLS);     
     274    switch (tp_type) { 
     275        case PJ_TURN_TP_TCP: 
     276            flag = TURN_TCP; 
     277            break; 
     278        case PJ_TURN_TP_TLS: 
     279            flag = TURN_TLS; 
     280    } 
     281    test_cfg->srv.flags |= ((use_ipv6)?SERVER_IPV6:SERVER_IPV4)+flag; 
    264282} 
    265283 
    266284static int state_progression_test(pj_stun_config  *stun_cfg,  
    267                                   pj_bool_t use_ipv6) 
     285                                  pj_bool_t use_ipv6, 
     286                                  pj_turn_tp_type tp_type) 
    268287{ 
    269288    struct test_session_cfg test_cfg =  
     
    283302    int rc = 0; 
    284303 
    285     PJ_LOG(3,("", "  state progression tests - (%s)",use_ipv6?"IPv6":"IPv4")); 
     304    PJ_LOG(3,("", "  state progression tests - (%s) (%s)", 
     305              use_ipv6?"IPv6":"IPv4", 
     306              (tp_type==PJ_TURN_TP_UDP)?"UDP": 
     307                (tp_type==PJ_TURN_TP_TCP)?"TCP":"TLS")); 
    286308     
    287     set_server_flag(&test_cfg, use_ipv6); 
     309    set_server_flag(&test_cfg, use_ipv6, tp_type); 
    288310    for (i=0; i<=1; ++i) { 
    289311        enum { TIMEOUT = 60 }; 
     
    312334 
    313335            poll_events(stun_cfg, 10, PJ_FALSE); 
     336            if (sess->turn_sock == NULL) { 
     337                break; 
     338            } 
    314339            rc = pj_turn_sock_get_info(sess->turn_sock, &info); 
    315340            if (rc!=PJ_SUCCESS) 
     
    389414 
    390415    if (use_ipv6) 
    391         rc = state_progression_test(stun_cfg, 0); 
     416        rc = state_progression_test(stun_cfg, 0, tp_type); 
    392417 
    393418    return rc; 
     
    400425                        pj_bool_t with_dns_srv, 
    401426                        pj_bool_t in_callback, 
    402                         pj_bool_t use_ipv6) 
     427                        pj_bool_t use_ipv6, 
     428                        pj_turn_tp_type tp_type) 
    403429{ 
    404430    struct test_session_cfg test_cfg =  
     
    418444    int rc; 
    419445 
    420     PJ_LOG(3,("", "  destroy test %s %s", 
     446    PJ_LOG(3,("", "  destroy test %s %s (%s)", 
    421447                  (in_callback? "in callback" : ""), 
    422                   (with_dns_srv? "with DNS srv" : "") 
    423                   )); 
     448                  (with_dns_srv? "with DNS srv" : ""), 
     449                  (tp_type==PJ_TURN_TP_UDP)?"UDP": 
     450                    (tp_type==PJ_TURN_TP_TCP)?"TCP":"TLS")); 
    424451 
    425452    test_cfg.client.enable_dns_srv = with_dns_srv; 
    426     set_server_flag(&test_cfg, use_ipv6);     
     453    set_server_flag(&test_cfg, use_ipv6, tp_type);     
    427454 
    428455    for (target_state=PJ_TURN_STATE_RESOLVING; target_state<=PJ_TURN_STATE_READY; ++target_state) { 
     
    507534    pj_pool_t *pool; 
    508535    pj_stun_config stun_cfg; 
    509     int i, rc = 0; 
     536    int n, i, rc = 0; 
    510537 
    511538    pool = pj_pool_create(mem, "turntest", 512, 512, NULL); 
     
    516543    } 
    517544 
    518     rc = state_progression_test(&stun_cfg, USE_IPV6); 
    519     if (rc != 0)  
    520         goto on_return; 
    521  
    522     for (i=0; i<=1; ++i) { 
    523         int j; 
    524         for (j=0; j<=1; ++j) { 
    525             rc = destroy_test(&stun_cfg, i, j, USE_IPV6); 
    526             if (rc != 0) 
    527                 goto on_return; 
     545    for (n = 0; n <= 2; ++n) { 
     546        pj_turn_tp_type tp_type = PJ_TURN_TP_UDP; 
     547 
     548        if ((n == 2) && !USE_TLS) 
     549            break; 
     550 
     551        switch (n) { 
     552        case 1: 
     553            tp_type = PJ_TURN_TP_TCP; 
     554            break; 
     555        case 2: 
     556            tp_type = PJ_TURN_TP_TLS; 
     557        } 
     558 
     559        rc = state_progression_test(&stun_cfg, USE_IPV6, tp_type); 
     560        if (rc != 0)  
     561            goto on_return; 
     562 
     563        for (i=0; i<=1; ++i) { 
     564            int j; 
     565            for (j=0; j<=1; ++j) { 
     566                rc = destroy_test(&stun_cfg, i, j, USE_IPV6, tp_type); 
     567                if (rc != 0) 
     568                    goto on_return; 
     569            } 
    528570        } 
    529571    } 
  • pjproject/trunk/pjnath/src/pjnath/turn_sock.c

    r5988 r6004  
    2020#include <pjnath/turn_sock.h> 
    2121#include <pj/activesock.h> 
     22#include <pj/ssl_sock.h> 
    2223#include <pj/assert.h> 
    2324#include <pj/errno.h> 
     
    2627#include <pj/pool.h> 
    2728#include <pj/ioqueue.h> 
     29#include <pj/compat/socket.h> 
    2830 
    2931enum 
     
    8587    pj_turn_tp_type      conn_type; 
    8688    pj_activesock_t     *active_sock; 
     89#if PJ_HAS_SSL_SOCK 
     90    pj_ssl_sock_t       *ssl_sock; 
     91    pj_ssl_cert_t       *cert; 
     92    pj_str_t             server_name; 
     93#endif 
     94 
    8795    pj_ioqueue_op_key_t  send_key; 
    8896 
     
    123131                                           unsigned addr_len); 
    124132 
    125 static pj_bool_t on_data_read(pj_activesock_t *asock, 
     133static pj_bool_t on_data_read(pj_turn_sock *turn_sock, 
    126134                              void *data, 
    127135                              pj_size_t size, 
    128136                              pj_status_t status, 
    129137                              pj_size_t *remainder); 
    130 static pj_bool_t on_connect_complete(pj_activesock_t *asock, 
     138static pj_bool_t on_connect_complete(pj_turn_sock *turn_sock, 
    131139                                     pj_status_t status); 
    132140 
     141/* 
     142 * Activesock callback 
     143 */ 
     144static pj_bool_t on_connect_complete_asock(pj_activesock_t *asock, 
     145                                           pj_status_t status); 
     146static pj_bool_t on_data_read_asock(pj_activesock_t *asock, 
     147                                    void *data, 
     148                                    pj_size_t size, 
     149                                    pj_status_t status, 
     150                                    pj_size_t *remainder); 
     151 
     152/* 
     153 * SSL sock callback 
     154 */ 
     155static pj_bool_t on_connect_complete_ssl_sock(pj_ssl_sock_t *ssl_sock, 
     156                                              pj_status_t status); 
     157static pj_bool_t on_data_read_ssl_sock(pj_ssl_sock_t *ssl_sock, 
     158                                       void *data, 
     159                                       pj_size_t size, 
     160                                       pj_status_t status, 
     161                                       pj_size_t *remainder); 
     162   
    133163static pj_bool_t dataconn_on_data_read(pj_activesock_t *asock, 
    134164                                       void *data, 
     
    152182    cfg->qos_type = PJ_QOS_TYPE_BEST_EFFORT; 
    153183    cfg->qos_ignore_error = PJ_TRUE; 
    154 } 
    155  
     184 
     185#if PJ_HAS_SSL_SOCK 
     186    pj_turn_sock_tls_cfg_default(&cfg->tls_cfg); 
     187#endif 
     188} 
     189 
     190#if PJ_HAS_SSL_SOCK 
     191 
     192PJ_DEF(void) pj_turn_sock_tls_cfg_default(pj_turn_sock_tls_cfg *tls_cfg) 
     193{ 
     194    pj_bzero(tls_cfg, sizeof(*tls_cfg)); 
     195    pj_ssl_sock_param_default(&tls_cfg->ssock_param); 
     196    tls_cfg->ssock_param.proto = PJ_TURN_TLS_DEFAULT_PROTO; 
     197} 
     198 
     199PJ_DEF(void) pj_turn_sock_tls_cfg_dup(pj_pool_t *pool, 
     200                                      pj_turn_sock_tls_cfg *dst, 
     201                                      const pj_turn_sock_tls_cfg *src) 
     202{ 
     203    pj_memcpy(dst, src, sizeof(*dst)); 
     204    pj_strdup_with_null(pool, &dst->ca_list_file, &src->ca_list_file); 
     205    pj_strdup_with_null(pool, &dst->ca_list_path, &src->ca_list_path); 
     206    pj_strdup_with_null(pool, &dst->cert_file, &src->cert_file); 
     207    pj_strdup_with_null(pool, &dst->privkey_file, &src->privkey_file); 
     208    pj_strdup_with_null(pool, &dst->password, &src->password); 
     209    pj_strdup(pool, &dst->ca_buf, &src->ca_buf); 
     210    pj_strdup(pool, &dst->cert_buf, &src->cert_buf); 
     211    pj_strdup(pool, &dst->privkey_buf, &src->privkey_buf); 
     212    pj_ssl_sock_param_copy(pool, &dst->ssock_param, &src->ssock_param); 
     213} 
     214 
     215static void wipe_buf(pj_str_t *buf) 
     216{ 
     217    volatile char *p = buf->ptr; 
     218    pj_ssize_t len = buf->slen; 
     219    while (len--) *p++ = 0; 
     220    buf->slen = 0; 
     221} 
     222 
     223PJ_DEF(void) pj_turn_sock_tls_cfg_wipe_keys(pj_turn_sock_tls_cfg *tls_cfg) 
     224{ 
     225    wipe_buf(&tls_cfg->ca_list_file); 
     226    wipe_buf(&tls_cfg->ca_list_path); 
     227    wipe_buf(&tls_cfg->cert_file); 
     228    wipe_buf(&tls_cfg->privkey_file); 
     229    wipe_buf(&tls_cfg->password); 
     230    wipe_buf(&tls_cfg->ca_buf); 
     231    wipe_buf(&tls_cfg->cert_buf); 
     232    wipe_buf(&tls_cfg->privkey_buf);  
     233} 
     234#endif 
    156235 
    157236/* 
     
    176255    PJ_ASSERT_RETURN(af==pj_AF_INET() || af==pj_AF_INET6(), PJ_EINVAL); 
    177256    PJ_ASSERT_RETURN(conn_type!=PJ_TURN_TP_TCP || PJ_HAS_TCP, PJ_EINVAL); 
     257    PJ_ASSERT_RETURN(conn_type!=PJ_TURN_TP_TLS || PJ_HAS_SSL_SOCK, PJ_EINVAL); 
    178258 
    179259    if (!setting) { 
     
    189269        name_tmpl = "tcprel%p"; 
    190270        break; 
     271#if PJ_HAS_SSL_SOCK 
     272    case PJ_TURN_TP_TLS: 
     273        name_tmpl = "tlsrel%p"; 
     274        break; 
     275#endif 
    191276    default: 
    192277        PJ_ASSERT_RETURN(!"Invalid TURN conn_type", PJ_EINVAL); 
     
    210295    /* Copy setting (QoS parameters etc */ 
    211296    pj_memcpy(&turn_sock->setting, setting, sizeof(*setting)); 
     297#if PJ_HAS_SSL_SOCK 
     298    pj_turn_sock_tls_cfg_dup(turn_sock->pool, &turn_sock->setting.tls_cfg, 
     299                             &setting->tls_cfg); 
     300#endif 
    212301 
    213302    /* Set callback */ 
     
    289378    if (turn_sock->active_sock) 
    290379        pj_activesock_close(turn_sock->active_sock); 
     380#if PJ_HAS_SSL_SOCK 
     381    if (turn_sock->ssl_sock) 
     382        pj_ssl_sock_close(turn_sock->ssl_sock); 
     383#endif 
    291384 
    292385    for (i=0; i < PJ_TURN_MAX_TCP_CONN_CNT; ++i) { 
     
    475568        } 
    476569    } 
     570#if PJ_HAS_SSL_SOCK 
     571    if (turn_sock->conn_type == PJ_TURN_TP_TLS) { 
     572        pj_strdup_with_null(turn_sock->pool, &turn_sock->server_name, domain); 
     573    } 
     574#endif 
    477575 
    478576    /* Resolve server */ 
     
    549647 * Notification when outgoing TCP socket has been connected. 
    550648 */ 
    551 static pj_bool_t on_connect_complete(pj_activesock_t *asock, 
     649static pj_bool_t on_connect_complete(pj_turn_sock *turn_sock, 
    552650                                     pj_status_t status) 
    553651{ 
    554     pj_turn_sock *turn_sock; 
    555  
    556     turn_sock = (pj_turn_sock*) pj_activesock_get_user_data(asock); 
    557     if (!turn_sock) 
    558         return PJ_FALSE; 
    559  
    560652    pj_grp_lock_acquire(turn_sock->grp_lock); 
    561653 
     
    570662 
    571663    if (status != PJ_SUCCESS) { 
    572         sess_fail(turn_sock, "TCP connect() error", status); 
     664        if (turn_sock->conn_type == PJ_TURN_TP_UDP) 
     665            sess_fail(turn_sock, "UDP connect() error", status); 
     666        else if (turn_sock->conn_type == PJ_TURN_TP_TCP) 
     667            sess_fail(turn_sock, "TCP connect() error", status); 
     668        else if (turn_sock->conn_type == PJ_TURN_TP_TLS) 
     669            sess_fail(turn_sock, "TLS connect() error", status); 
     670 
    573671        pj_grp_lock_release(turn_sock->grp_lock); 
    574672        return PJ_FALSE; 
     
    576674 
    577675    if (turn_sock->conn_type != PJ_TURN_TP_UDP) { 
    578         PJ_LOG(5,(turn_sock->obj_name, "TCP connected")); 
     676        PJ_LOG(5, (turn_sock->obj_name, "%s connected", 
     677                   turn_sock->conn_type == PJ_TURN_TP_TCP ? "TCP" : "TLS")); 
    579678    } 
    580679 
    581680    /* Kick start pending read operation */ 
    582     status = pj_activesock_start_read(asock, turn_sock->pool,  
    583                                       turn_sock->setting.max_pkt_size, 0); 
     681    if (turn_sock->conn_type != PJ_TURN_TP_TLS)  
     682        status = pj_activesock_start_read(turn_sock->active_sock,  
     683                                          turn_sock->pool, 
     684                                          turn_sock->setting.max_pkt_size,  
     685                                          0); 
     686#if PJ_HAS_SSL_SOCK 
     687    else 
     688        status = pj_ssl_sock_start_read(turn_sock->ssl_sock, turn_sock->pool, 
     689                                        turn_sock->setting.max_pkt_size, 0); 
     690#endif 
    584691 
    585692    /* Init send_key */ 
     
    598705} 
    599706 
     707static pj_bool_t on_connect_complete_asock(pj_activesock_t *asock, 
     708                                           pj_status_t status) 
     709{ 
     710    pj_turn_sock *turn_sock; 
     711 
     712    turn_sock = (pj_turn_sock*)pj_activesock_get_user_data(asock); 
     713    if (!turn_sock) 
     714        return PJ_FALSE; 
     715 
     716    return on_connect_complete(turn_sock, status); 
     717} 
     718 
     719static pj_bool_t on_connect_complete_ssl_sock(pj_ssl_sock_t *ssl_sock, 
     720                                              pj_status_t status) 
     721{ 
     722    pj_turn_sock *turn_sock; 
     723 
     724    turn_sock = (pj_turn_sock*)pj_ssl_sock_get_user_data(ssl_sock); 
     725    if (!turn_sock) 
     726        return PJ_FALSE; 
     727 
     728    return on_connect_complete(turn_sock, status); 
     729} 
     730 
    600731static pj_uint16_t GETVAL16H(const pj_uint8_t *buf, unsigned pos) 
    601732{ 
     
    644775 * Notification from ioqueue when incoming UDP packet is received. 
    645776 */ 
    646 static pj_bool_t on_data_read(pj_activesock_t *asock, 
     777static pj_bool_t on_data_read(pj_turn_sock *turn_sock, 
    647778                              void *data, 
    648779                              pj_size_t size, 
     
    650781                              pj_size_t *remainder) 
    651782{ 
    652     pj_turn_sock *turn_sock; 
    653783    pj_bool_t ret = PJ_TRUE; 
    654784 
    655     turn_sock = (pj_turn_sock*) pj_activesock_get_user_data(asock); 
    656785    pj_grp_lock_acquire(turn_sock->grp_lock); 
    657786 
     
    697826            //        "Buffer size now %lu bytes", size)); 
    698827        } 
    699     } else if (status != PJ_SUCCESS &&  
    700                turn_sock->conn_type != PJ_TURN_TP_UDP)  
    701     { 
    702         sess_fail(turn_sock, "TCP connection closed", status); 
     828    } else if (status != PJ_SUCCESS) { 
     829        if (turn_sock->conn_type == PJ_TURN_TP_UDP) 
     830            sess_fail(turn_sock, "UDP connection closed", status); 
     831        else if (turn_sock->conn_type == PJ_TURN_TP_TCP) 
     832            sess_fail(turn_sock, "TCP connection closed", status); 
     833        else if (turn_sock->conn_type == PJ_TURN_TP_TLS) 
     834            sess_fail(turn_sock, "TLS connection closed", status); 
     835 
    703836        ret = PJ_FALSE; 
    704837        goto on_return; 
     
    711844} 
    712845 
     846static pj_bool_t on_data_read_asock(pj_activesock_t *asock, 
     847                                    void *data, 
     848                                    pj_size_t size, 
     849                                    pj_status_t status, 
     850                                    pj_size_t *remainder) 
     851{ 
     852    pj_turn_sock *turn_sock; 
     853 
     854    turn_sock = (pj_turn_sock*)pj_activesock_get_user_data(asock); 
     855 
     856    return on_data_read(turn_sock, data, size, status, remainder); 
     857} 
     858 
     859static pj_bool_t on_data_read_ssl_sock(pj_ssl_sock_t *ssl_sock, 
     860                                       void *data, 
     861                                       pj_size_t size, 
     862                                       pj_status_t status, 
     863                                       pj_size_t *remainder) 
     864{ 
     865    pj_turn_sock *turn_sock; 
     866 
     867    turn_sock = (pj_turn_sock*)pj_ssl_sock_get_user_data(ssl_sock); 
     868 
     869    return on_data_read(turn_sock, data, size, status, remainder); 
     870} 
     871 
     872static pj_bool_t on_data_sent_ssl_sock(pj_ssl_sock_t *ssl_sock, 
     873                                       pj_ioqueue_op_key_t *op_key, 
     874                                       pj_ssize_t bytes_sent) 
     875{ 
     876    pj_turn_sock *turn_sock; 
     877 
     878    PJ_UNUSED_ARG(op_key); 
     879 
     880    turn_sock = (pj_turn_sock*)pj_ssl_sock_get_user_data(ssl_sock); 
     881 
     882    /* Check for error/closure */ 
     883    if (bytes_sent <= 0) { 
     884        pj_status_t status; 
     885 
     886        status = (bytes_sent == 0) ? PJ_RETURN_OS_ERROR(OSERR_ENOTCONN) : 
     887            (pj_status_t)-bytes_sent; 
     888 
     889        sess_fail(turn_sock, "TLS send() error", status); 
     890 
     891        return PJ_FALSE; 
     892    } 
     893 
     894    return PJ_TRUE; 
     895} 
    713896 
    714897/* 
     
    761944            } 
    762945        } 
    763     } else { 
     946    } else  if (turn_sock->conn_type == PJ_TURN_TP_TCP) { 
    764947        status = pj_activesock_send(turn_sock->active_sock, 
    765948                                    &turn_sock->send_key, pkt, &len, 0); 
     949    } 
     950#if PJ_HAS_SSL_SOCK 
     951    else if (turn_sock->conn_type == PJ_TURN_TP_TLS) { 
     952        status = pj_ssl_sock_send(turn_sock->ssl_sock, 
     953                                  &turn_sock->send_key, pkt, &len, 0); 
     954    } 
     955#endif 
     956    else { 
     957        PJ_ASSERT_RETURN(!"Invalid TURN conn_type", PJ_EINVAL); 
    766958    } 
    767959 
     
    8261018    pj_turn_sock *turn_sock = (pj_turn_sock*)  
    8271019                           pj_turn_session_get_user_data(sess); 
    828     pj_status_t status; 
     1020    pj_status_t status = PJ_SUCCESS; 
    8291021 
    8301022    if (turn_sock == NULL) { 
     
    8631055         * connection or ALLOCATE request failed. 
    8641056         */ 
    865         if (turn_sock->active_sock) { 
     1057        if ((turn_sock->conn_type != PJ_TURN_TP_TLS) &&  
     1058            (turn_sock->active_sock))  
     1059        { 
    8661060            pj_activesock_close(turn_sock->active_sock); 
    8671061            turn_sock->active_sock = NULL; 
    8681062        } 
    869  
     1063#if PJ_HAS_SSL_SOCK 
     1064        else if ((turn_sock->conn_type == PJ_TURN_TP_TLS) && 
     1065            (turn_sock->ssl_sock)) 
     1066        { 
     1067            pj_ssl_sock_close(turn_sock->ssl_sock); 
     1068            turn_sock->ssl_sock = NULL; 
     1069        } 
     1070#endif 
    8701071        /* Get server address from session info */ 
    8711072        pj_turn_session_get_info(sess, &info); 
     
    8761077            sock_type = pj_SOCK_STREAM(); 
    8771078 
    878         /* Init socket */ 
    879         status = pj_sock_socket(turn_sock->af, sock_type, 0, &sock); 
    880         if (status != PJ_SUCCESS) { 
    881             pj_turn_sock_destroy(turn_sock); 
    882             return; 
    883         } 
    884  
    885         /* Bind socket */ 
    8861079        cfg_bind_addr = &turn_sock->setting.bound_addr; 
    8871080        max_bind_retry = MAX_BIND_RETRY; 
     
    8971090            pj_sockaddr_cp(&bound_addr, cfg_bind_addr); 
    8981091        } 
    899         status = pj_sock_bind_random(sock, &bound_addr, 
    900                                      turn_sock->setting.port_range, 
    901                                      max_bind_retry); 
    902         if (status != PJ_SUCCESS) { 
    903             pj_turn_sock_destroy(turn_sock); 
    904             return; 
    905         } 
    906  
    907         /* Apply QoS, if specified */ 
    908         status = pj_sock_apply_qos2(sock, turn_sock->setting.qos_type, 
    909                                     &turn_sock->setting.qos_params,  
     1092 
     1093        if (turn_sock->conn_type != PJ_TURN_TP_TLS) { 
     1094            /* Init socket */ 
     1095            status = pj_sock_socket(turn_sock->af, sock_type, 0, &sock); 
     1096            if (status != PJ_SUCCESS) { 
     1097                pj_turn_sock_destroy(turn_sock); 
     1098                return; 
     1099            } 
     1100 
     1101            /* Bind socket */ 
     1102            status = pj_sock_bind_random(sock, &bound_addr, 
     1103                                         turn_sock->setting.port_range, 
     1104                                         max_bind_retry); 
     1105            if (status != PJ_SUCCESS) { 
     1106                pj_turn_sock_destroy(turn_sock); 
     1107                return; 
     1108            } 
     1109            /* Apply QoS, if specified */ 
     1110            status = pj_sock_apply_qos2(sock, turn_sock->setting.qos_type, 
     1111                                    &turn_sock->setting.qos_params, 
    9101112                                    (turn_sock->setting.qos_ignore_error?2:1), 
    9111113                                    turn_sock->pool->obj_name, NULL); 
    912         if (status != PJ_SUCCESS && !turn_sock->setting.qos_ignore_error) { 
    913             pj_turn_sock_destroy(turn_sock); 
    914             return; 
    915         } 
    916  
    917         /* Apply socket buffer size */ 
    918         if (turn_sock->setting.so_rcvbuf_size > 0) { 
    919             unsigned sobuf_size = turn_sock->setting.so_rcvbuf_size; 
    920             status = pj_sock_setsockopt_sobuf(sock, pj_SO_RCVBUF(), 
    921                                               PJ_TRUE, &sobuf_size); 
    922             if (status != PJ_SUCCESS) { 
    923                 PJ_PERROR(3, (turn_sock->obj_name, status, 
    924                               "Failed setting SO_RCVBUF")); 
    925             } else { 
    926                 if (sobuf_size < turn_sock->setting.so_rcvbuf_size) { 
    927                     PJ_LOG(4, (turn_sock->obj_name,  
    928                                "Warning! Cannot set SO_RCVBUF as configured," 
    929                                " now=%d, configured=%d", sobuf_size, 
    930                                turn_sock->setting.so_rcvbuf_size)); 
     1114            if (status != PJ_SUCCESS && !turn_sock->setting.qos_ignore_error)  
     1115            { 
     1116                pj_turn_sock_destroy(turn_sock); 
     1117                return; 
     1118            } 
     1119 
     1120            /* Apply socket buffer size */ 
     1121            if (turn_sock->setting.so_rcvbuf_size > 0) { 
     1122                unsigned sobuf_size = turn_sock->setting.so_rcvbuf_size; 
     1123                status = pj_sock_setsockopt_sobuf(sock, pj_SO_RCVBUF(), 
     1124                                                  PJ_TRUE, &sobuf_size); 
     1125                if (status != PJ_SUCCESS) { 
     1126                    pj_perror(3, turn_sock->obj_name, status, 
     1127                              "Failed setting SO_RCVBUF"); 
    9311128                } else { 
    932                     PJ_LOG(5, (turn_sock->obj_name, "SO_RCVBUF set to %d", 
    933                                sobuf_size)); 
     1129                    if (sobuf_size < turn_sock->setting.so_rcvbuf_size) { 
     1130                        PJ_LOG(4, (turn_sock->obj_name, 
     1131                                "Warning! Cannot set SO_RCVBUF as configured," 
     1132                                " now=%d, configured=%d", sobuf_size, 
     1133                                turn_sock->setting.so_rcvbuf_size)); 
     1134                    } else { 
     1135                        PJ_LOG(5, (turn_sock->obj_name, "SO_RCVBUF set to %d", 
     1136                                   sobuf_size)); 
     1137                    } 
    9341138                } 
    9351139            } 
    936         } 
    937         if (turn_sock->setting.so_sndbuf_size > 0) { 
    938             unsigned sobuf_size = turn_sock->setting.so_sndbuf_size; 
    939             status = pj_sock_setsockopt_sobuf(sock, pj_SO_SNDBUF(), 
    940                                               PJ_TRUE, &sobuf_size); 
    941             if (status != PJ_SUCCESS) { 
    942                 PJ_PERROR(3, (turn_sock->obj_name, status, 
    943                               "Failed setting SO_SNDBUF")); 
    944             } else { 
    945                 if (sobuf_size < turn_sock->setting.so_sndbuf_size) { 
    946                     PJ_LOG(4, (turn_sock->obj_name,  
    947                                "Warning! Cannot set SO_SNDBUF as configured," 
    948                                " now=%d, configured=%d", sobuf_size, 
    949                                turn_sock->setting.so_sndbuf_size)); 
     1140            if (turn_sock->setting.so_sndbuf_size > 0) { 
     1141                unsigned sobuf_size = turn_sock->setting.so_sndbuf_size; 
     1142                status = pj_sock_setsockopt_sobuf(sock, pj_SO_SNDBUF(), 
     1143                                                  PJ_TRUE, &sobuf_size); 
     1144                if (status != PJ_SUCCESS) { 
     1145                    pj_perror(3, turn_sock->obj_name, status, 
     1146                              "Failed setting SO_SNDBUF"); 
    9501147                } else { 
    951                     PJ_LOG(5, (turn_sock->obj_name, "SO_SNDBUF set to %d", 
    952                                sobuf_size)); 
     1148                    if (sobuf_size < turn_sock->setting.so_sndbuf_size) { 
     1149                        PJ_LOG(4, (turn_sock->obj_name, 
     1150                                "Warning! Cannot set SO_SNDBUF as configured," 
     1151                                " now=%d, configured=%d", sobuf_size, 
     1152                                turn_sock->setting.so_sndbuf_size)); 
     1153                    } else { 
     1154                        PJ_LOG(5, (turn_sock->obj_name, "SO_SNDBUF set to %d", 
     1155                                   sobuf_size)); 
     1156                    } 
    9531157                } 
    9541158            } 
    955         } 
    956  
    957         /* Create active socket */ 
    958         pj_activesock_cfg_default(&asock_cfg); 
    959         asock_cfg.grp_lock = turn_sock->grp_lock; 
    960  
    961         pj_bzero(&asock_cb, sizeof(asock_cb)); 
    962         asock_cb.on_data_read = &on_data_read; 
    963         asock_cb.on_connect_complete = &on_connect_complete; 
    964         status = pj_activesock_create(turn_sock->pool, sock, 
    965                                       sock_type, &asock_cfg, 
    966                                       turn_sock->cfg.ioqueue, &asock_cb,  
    967                                       turn_sock, 
    968                                       &turn_sock->active_sock); 
     1159 
     1160            /* Create active socket */ 
     1161            pj_activesock_cfg_default(&asock_cfg); 
     1162            asock_cfg.grp_lock = turn_sock->grp_lock; 
     1163 
     1164            pj_bzero(&asock_cb, sizeof(asock_cb)); 
     1165            asock_cb.on_data_read = &on_data_read_asock; 
     1166            asock_cb.on_connect_complete = &on_connect_complete_asock; 
     1167            status = pj_activesock_create(turn_sock->pool, sock, 
     1168                                          sock_type, &asock_cfg, 
     1169                                          turn_sock->cfg.ioqueue, &asock_cb, 
     1170                                          turn_sock, 
     1171                                          &turn_sock->active_sock); 
     1172        } 
     1173#if PJ_HAS_SSL_SOCK 
     1174        else { 
     1175            //TURN TLS 
     1176            pj_ssl_sock_param param, *ssock_param; 
     1177 
     1178            ssock_param = &turn_sock->setting.tls_cfg.ssock_param; 
     1179            pj_ssl_sock_param_default(&param); 
     1180 
     1181            pj_ssl_sock_param_copy(turn_sock->pool, &param, ssock_param); 
     1182            param.cb.on_connect_complete = &on_connect_complete_ssl_sock; 
     1183            param.cb.on_data_read = &on_data_read_ssl_sock; 
     1184            param.cb.on_data_sent = &on_data_sent_ssl_sock; 
     1185            param.ioqueue = turn_sock->cfg.ioqueue; 
     1186            param.timer_heap = turn_sock->cfg.timer_heap; 
     1187            param.grp_lock = turn_sock->grp_lock; 
     1188            param.server_name = turn_sock->server_name; 
     1189            param.user_data = turn_sock; 
     1190            param.sock_type = sock_type; 
     1191            param.sock_af = turn_sock->af; 
     1192            if (param.send_buffer_size < PJ_TURN_MAX_PKT_LEN) 
     1193                param.send_buffer_size = PJ_TURN_MAX_PKT_LEN; 
     1194            if (param.read_buffer_size < PJ_TURN_MAX_PKT_LEN) 
     1195                param.read_buffer_size = PJ_TURN_MAX_PKT_LEN; 
     1196 
     1197            param.qos_type = turn_sock->setting.qos_type; 
     1198            param.qos_ignore_error = turn_sock->setting.qos_ignore_error; 
     1199            pj_memcpy(&param.qos_params, &turn_sock->setting.qos_params, 
     1200                      sizeof(param.qos_params)); 
     1201 
     1202            if (turn_sock->setting.tls_cfg.cert_file.slen || 
     1203                turn_sock->setting.tls_cfg.ca_list_file.slen || 
     1204                turn_sock->setting.tls_cfg.ca_list_path.slen || 
     1205                turn_sock->setting.tls_cfg.privkey_file.slen) 
     1206            { 
     1207                status = pj_ssl_cert_load_from_files2( 
     1208                    turn_sock->pool, 
     1209                    &turn_sock->setting.tls_cfg.ca_list_file, 
     1210                    &turn_sock->setting.tls_cfg.ca_list_path, 
     1211                    &turn_sock->setting.tls_cfg.cert_file, 
     1212                    &turn_sock->setting.tls_cfg.privkey_file, 
     1213                    &turn_sock->setting.tls_cfg.password, 
     1214                    &turn_sock->cert); 
     1215 
     1216            } else if (turn_sock->setting.tls_cfg.ca_buf.slen || 
     1217                       turn_sock->setting.tls_cfg.cert_buf.slen || 
     1218                       turn_sock->setting.tls_cfg.privkey_buf.slen) 
     1219            { 
     1220                status = pj_ssl_cert_load_from_buffer( 
     1221                    turn_sock->pool, 
     1222                    &turn_sock->setting.tls_cfg.ca_buf, 
     1223                    &turn_sock->setting.tls_cfg.cert_buf, 
     1224                    &turn_sock->setting.tls_cfg.privkey_buf, 
     1225                    &turn_sock->setting.tls_cfg.password, 
     1226                    &turn_sock->cert); 
     1227            } 
     1228            if (status != PJ_SUCCESS) { 
     1229                pj_turn_sock_destroy(turn_sock); 
     1230                return; 
     1231            } 
     1232            if (turn_sock->cert) { 
     1233                pj_turn_sock_tls_cfg_wipe_keys(&turn_sock->setting.tls_cfg); 
     1234            } 
     1235 
     1236            status = pj_ssl_sock_create(turn_sock->pool, &param, 
     1237                                        &turn_sock->ssl_sock); 
     1238 
     1239            if (status != PJ_SUCCESS) { 
     1240                pj_turn_sock_destroy(turn_sock); 
     1241                return; 
     1242            } 
     1243 
     1244            if (turn_sock->cert) { 
     1245                status = pj_ssl_sock_set_certificate(turn_sock->ssl_sock, 
     1246                                                     turn_sock->pool, 
     1247                                                     turn_sock->cert); 
     1248 
     1249                pj_ssl_cert_wipe_keys(turn_sock->cert); 
     1250                turn_sock->cert = NULL; 
     1251            } 
     1252 
     1253        } 
     1254#endif 
     1255 
    9691256        if (status != PJ_SUCCESS) { 
    9701257            pj_turn_sock_destroy(turn_sock); 
     
    9781265 
    9791266        /* Initiate non-blocking connect */ 
     1267        if (turn_sock->conn_type == PJ_TURN_TP_UDP) { 
     1268            status = PJ_SUCCESS; 
     1269        } 
    9801270#if PJ_HAS_TCP 
    981         if (turn_sock->conn_type != PJ_TURN_TP_UDP) { 
     1271        else if (turn_sock->conn_type == PJ_TURN_TP_TCP) { 
    9821272            status=pj_activesock_start_connect( 
    9831273                                        turn_sock->active_sock,  
     
    9851275                                        &info.server,  
    9861276                                        pj_sockaddr_get_len(&info.server)); 
    987         } else { 
    988             status = PJ_SUCCESS; 
    989         } 
     1277        }  
     1278#endif   
     1279#if PJ_HAS_SSL_SOCK 
     1280        else if (turn_sock->conn_type == PJ_TURN_TP_TLS) { 
     1281            pj_ssl_start_connect_param connect_param; 
     1282            connect_param.pool = turn_sock->pool; 
     1283            connect_param.localaddr = &bound_addr; 
     1284            connect_param.local_port_range = turn_sock->setting.port_range; 
     1285            connect_param.remaddr = &info.server; 
     1286            connect_param.addr_len = pj_sockaddr_get_len(&info.server); 
     1287 
     1288            status = pj_ssl_sock_start_connect2(turn_sock->ssl_sock, 
     1289                                                &connect_param); 
     1290        } 
     1291#endif 
    9901292        if (status == PJ_SUCCESS) { 
    991             on_connect_complete(turn_sock->active_sock, PJ_SUCCESS); 
     1293            on_connect_complete(turn_sock, PJ_SUCCESS); 
    9921294        } else if (status != PJ_EPENDING) { 
    9931295            PJ_PERROR(3, (turn_sock->pool->obj_name, status, 
     
    9981300            return; 
    9991301        } 
    1000 #else 
    1001         on_connect_complete(turn_sock->active_sock, PJ_SUCCESS); 
    1002 #endif 
    10031302 
    10041303        /* Done for now. Subsequent work will be done in  
  • pjproject/trunk/pjsip-apps/src/pjsua/pjsua_app_config.c

    r5788 r6004  
    197197    puts  ("                      0=SDES (default), 1=DTLS"); 
    198198#endif 
    199  
     199#if PJ_HAS_SSL_SOCK 
     200    puts  (""); 
     201    puts  ("TURN TLS Options:"); 
     202    puts  ("  --turn-tls          Use TLS connection to TURN server (default no)"); 
     203    puts  ("  --turn-tls-ca-file  Specify TURN TLS CA file (default=none)"); 
     204    puts  ("  --turn-tls-cert-file  Specify TURN TLS certificate file (default=none)"); 
     205    puts  ("  --turn-tls-privkey-file  Specify TURN TLS private key file (default=none)"); 
     206    puts  ("  --turn-tls-privkey-pwd Specify TURN TLS password to private key file (default=none)"); 
     207    puts  ("  --turn-tls-neg-timeout Specify TURN TLS negotiation timeout (default=no)"); 
     208    puts  ("  --turn-tls-cipher   Specify prefered TURN TLS cipher (optional)."); 
     209    puts  ("                      May be specified multiple times"); 
     210#endif 
    200211    puts  (""); 
    201212    puts  ("Buddy List (can be more than one):"); 
     
    361372           OPT_USE_ICE, OPT_ICE_REGULAR, OPT_USE_SRTP, OPT_SRTP_SECURE, 
    362373           OPT_USE_TURN, OPT_ICE_MAX_HOSTS, OPT_ICE_NO_RTCP, OPT_TURN_SRV, 
    363            OPT_TURN_TCP, OPT_TURN_USER, OPT_TURN_PASSWD, OPT_RTCP_MUX, 
    364            OPT_SRTP_KEYING, 
     374           OPT_TURN_TCP, OPT_TURN_USER, OPT_TURN_PASSWD, OPT_TURN_TLS,  
     375           OPT_TURN_TLS_CA_FILE, OPT_TURN_TLS_CERT_FILE,  
     376           OPT_TURN_TLS_NEG_TIMEOUT, OPT_TURN_TLS_CIPHER, 
     377           OPT_TURN_TLS_PRIV_FILE, OPT_TURN_TLS_PASSWORD, 
     378           OPT_RTCP_MUX, OPT_SRTP_KEYING, 
    365379           OPT_PLAY_FILE, OPT_PLAY_TONE, OPT_RTP_PORT, OPT_ADD_CODEC, 
    366380           OPT_ILBC_MODE, OPT_REC_FILE, OPT_AUTO_REC, 
     
    453467        { "turn-srv",   1, 0, OPT_TURN_SRV}, 
    454468        { "turn-tcp",   0, 0, OPT_TURN_TCP}, 
     469#if PJ_HAS_SSL_SOCK 
     470        { "turn-tls",   0, 0, OPT_TURN_TLS}, 
     471        { "turn-tls-ca-file",1, 0, OPT_TURN_TLS_CA_FILE}, 
     472        { "turn-tls-cert-file",1,0, OPT_TURN_TLS_CERT_FILE}, 
     473        { "turn-tls-privkey-file",1,0, OPT_TURN_TLS_PRIV_FILE}, 
     474        { "turn-tls-privkey-pwd",1,0, OPT_TURN_TLS_PASSWORD}, 
     475        { "turn-tls-neg-timeout", 1, 0, OPT_TURN_TLS_NEG_TIMEOUT}, 
     476        { "turn-tls-cipher", 1, 0, OPT_TURN_TLS_CIPHER}, 
     477#endif 
    455478        { "turn-user",  1, 0, OPT_TURN_USER}, 
    456479        { "turn-passwd",1, 0, OPT_TURN_PASSWD}, 
     
    10091032            break; 
    10101033 
     1034#if PJ_HAS_SSL_SOCK 
     1035        case OPT_TURN_TLS: 
     1036            cfg->media_cfg.turn_conn_type = 
     1037                    cur_acc->turn_cfg.turn_conn_type = PJ_TURN_TP_TLS; 
     1038            break; 
     1039        case OPT_TURN_TLS_CA_FILE: 
     1040            cfg->media_cfg.turn_tls_setting.ca_list_file = 
     1041                cur_acc->turn_cfg.turn_tls_setting.ca_list_file = 
     1042                    pj_str(pj_optarg); 
     1043            break; 
     1044 
     1045        case OPT_TURN_TLS_CERT_FILE: 
     1046            cfg->media_cfg.turn_tls_setting.cert_file = 
     1047                cur_acc->turn_cfg.turn_tls_setting.cert_file = 
     1048                    pj_str(pj_optarg); 
     1049            break; 
     1050 
     1051        case OPT_TURN_TLS_PRIV_FILE: 
     1052            cfg->media_cfg.turn_tls_setting.privkey_file = 
     1053                cur_acc->turn_cfg.turn_tls_setting.privkey_file = 
     1054                    pj_str(pj_optarg); 
     1055            break; 
     1056 
     1057        case OPT_TURN_TLS_PASSWORD: 
     1058            cfg->media_cfg.turn_tls_setting.password = 
     1059                cur_acc->turn_cfg.turn_tls_setting.password = 
     1060                    pj_str(pj_optarg); 
     1061            break; 
     1062 
     1063        case OPT_TURN_TLS_NEG_TIMEOUT: 
     1064            cfg->media_cfg.turn_tls_setting.ssock_param.timeout.sec = 
     1065                cur_acc->turn_cfg.turn_tls_setting.ssock_param.timeout.sec = 
     1066                    atoi(pj_optarg); 
     1067            break; 
     1068 
     1069        case OPT_TURN_TLS_CIPHER: 
     1070            { 
     1071                pj_ssl_cipher cipher; 
     1072 
     1073                if (pj_ansi_strnicmp(pj_optarg, "0x", 2) == 0) { 
     1074                    pj_str_t cipher_st = pj_str(pj_optarg + 2); 
     1075                    cipher = pj_strtoul2(&cipher_st, NULL, 16); 
     1076                } else { 
     1077                    cipher = atoi(pj_optarg); 
     1078                } 
     1079 
     1080                if (pj_ssl_cipher_is_supported(cipher)) { 
     1081                    static pj_ssl_cipher tls_ciphers[PJ_SSL_SOCK_MAX_CIPHERS]; 
     1082                    pj_ssl_sock_param *ssock_param = 
     1083                                  &cfg->media_cfg.turn_tls_setting.ssock_param; 
     1084 
     1085                    tls_ciphers[ssock_param->ciphers_num++] = cipher; 
     1086                    ssock_param->ciphers = 
     1087                       cur_acc->turn_cfg.turn_tls_setting.ssock_param.ciphers = 
     1088                            tls_ciphers; 
     1089                } else { 
     1090                    pj_ssl_cipher ciphers[PJ_SSL_SOCK_MAX_CIPHERS]; 
     1091                    unsigned j, ciphers_cnt; 
     1092 
     1093                    ciphers_cnt = PJ_ARRAY_SIZE(ciphers); 
     1094                    pj_ssl_cipher_get_availables(ciphers, &ciphers_cnt); 
     1095 
     1096                    PJ_LOG(1,(THIS_FILE, "Cipher \"%s\" is not supported by " 
     1097                                         "TLS/SSL backend.", pj_optarg)); 
     1098                    printf("Available TLS/SSL ciphers (%d):\n", ciphers_cnt); 
     1099                    for (j=0; j<ciphers_cnt; ++j) 
     1100                        printf("- 0x%06X: %s\n", ciphers[j],  
     1101                               pj_ssl_cipher_name(ciphers[j])); 
     1102                    return -1; 
     1103                } 
     1104            } 
     1105            break; 
     1106#endif 
     1107 
    10111108        case OPT_TURN_USER: 
    10121109            cfg->media_cfg.turn_auth_cred.type = 
  • pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h

    r5989 r6004  
    33473347    /** 
    33483348     * Specify the connection type to be used to the TURN server. Valid 
    3349      * values are PJ_TURN_TP_UDP or PJ_TURN_TP_TCP. 
     3349     * values are PJ_TURN_TP_UDP, PJ_TURN_TP_TCP or PJ_TURN_TP_TLS. 
    33503350     * 
    33513351     * Default: PJ_TURN_TP_UDP 
     
    33573357     */ 
    33583358    pj_stun_auth_cred   turn_auth_cred; 
     3359 
     3360    /** 
     3361     * This specifies TLS settings for TURN TLS. It is only be used 
     3362     * when this TLS is used to connect to the TURN server. 
     3363     */ 
     3364    pj_turn_sock_tls_cfg turn_tls_setting; 
    33593365 
    33603366} pjsua_turn_config; 
     
    66436649    /** 
    66446650     * Specify the connection type to be used to the TURN server. Valid 
    6645      * values are PJ_TURN_TP_UDP or PJ_TURN_TP_TCP. 
     6651     * values are PJ_TURN_TP_UDP, PJ_TURN_TP_TCP or PJ_TURN_TP_TLS. 
    66466652     * 
    66476653     * Default: PJ_TURN_TP_UDP 
     
    66536659     */ 
    66546660    pj_stun_auth_cred   turn_auth_cred; 
     6661 
     6662    /** 
     6663     * This specifies TLS settings for TLS transport. It is only be used 
     6664     * when this TLS is used to connect to the TURN server. 
     6665     */ 
     6666    pj_turn_sock_tls_cfg turn_tls_setting; 
    66556667 
    66566668    /** 
  • pjproject/trunk/pjsip/src/pjsip/sip_transport_tls.c

    r5994 r6004  
    169169/* Clean up TLS resources */ 
    170170static void tls_on_destroy(void *arg); 
     171 
     172static void wipe_buf(pj_str_t *buf); 
    171173 
    172174 
     
    665667{ 
    666668    struct tls_listener *listener = (struct tls_listener*)arg; 
     669 
     670    if (listener->cert) { 
     671        pj_ssl_cert_wipe_keys(listener->cert); 
     672        listener->cert = NULL; 
     673    } 
    667674 
    668675    if (listener->factory.lock) { 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_acc.c

    r5963 r6004  
    713713    if (pjsua_var.default_acc == acc_id) 
    714714        pjsua_var.default_acc = 0; 
     715 
     716#if PJ_HAS_SSL_SOCK 
     717    pj_turn_sock_tls_cfg_wipe_keys(&acc->cfg.turn_cfg.turn_tls_setting); 
     718#endif 
    715719 
    716720    PJSUA_UNLOCK(); 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_core.c

    r5911 r6004  
    239239        dst->turn_server = src->turn_server; 
    240240        dst->turn_auth_cred = src->turn_auth_cred; 
     241 
     242#if PJ_HAS_SSL_SOCK 
     243        pj_memcpy(&dst->turn_tls_setting, &src->turn_tls_setting, 
     244                  sizeof(src->turn_tls_setting)); 
     245#endif 
    241246    } else { 
    242247        if (pj_stricmp(&dst->turn_server, &src->turn_server)) 
     
    244249        pj_stun_auth_cred_dup(pool, &dst->turn_auth_cred, 
    245250                              &src->turn_auth_cred); 
     251 
     252#if PJ_HAS_SSL_SOCK 
     253        pj_turn_sock_tls_cfg_dup(pool, &dst->turn_tls_setting, 
     254                                 &src->turn_tls_setting); 
     255#endif 
    246256    } 
    247257} 
     
    256266        pj_stun_auth_cred_dup(pool, &dst->turn_auth_cred, 
    257267                              &src->turn_auth_cred); 
     268 
     269#if PJ_HAS_SSL_SOCK 
     270        pj_turn_sock_tls_cfg_dup(pool, &dst->turn_tls_setting, 
     271                                 &src->turn_tls_setting); 
     272#endif 
    258273    } 
    259274} 
     
    408423 
    409424    cfg->turn_conn_type = PJ_TURN_TP_UDP; 
     425#if PJ_HAS_SSL_SOCK 
     426    pj_turn_sock_tls_cfg_default(&cfg->turn_tls_setting); 
     427#endif 
    410428    cfg->vid_preview_enable_native = PJ_TRUE; 
    411429} 
     
    19281946                pjsua_acc_set_registration(i, PJ_FALSE); 
    19291947            } 
     1948#if PJ_HAS_SSL_SOCK 
     1949            pj_turn_sock_tls_cfg_wipe_keys( 
     1950                              &pjsua_var.acc[i].cfg.turn_cfg.turn_tls_setting); 
     1951#endif 
    19301952        } 
    19311953 
  • pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c

    r5989 r6004  
    3737    pj_strdup(pool, &dst->turn_server, &src->turn_server); 
    3838    pj_stun_auth_cred_dup(pool, &dst->turn_auth_cred, &src->turn_auth_cred); 
     39#if PJ_HAS_SSL_SOCK 
     40    pj_turn_sock_tls_cfg_dup(pool, &dst->turn_tls_setting, 
     41                             &src->turn_tls_setting); 
     42#endif 
    3943} 
    4044 
     
    10751079            /* Configure max packet size */ 
    10761080            ice_cfg.turn_tp[i].cfg.max_pkt_size = PJMEDIA_MAX_MRU; 
     1081 
     1082#if PJ_HAS_SSL_SOCK 
     1083            if (ice_cfg.turn_tp[i].conn_type == PJ_TURN_TP_TLS) { 
     1084                pj_memcpy(&ice_cfg.turn_tp[i].cfg.tls_cfg,  
     1085                          &acc_cfg->turn_cfg.turn_tls_setting, 
     1086                          sizeof(ice_cfg.turn_tp[i].cfg.tls_cfg)); 
     1087            } 
     1088#endif 
    10771089        } 
    10781090    } 
Note: See TracChangeset for help on using the changeset viewer.