Ignore:
Timestamp:
Dec 28, 2016 3:40:07 AM (7 years ago)
Author:
nanang
Message:

Re #1900: More merged from trunk (r5512 mistakenly contains merged changes in third-party dir only).

Location:
pjproject/branches/projects/uwp
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • pjproject/branches/projects/uwp

  • pjproject/branches/projects/uwp/pjlib/src/pj/ssl_sock_ossl.c

    r5087 r5513  
    3838#define THIS_FILE               "ssl_sock_ossl.c" 
    3939 
    40 /* Workaround for ticket #985 */ 
    41 #define DELAYED_CLOSE_TIMEOUT   200 
     40/* Workaround for ticket #985 and #1930 */ 
     41#ifndef PJ_SSL_SOCK_DELAYED_CLOSE_TIMEOUT 
     42#   define PJ_SSL_SOCK_DELAYED_CLOSE_TIMEOUT    500 
     43#endif 
    4244 
    4345/*  
     
    4850#include <openssl/err.h> 
    4951#include <openssl/x509v3.h> 
    50  
     52#include <openssl/rand.h> 
     53#include <openssl/engine.h> 
     54 
     55#if defined(PJ_SSL_SOCK_OSSL_HAS_EC) && PJ_SSL_SOCK_OSSL_HAS_EC==1 
     56   extern int tls1_ec_nid2curve_id(int nid); 
     57   extern int tls1_ec_curve_id2nid(int curve_id); 
     58#endif 
    5159 
    5260#ifdef _MSC_VER 
     
    142150    pj_ssl_sock_t        *parent; 
    143151    pj_ssl_sock_param     param; 
     152    pj_ssl_sock_param     newsock_param; 
    144153    pj_ssl_cert_t        *cert; 
    145154     
     
    297306} openssl_ciphers[PJ_SSL_SOCK_MAX_CIPHERS]; 
    298307 
     308/* OpenSSL available curves */ 
     309static unsigned openssl_curves_num; 
     310static struct openssl_curves_t { 
     311    pj_ssl_curve    id; 
     312    const char      *name; 
     313} openssl_curves[PJ_SSL_SOCK_MAX_CURVES]; 
     314 
    299315/* OpenSSL application data index */ 
    300316static int sslsock_idx; 
     
    326342 
    327343    /* Init available ciphers */ 
    328     if (openssl_cipher_num == 0) { 
     344    if (openssl_cipher_num == 0 || openssl_curves_num == 0) { 
    329345        SSL_METHOD *meth = NULL; 
    330346        SSL_CTX *ctx; 
     
    332348        STACK_OF(SSL_CIPHER) *sk_cipher; 
    333349        unsigned i, n; 
     350        int nid; 
     351        const char *cname; 
    334352 
    335353        meth = (SSL_METHOD*)SSLv23_server_method(); 
     
    350368 
    351369        ssl = SSL_new(ctx); 
     370 
    352371        sk_cipher = SSL_get_ciphers(ssl); 
    353372 
     
    363382            openssl_ciphers[i].name = SSL_CIPHER_get_name(c); 
    364383        } 
     384        openssl_cipher_num = n; 
     385 
     386        ssl->session = SSL_SESSION_new(); 
     387 
     388#if defined(PJ_SSL_SOCK_OSSL_HAS_EC) && PJ_SSL_SOCK_OSSL_HAS_EC==1 
     389        openssl_curves_num = SSL_get_shared_curve(ssl,-1); 
     390        if (openssl_curves_num > PJ_ARRAY_SIZE(openssl_curves)) 
     391            openssl_curves_num = PJ_ARRAY_SIZE(openssl_curves); 
     392 
     393        for (i = 0; i < openssl_curves_num; i++) { 
     394            nid = SSL_get_shared_curve(ssl, i); 
     395 
     396            if (nid & TLSEXT_nid_unknown) { 
     397                cname = "curve unknown"; 
     398                nid &= 0xFFFF; 
     399            } else { 
     400                cname = EC_curve_nid2nist(nid); 
     401                if (!cname) 
     402                    cname = OBJ_nid2sn(nid); 
     403            } 
     404 
     405            openssl_curves[i].id   = tls1_ec_nid2curve_id(nid); 
     406            openssl_curves[i].name = cname; 
     407        } 
     408#else 
     409        PJ_UNUSED_ARG(nid); 
     410        PJ_UNUSED_ARG(cname); 
     411        openssl_curves_num = 0; 
     412#endif 
    365413 
    366414        SSL_free(ssl); 
    367415        SSL_CTX_free(ctx); 
    368  
    369         openssl_cipher_num = n; 
    370416    } 
    371417 
     
    373419    sslsock_idx = SSL_get_ex_new_index(0, "SSL socket", NULL, NULL, NULL); 
    374420 
    375     return PJ_SUCCESS; 
     421    return status; 
    376422} 
    377423 
     
    496542/* Setting SSL sock cipher list */ 
    497543static pj_status_t set_cipher_list(pj_ssl_sock_t *ssock); 
    498  
     544/* Setting SSL sock curves list */ 
     545static pj_status_t set_curves_list(pj_ssl_sock_t *ssock); 
     546/* Setting sigalgs list */ 
     547static pj_status_t set_sigalgs(pj_ssl_sock_t *ssock); 
     548/* Setting entropy for rng */ 
     549static void set_entropy(pj_ssl_sock_t *ssock); 
    499550 
    500551/* Create and initialize new SSL context and instance */ 
     
    520571    /* Make sure OpenSSL library has been initialized */ 
    521572    init_openssl(); 
     573 
     574    set_entropy(ssock); 
    522575 
    523576    if (ssock->param.proto == PJ_SSL_SOCK_PROTO_DEFAULT) 
     
    773826        return status; 
    774827 
     828    /* Set curve list */ 
     829    status = set_curves_list(ssock); 
     830    if (status != PJ_SUCCESS) 
     831        return status; 
     832 
     833    /* Set sigalg list */ 
     834    status = set_sigalgs(ssock); 
     835    if (status != PJ_SUCCESS) 
     836        return status; 
     837 
    775838    /* Setup SSL BIOs */ 
    776839    ssock->ossl_rbio = BIO_new(BIO_s_mem()); 
     
    807870 
    808871 
     872/* Close sockets */ 
     873static void close_sockets(pj_ssl_sock_t *ssock) 
     874{ 
     875    pj_activesock_t *asock; 
     876    pj_sock_t sock; 
     877 
     878    /* This can happen when pj_ssl_sock_create() fails. */ 
     879    if (!ssock->write_mutex) 
     880        return; 
     881 
     882    pj_lock_acquire(ssock->write_mutex); 
     883    asock = ssock->asock; 
     884    if (asock) { 
     885        // Don't set ssock->asock to NULL, as it may trigger assertion in 
     886        // send operation. This should be safe as active socket will simply 
     887        // return PJ_EINVALIDOP on any operation if it is already closed. 
     888        //ssock->asock = NULL; 
     889        ssock->sock = PJ_INVALID_SOCKET; 
     890    } 
     891    sock = ssock->sock; 
     892    if (sock != PJ_INVALID_SOCKET) 
     893        ssock->sock = PJ_INVALID_SOCKET; 
     894    pj_lock_release(ssock->write_mutex); 
     895 
     896    if (asock) 
     897        pj_activesock_close(asock); 
     898 
     899    if (sock != PJ_INVALID_SOCKET) 
     900        pj_sock_close(sock); 
     901} 
     902 
     903 
    809904/* Reset SSL socket state */ 
    810905static void reset_ssl_sock_state(pj_ssl_sock_t *ssock) 
    811906{ 
     907    pj_lock_acquire(ssock->write_mutex); 
    812908    ssock->ssl_state = SSL_STATE_NULL; 
    813  
    814     destroy_ssl(ssock); 
    815  
    816     if (ssock->asock) { 
    817         pj_activesock_close(ssock->asock); 
    818         ssock->asock = NULL; 
    819         ssock->sock = PJ_INVALID_SOCKET; 
    820     } 
    821     if (ssock->sock != PJ_INVALID_SOCKET) { 
    822         pj_sock_close(ssock->sock); 
    823         ssock->sock = PJ_INVALID_SOCKET; 
    824     } 
     909    pj_lock_release(ssock->write_mutex); 
     910 
     911    close_sockets(ssock); 
    825912 
    826913    /* Upon error, OpenSSL may leave any error description in the thread  
     
    837924static pj_status_t set_cipher_list(pj_ssl_sock_t *ssock) 
    838925{ 
    839     char buf[1024]; 
     926    pj_pool_t *tmp_pool = NULL; 
     927    char *buf = NULL; 
     928    enum { BUF_SIZE = 8192 }; 
    840929    pj_str_t cipher_list; 
    841930    STACK_OF(SSL_CIPHER) *sk_cipher; 
     
    851940        return PJ_SUCCESS; 
    852941    } 
     942 
     943    /* Create temporary pool. */ 
     944    tmp_pool = pj_pool_create(ssock->pool->factory, "ciphpool", BUF_SIZE,  
     945                              BUF_SIZE/2 , NULL); 
     946    if (!tmp_pool) 
     947        return PJ_ENOMEM; 
     948 
     949    buf = (char *)pj_pool_zalloc(tmp_pool, BUF_SIZE); 
    853950 
    854951    pj_strset(&cipher_list, buf, 0); 
     
    872969                /* Check buffer size */ 
    873970                if (cipher_list.slen + pj_ansi_strlen(c_name) + 2 > 
    874                     sizeof(buf)) 
     971                    BUF_SIZE) 
    875972                { 
    876973                    pj_assert(!"Insufficient temporary buffer for cipher"); 
     
    895992    ret = SSL_set_cipher_list(ssock->ossl_ssl, buf); 
    896993    if (ret < 1) { 
     994        pj_pool_release(tmp_pool); 
    897995        return GET_SSL_STATUS(ssock); 
    898996    } 
    899997 
     998    pj_pool_release(tmp_pool); 
    900999    return PJ_SUCCESS; 
    9011000} 
    9021001 
     1002static pj_status_t set_curves_list(pj_ssl_sock_t *ssock) 
     1003{ 
     1004#if defined(PJ_SSL_SOCK_OSSL_HAS_EC) && PJ_SSL_SOCK_OSSL_HAS_EC==1 
     1005    int ret; 
     1006    int curves[PJ_SSL_SOCK_MAX_CURVES]; 
     1007    int cnt; 
     1008 
     1009    if (ssock->param.curves_num == 0) 
     1010        return PJ_SUCCESS; 
     1011 
     1012    for (cnt = 0; cnt < ssock->param.curves_num; cnt++) { 
     1013        curves[cnt] = tls1_ec_curve_id2nid(ssock->param.curves[cnt]); 
     1014    } 
     1015 
     1016    if( ssock->ossl_ssl->server ) { 
     1017        ret = SSL_set1_curves(ssock->ossl_ssl, curves, 
     1018                              ssock->param.curves_num); 
     1019        if (ret < 1) 
     1020            return GET_SSL_STATUS(ssock); 
     1021    } else { 
     1022        ret = SSL_CTX_set1_curves(ssock->ossl_ctx, curves, 
     1023                                  ssock->param.curves_num); 
     1024        if (ret < 1) 
     1025            return GET_SSL_STATUS(ssock); 
     1026    } 
     1027#else 
     1028    PJ_UNUSED_ARG(ssock); 
     1029#endif 
     1030 
     1031    return PJ_SUCCESS; 
     1032} 
     1033 
     1034static pj_status_t set_sigalgs(pj_ssl_sock_t *ssock) 
     1035{ 
     1036#if defined(PJ_SSL_SOCK_OSSL_HAS_SIGALG) && PJ_SSL_SOCK_OSSL_HAS_SIGALG==1 
     1037    int ret; 
     1038 
     1039    if (ssock->param.sigalgs.ptr && ssock->param.sigalgs.slen) { 
     1040        if (ssock->is_server) { 
     1041            ret = SSL_set1_client_sigalgs_list(ssock->ossl_ssl, 
     1042                                               ssock->param.sigalgs.ptr); 
     1043        } else { 
     1044            ret = SSL_set1_sigalgs_list(ssock->ossl_ssl, 
     1045                                        ssock->param.sigalgs.ptr); 
     1046        } 
     1047 
     1048        if (ret < 1) 
     1049            return GET_SSL_STATUS(ssock); 
     1050    } 
     1051#else 
     1052    PJ_UNUSED_ARG(ssock); 
     1053#endif 
     1054 
     1055    return PJ_SUCCESS; 
     1056} 
     1057 
     1058static void set_entropy(pj_ssl_sock_t *ssock) 
     1059{ 
     1060    int ret; 
     1061 
     1062    switch (ssock->param.entropy_type) { 
     1063#ifndef OPENSSL_NO_EGD 
     1064        case PJ_SSL_ENTROPY_EGD: 
     1065            ret = RAND_egd(ssock->param.entropy_path.ptr); 
     1066            break; 
     1067#endif 
     1068        case PJ_SSL_ENTROPY_RANDOM: 
     1069            ret = RAND_load_file("/dev/random",255); 
     1070            break; 
     1071        case PJ_SSL_ENTROPY_URANDOM: 
     1072            ret = RAND_load_file("/dev/urandom",255); 
     1073            break; 
     1074        case PJ_SSL_ENTROPY_FILE: 
     1075            ret = RAND_load_file(ssock->param.entropy_path.ptr,255); 
     1076            break; 
     1077        case PJ_SSL_ENTROPY_NONE: 
     1078            default: 
     1079            return; 
     1080            break; 
     1081    } 
     1082 
     1083    if (ret < 0) { 
     1084        PJ_LOG(3, (ssock->pool->obj_name, "SSL failed to reseed with " 
     1085                                          "entropy type %d", 
     1086                                          ssock->param.entropy_type)); 
     1087    } 
     1088} 
    9031089 
    9041090/* Parse OpenSSL ASN1_TIME to pj_time_val and GMT info */ 
     
    9651151    char *p, *q; 
    9661152 
    967     pj_bzero(cn, sizeof(cn)); 
     1153    pj_bzero(cn, sizeof(pj_str_t)); 
    9681154 
    9691155    p = pj_strstr(gen_name, &CN_sign); 
     
    9831169 * to be updated by inspecting the issuer and the serial number. 
    9841170 */ 
    985 static void get_cert_info(pj_pool_t *pool, pj_ssl_cert_info *ci, X509 *x) 
     1171static void get_cert_info(pj_pool_t *pool, pj_ssl_cert_info *ci, X509 *x, 
     1172                          pj_bool_t get_pem) 
    9861173{ 
    9871174    pj_bool_t update_needed; 
    9881175    char buf[512]; 
    9891176    pj_uint8_t serial_no[64] = {0}; /* should be >= sizeof(ci->serial_no) */ 
    990     pj_uint8_t *p; 
     1177    pj_uint8_t *q; 
    9911178    unsigned len; 
    9921179    GENERAL_NAMES *names = NULL; 
     
    9981185 
    9991186    /* Get serial no */ 
    1000     p = (pj_uint8_t*) M_ASN1_STRING_data(X509_get_serialNumber(x)); 
     1187    q = (pj_uint8_t*) M_ASN1_STRING_data(X509_get_serialNumber(x)); 
    10011188    len = M_ASN1_STRING_length(X509_get_serialNumber(x)); 
    10021189    if (len > sizeof(ci->serial_no))  
    10031190        len = sizeof(ci->serial_no); 
    1004     pj_memcpy(serial_no + sizeof(ci->serial_no) - len, p, len); 
     1191    pj_memcpy(serial_no + sizeof(ci->serial_no) - len, q, len); 
    10051192 
    10061193    /* Check if the contents need to be updated. */ 
     
    10961283        } 
    10971284    } 
     1285 
     1286    if (get_pem) { 
     1287        /* Update raw Certificate info in PEM format. */ 
     1288        BIO *bio;        
     1289        BUF_MEM *ptr; 
     1290         
     1291        bio = BIO_new(BIO_s_mem()); 
     1292        if (!PEM_write_bio_X509(bio, x)) { 
     1293            PJ_LOG(3,(THIS_FILE, "Error retrieving raw certificate info")); 
     1294            ci->raw.ptr = NULL; 
     1295            ci->raw.slen = 0; 
     1296        } else { 
     1297            BIO_write(bio, "\0", 1); 
     1298            BIO_get_mem_ptr(bio, &ptr); 
     1299            pj_strdup2(pool, &ci->raw, ptr->data);       
     1300        }        
     1301        BIO_free(bio);       
     1302    }     
    10981303} 
    10991304 
     
    11111316    x = SSL_get_certificate(ssock->ossl_ssl); 
    11121317    if (x) { 
    1113         get_cert_info(ssock->pool, &ssock->local_cert_info, x); 
     1318        get_cert_info(ssock->pool, &ssock->local_cert_info, x, PJ_FALSE); 
    11141319        /* Don't free local's X509! */ 
    11151320    } else { 
     
    11201325    x = SSL_get_peer_certificate(ssock->ossl_ssl); 
    11211326    if (x) { 
    1122         get_cert_info(ssock->pool, &ssock->remote_cert_info, x); 
     1327        get_cert_info(ssock->pool, &ssock->remote_cert_info, x, PJ_TRUE); 
    11231328        /* Free peer's X509 */ 
    11241329        X509_free(x); 
     
    11611366                      errmsg)); 
    11621367 
    1163             /* Workaround for ticket #985 */ 
    1164 #if (defined(PJ_WIN32) && PJ_WIN32!=0) || (defined(PJ_WIN64) && PJ_WIN64!=0) 
     1368            /* Originally, this is a workaround for ticket #985. However, 
     1369             * a race condition may occur in multiple worker threads 
     1370             * environment when we are destroying SSL objects while other 
     1371             * threads are still accessing them. 
     1372             * Please see ticket #1930 for more info. 
     1373             */ 
     1374#if 1 //(defined(PJ_WIN32) && PJ_WIN32!=0)||(defined(PJ_WIN64) && PJ_WIN64!=0) 
    11651375            if (ssock->param.timer_heap) { 
    1166                 pj_time_val interval = {0, DELAYED_CLOSE_TIMEOUT}; 
    1167  
    1168                 reset_ssl_sock_state(ssock); 
    1169  
     1376                pj_time_val interval = {0, PJ_SSL_SOCK_DELAYED_CLOSE_TIMEOUT}; 
     1377 
     1378                ssock->ssl_state = SSL_STATE_NULL; 
     1379                close_sockets(ssock); 
     1380 
     1381                if (ssock->timer.id != TIMER_NONE) { 
     1382                    pj_timer_heap_cancel(ssock->param.timer_heap, 
     1383                                         &ssock->timer); 
     1384                } 
    11701385                ssock->timer.id = TIMER_CLOSE; 
    11711386                pj_time_val_normalize(&interval); 
     
    11731388                                           &ssock->timer, &interval) != 0) 
    11741389                { 
     1390                    PJ_LOG(3,(ssock->pool->obj_name, "Failed to schedule " 
     1391                              "a delayed close. Race condition may occur.")); 
    11751392                    ssock->timer.id = TIMER_NONE; 
    11761393                    pj_ssl_sock_close(ssock); 
    11771394                } 
    1178             } else  
    1179 #endif  /* PJ_WIN32 */ 
     1395            } else { 
     1396                pj_ssl_sock_close(ssock); 
     1397            } 
     1398#else 
    11801399            { 
    11811400                pj_ssl_sock_close(ssock); 
    11821401            } 
     1402#endif 
     1403 
    11831404            return PJ_FALSE; 
    11841405        } 
     
    15421763} 
    15431764 
     1765static void ssl_on_destroy(void *arg) 
     1766{ 
     1767    pj_pool_t *pool = NULL; 
     1768    pj_ssl_sock_t *ssock = (pj_ssl_sock_t*)arg; 
     1769 
     1770    destroy_ssl(ssock); 
     1771 
     1772    pj_lock_destroy(ssock->write_mutex); 
     1773 
     1774    pool = ssock->pool; 
     1775    ssock->pool = NULL; 
     1776    if (pool) 
     1777        pj_pool_release(pool); 
     1778} 
     1779 
    15441780 
    15451781/* 
     
    17581994    pj_status_t status; 
    17591995 
    1760     PJ_UNUSED_ARG(src_addr_len); 
    1761  
    17621996    /* Create new SSL socket instance */ 
    1763     status = pj_ssl_sock_create(ssock_parent->pool, &ssock_parent->param, 
    1764                                 &ssock); 
     1997    status = pj_ssl_sock_create(ssock_parent->pool, 
     1998                                &ssock_parent->newsock_param, &ssock); 
    17651999    if (status != PJ_SUCCESS) 
    17662000        goto on_return; 
     
    18382072            goto on_return; 
    18392073 
    1840         /* Temporarily add ref the group lock until active socket creation, 
    1841          * to make sure that group lock is destroyed if the active socket 
    1842          * creation fails. 
    1843          */ 
    18442074        pj_grp_lock_add_ref(glock); 
    18452075        asock_cfg.grp_lock = ssock->param.grp_lock = glock; 
     2076        pj_grp_lock_add_handler(ssock->param.grp_lock, ssock->pool, ssock, 
     2077                                ssl_on_destroy); 
    18462078    } 
    18472079 
     
    18582090                                  ssock, 
    18592091                                  &ssock->asock); 
    1860  
    1861     /* This will destroy the group lock if active socket creation fails */ 
    1862     if (asock_cfg.grp_lock) { 
    1863         pj_grp_lock_dec_ref(asock_cfg.grp_lock); 
    1864     } 
    18652092 
    18662093    if (status != PJ_SUCCESS) 
     
    18932120                                        &ssock->timer, 
    18942121                                        &ssock->param.timeout); 
    1895         if (status != PJ_SUCCESS) 
     2122        if (status != PJ_SUCCESS) { 
    18962123            ssock->timer.id = TIMER_NONE; 
     2124            status = PJ_SUCCESS; 
     2125        } 
    18972126    } 
    18982127 
     
    19032132 
    19042133on_return: 
    1905     if (ssock && status != PJ_EPENDING) 
     2134    if (ssock && status != PJ_EPENDING) { 
    19062135        on_handshake_complete(ssock, status); 
     2136    } 
    19072137 
    19082138    /* Must return PJ_TRUE whatever happened, as active socket must  
     
    20452275 
    20462276/* Set SSL socket credentials. */ 
    2047 PJ_DECL(pj_status_t) pj_ssl_sock_set_certificate( 
     2277PJ_DEF(pj_status_t) pj_ssl_sock_set_certificate( 
    20482278                                            pj_ssl_sock_t *ssock, 
    20492279                                            pj_pool_t *pool, 
     
    20552285 
    20562286    cert_ = PJ_POOL_ZALLOC_T(pool, pj_ssl_cert_t); 
    2057     pj_memcpy(cert_, cert, sizeof(cert)); 
     2287    pj_memcpy(cert_, cert, sizeof(pj_ssl_cert_t)); 
    20582288    pj_strdup_with_null(pool, &cert_->CA_file, &cert->CA_file); 
    20592289    pj_strdup_with_null(pool, &cert_->CA_path, &cert->CA_path); 
     
    21492379} 
    21502380 
     2381/* Get available curves. */ 
     2382PJ_DEF(pj_status_t) pj_ssl_curve_get_availables(pj_ssl_curve curves[], 
     2383                                                unsigned *curve_num) 
     2384{ 
     2385    unsigned i; 
     2386 
     2387    PJ_ASSERT_RETURN(curves && curve_num, PJ_EINVAL); 
     2388 
     2389    if (openssl_curves_num == 0) { 
     2390        init_openssl(); 
     2391        shutdown_openssl(); 
     2392    } 
     2393 
     2394    if (openssl_curves_num == 0) { 
     2395        *curve_num = 0; 
     2396        return PJ_ENOTFOUND; 
     2397    } 
     2398 
     2399    *curve_num = PJ_MIN(*curve_num, openssl_curves_num); 
     2400 
     2401    for (i = 0; i < *curve_num; ++i) 
     2402        curves[i] = openssl_curves[i].id; 
     2403 
     2404    return PJ_SUCCESS; 
     2405} 
     2406 
     2407/* Get curve name string. */ 
     2408PJ_DEF(const char*) pj_ssl_curve_name(pj_ssl_curve curve) 
     2409{ 
     2410    unsigned i; 
     2411 
     2412    if (openssl_curves_num == 0) { 
     2413        init_openssl(); 
     2414        shutdown_openssl(); 
     2415    } 
     2416 
     2417    for (i = 0; i < openssl_curves_num; ++i) { 
     2418        if (curve == openssl_curves[i].id) 
     2419            return openssl_curves[i].name; 
     2420    } 
     2421 
     2422    return NULL; 
     2423} 
     2424 
     2425/* Get curve ID from curve name string. */ 
     2426PJ_DEF(pj_ssl_curve) pj_ssl_curve_id(const char *curve_name) 
     2427{ 
     2428    unsigned i; 
     2429 
     2430    if (openssl_curves_num == 0) { 
     2431        init_openssl(); 
     2432        shutdown_openssl(); 
     2433    } 
     2434 
     2435    for (i = 0; i < openssl_curves_num; ++i) { 
     2436        if (!pj_ansi_stricmp(openssl_curves[i].name, curve_name)) 
     2437            return openssl_curves[i].id; 
     2438    } 
     2439 
     2440    return PJ_TLS_UNKNOWN_CURVE; 
     2441} 
     2442 
     2443/* Check if the specified curve is supported by SSL/TLS backend. */ 
     2444PJ_DEF(pj_bool_t) pj_ssl_curve_is_supported(pj_ssl_curve curve) 
     2445{ 
     2446    unsigned i; 
     2447 
     2448    if (openssl_curves_num == 0) { 
     2449        init_openssl(); 
     2450        shutdown_openssl(); 
     2451    } 
     2452 
     2453    for (i = 0; i < openssl_curves_num; ++i) { 
     2454        if (curve == openssl_curves[i].id) 
     2455            return PJ_TRUE; 
     2456    } 
     2457 
     2458    return PJ_FALSE; 
     2459} 
    21512460 
    21522461/* 
     
    21802489    status = pj_lock_create_recursive_mutex(pool, pool->obj_name, 
    21812490                                            &ssock->write_mutex); 
    2182     if (status != PJ_SUCCESS) 
     2491    if (status != PJ_SUCCESS) { 
     2492        pj_pool_release(pool); 
    21832493        return status; 
     2494    } 
    21842495 
    21852496    /* Init secure socket param */ 
    2186     ssock->param = *param; 
     2497    pj_ssl_sock_param_copy(pool, &ssock->param, param); 
     2498 
     2499    if (ssock->param.grp_lock) { 
     2500        pj_grp_lock_add_ref(ssock->param.grp_lock); 
     2501        pj_grp_lock_add_handler(ssock->param.grp_lock, pool, ssock, 
     2502                                ssl_on_destroy); 
     2503    } 
     2504 
    21872505    ssock->param.read_buffer_size = ((ssock->param.read_buffer_size+7)>>3)<<3; 
    2188     if (param->ciphers_num > 0) { 
    2189         unsigned i; 
    2190         ssock->param.ciphers = (pj_ssl_cipher*) 
    2191                                pj_pool_calloc(pool, param->ciphers_num,  
    2192                                               sizeof(pj_ssl_cipher)); 
    2193         for (i = 0; i < param->ciphers_num; ++i) 
    2194             ssock->param.ciphers[i] = param->ciphers[i]; 
    2195     } 
    2196  
    2197     /* Server name must be null-terminated */ 
    2198     pj_strdup_with_null(pool, &ssock->param.server_name,  
    2199                         &param->server_name); 
     2506    if (!ssock->param.timer_heap) { 
     2507        PJ_LOG(3,(ssock->pool->obj_name, "Warning: timer heap is not " 
     2508                  "available. It is recommended to supply one to avoid " 
     2509                  "a race condition if more than one worker threads " 
     2510                  "are used.")); 
     2511    } 
    22002512 
    22012513    /* Finally */ 
     
    22122524PJ_DEF(pj_status_t) pj_ssl_sock_close(pj_ssl_sock_t *ssock) 
    22132525{ 
    2214     pj_pool_t *pool; 
    2215  
    22162526    PJ_ASSERT_RETURN(ssock, PJ_EINVAL); 
    22172527 
     
    22252535 
    22262536    reset_ssl_sock_state(ssock); 
    2227     pj_lock_destroy(ssock->write_mutex); 
    2228      
    2229     pool = ssock->pool; 
    2230     ssock->pool = NULL; 
    2231     if (pool) 
    2232         pj_pool_release(pool); 
     2537    if (ssock->param.grp_lock) { 
     2538        pj_grp_lock_dec_ref(ssock->param.grp_lock); 
     2539    } else { 
     2540        ssl_on_destroy(ssock); 
     2541    } 
    22332542 
    22342543    return PJ_SUCCESS; 
     
    26182927                                              int addr_len) 
    26192928{ 
     2929    return pj_ssl_sock_start_accept2(ssock, pool, localaddr, addr_len, 
     2930                                     &ssock->param); 
     2931} 
     2932 
     2933 
     2934/** 
     2935 * Same as #pj_ssl_sock_start_accept(), but application provides parameter 
     2936 * for new accepted secure sockets. 
     2937 */ 
     2938PJ_DEF(pj_status_t) 
     2939pj_ssl_sock_start_accept2(pj_ssl_sock_t *ssock, 
     2940                          pj_pool_t *pool, 
     2941                          const pj_sockaddr_t *localaddr, 
     2942                          int addr_len, 
     2943                          const pj_ssl_sock_param *newsock_param) 
     2944{ 
    26202945    pj_activesock_cb asock_cb; 
    26212946    pj_activesock_cfg asock_cfg; 
     
    26232948 
    26242949    PJ_ASSERT_RETURN(ssock && pool && localaddr && addr_len, PJ_EINVAL); 
     2950 
     2951    /* Verify new socket parameters */ 
     2952    if (newsock_param->grp_lock != ssock->param.grp_lock || 
     2953        newsock_param->sock_af != ssock->param.sock_af || 
     2954        newsock_param->sock_type != ssock->param.sock_type) 
     2955    { 
     2956        return PJ_EINVAL; 
     2957    } 
    26252958 
    26262959    /* Create socket */ 
     
    26923025 
    26933026    /* Start accepting */ 
     3027    pj_ssl_sock_param_copy(pool, &ssock->newsock_param, newsock_param); 
     3028    ssock->newsock_param.grp_lock = NULL; 
    26943029    status = pj_activesock_start_accept(ssock->asock, pool); 
    26953030    if (status != PJ_SUCCESS) 
     
    27163051 * Starts asynchronous socket connect() operation. 
    27173052 */ 
    2718 PJ_DECL(pj_status_t) pj_ssl_sock_start_connect(pj_ssl_sock_t *ssock, 
     3053PJ_DEF(pj_status_t) pj_ssl_sock_start_connect( pj_ssl_sock_t *ssock, 
    27193054                                               pj_pool_t *pool, 
    27203055                                               const pj_sockaddr_t *localaddr, 
     
    27923127                                        &ssock->timer, 
    27933128                                        &ssock->param.timeout); 
    2794         if (status != PJ_SUCCESS) 
     3129        if (status != PJ_SUCCESS) { 
    27953130            ssock->timer.id = TIMER_NONE; 
     3131            status = PJ_SUCCESS; 
     3132        } 
    27963133    } 
    27973134 
Note: See TracChangeset for help on using the changeset viewer.