- Timestamp:
- Dec 28, 2016 3:40:07 AM (8 years ago)
- Location:
- pjproject/branches/projects/uwp
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/branches/projects/uwp
- Property svn:mergeinfo changed
/pjproject/trunk (added) merged: 5209,5212-5234,5237-5253,5255,5257-5292,5294-5297,5299-5332,5334-5394,5396-5438,5440-5469,5471-5496,5498-5510
- Property svn:mergeinfo changed
-
pjproject/branches/projects/uwp/pjlib/src/pj/ssl_sock_ossl.c
r5087 r5513 38 38 #define THIS_FILE "ssl_sock_ossl.c" 39 39 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 42 44 43 45 /* … … 48 50 #include <openssl/err.h> 49 51 #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 51 59 52 60 #ifdef _MSC_VER … … 142 150 pj_ssl_sock_t *parent; 143 151 pj_ssl_sock_param param; 152 pj_ssl_sock_param newsock_param; 144 153 pj_ssl_cert_t *cert; 145 154 … … 297 306 } openssl_ciphers[PJ_SSL_SOCK_MAX_CIPHERS]; 298 307 308 /* OpenSSL available curves */ 309 static unsigned openssl_curves_num; 310 static struct openssl_curves_t { 311 pj_ssl_curve id; 312 const char *name; 313 } openssl_curves[PJ_SSL_SOCK_MAX_CURVES]; 314 299 315 /* OpenSSL application data index */ 300 316 static int sslsock_idx; … … 326 342 327 343 /* Init available ciphers */ 328 if (openssl_cipher_num == 0 ) {344 if (openssl_cipher_num == 0 || openssl_curves_num == 0) { 329 345 SSL_METHOD *meth = NULL; 330 346 SSL_CTX *ctx; … … 332 348 STACK_OF(SSL_CIPHER) *sk_cipher; 333 349 unsigned i, n; 350 int nid; 351 const char *cname; 334 352 335 353 meth = (SSL_METHOD*)SSLv23_server_method(); … … 350 368 351 369 ssl = SSL_new(ctx); 370 352 371 sk_cipher = SSL_get_ciphers(ssl); 353 372 … … 363 382 openssl_ciphers[i].name = SSL_CIPHER_get_name(c); 364 383 } 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 365 413 366 414 SSL_free(ssl); 367 415 SSL_CTX_free(ctx); 368 369 openssl_cipher_num = n;370 416 } 371 417 … … 373 419 sslsock_idx = SSL_get_ex_new_index(0, "SSL socket", NULL, NULL, NULL); 374 420 375 return PJ_SUCCESS;421 return status; 376 422 } 377 423 … … 496 542 /* Setting SSL sock cipher list */ 497 543 static pj_status_t set_cipher_list(pj_ssl_sock_t *ssock); 498 544 /* Setting SSL sock curves list */ 545 static pj_status_t set_curves_list(pj_ssl_sock_t *ssock); 546 /* Setting sigalgs list */ 547 static pj_status_t set_sigalgs(pj_ssl_sock_t *ssock); 548 /* Setting entropy for rng */ 549 static void set_entropy(pj_ssl_sock_t *ssock); 499 550 500 551 /* Create and initialize new SSL context and instance */ … … 520 571 /* Make sure OpenSSL library has been initialized */ 521 572 init_openssl(); 573 574 set_entropy(ssock); 522 575 523 576 if (ssock->param.proto == PJ_SSL_SOCK_PROTO_DEFAULT) … … 773 826 return status; 774 827 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 775 838 /* Setup SSL BIOs */ 776 839 ssock->ossl_rbio = BIO_new(BIO_s_mem()); … … 807 870 808 871 872 /* Close sockets */ 873 static 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 809 904 /* Reset SSL socket state */ 810 905 static void reset_ssl_sock_state(pj_ssl_sock_t *ssock) 811 906 { 907 pj_lock_acquire(ssock->write_mutex); 812 908 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); 825 912 826 913 /* Upon error, OpenSSL may leave any error description in the thread … … 837 924 static pj_status_t set_cipher_list(pj_ssl_sock_t *ssock) 838 925 { 839 char buf[1024]; 926 pj_pool_t *tmp_pool = NULL; 927 char *buf = NULL; 928 enum { BUF_SIZE = 8192 }; 840 929 pj_str_t cipher_list; 841 930 STACK_OF(SSL_CIPHER) *sk_cipher; … … 851 940 return PJ_SUCCESS; 852 941 } 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); 853 950 854 951 pj_strset(&cipher_list, buf, 0); … … 872 969 /* Check buffer size */ 873 970 if (cipher_list.slen + pj_ansi_strlen(c_name) + 2 > 874 sizeof(buf))971 BUF_SIZE) 875 972 { 876 973 pj_assert(!"Insufficient temporary buffer for cipher"); … … 895 992 ret = SSL_set_cipher_list(ssock->ossl_ssl, buf); 896 993 if (ret < 1) { 994 pj_pool_release(tmp_pool); 897 995 return GET_SSL_STATUS(ssock); 898 996 } 899 997 998 pj_pool_release(tmp_pool); 900 999 return PJ_SUCCESS; 901 1000 } 902 1001 1002 static 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 1034 static 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 1058 static 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 } 903 1089 904 1090 /* Parse OpenSSL ASN1_TIME to pj_time_val and GMT info */ … … 965 1151 char *p, *q; 966 1152 967 pj_bzero(cn, sizeof( cn));1153 pj_bzero(cn, sizeof(pj_str_t)); 968 1154 969 1155 p = pj_strstr(gen_name, &CN_sign); … … 983 1169 * to be updated by inspecting the issuer and the serial number. 984 1170 */ 985 static void get_cert_info(pj_pool_t *pool, pj_ssl_cert_info *ci, X509 *x) 1171 static void get_cert_info(pj_pool_t *pool, pj_ssl_cert_info *ci, X509 *x, 1172 pj_bool_t get_pem) 986 1173 { 987 1174 pj_bool_t update_needed; 988 1175 char buf[512]; 989 1176 pj_uint8_t serial_no[64] = {0}; /* should be >= sizeof(ci->serial_no) */ 990 pj_uint8_t * p;1177 pj_uint8_t *q; 991 1178 unsigned len; 992 1179 GENERAL_NAMES *names = NULL; … … 998 1185 999 1186 /* 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)); 1001 1188 len = M_ASN1_STRING_length(X509_get_serialNumber(x)); 1002 1189 if (len > sizeof(ci->serial_no)) 1003 1190 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); 1005 1192 1006 1193 /* Check if the contents need to be updated. */ … … 1096 1283 } 1097 1284 } 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 } 1098 1303 } 1099 1304 … … 1111 1316 x = SSL_get_certificate(ssock->ossl_ssl); 1112 1317 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); 1114 1319 /* Don't free local's X509! */ 1115 1320 } else { … … 1120 1325 x = SSL_get_peer_certificate(ssock->ossl_ssl); 1121 1326 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); 1123 1328 /* Free peer's X509 */ 1124 1329 X509_free(x); … … 1161 1366 errmsg)); 1162 1367 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) 1165 1375 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 } 1170 1385 ssock->timer.id = TIMER_CLOSE; 1171 1386 pj_time_val_normalize(&interval); … … 1173 1388 &ssock->timer, &interval) != 0) 1174 1389 { 1390 PJ_LOG(3,(ssock->pool->obj_name, "Failed to schedule " 1391 "a delayed close. Race condition may occur.")); 1175 1392 ssock->timer.id = TIMER_NONE; 1176 1393 pj_ssl_sock_close(ssock); 1177 1394 } 1178 } else 1179 #endif /* PJ_WIN32 */ 1395 } else { 1396 pj_ssl_sock_close(ssock); 1397 } 1398 #else 1180 1399 { 1181 1400 pj_ssl_sock_close(ssock); 1182 1401 } 1402 #endif 1403 1183 1404 return PJ_FALSE; 1184 1405 } … … 1542 1763 } 1543 1764 1765 static 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 1544 1780 1545 1781 /* … … 1758 1994 pj_status_t status; 1759 1995 1760 PJ_UNUSED_ARG(src_addr_len);1761 1762 1996 /* 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); 1765 1999 if (status != PJ_SUCCESS) 1766 2000 goto on_return; … … 1838 2072 goto on_return; 1839 2073 1840 /* Temporarily add ref the group lock until active socket creation,1841 * to make sure that group lock is destroyed if the active socket1842 * creation fails.1843 */1844 2074 pj_grp_lock_add_ref(glock); 1845 2075 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); 1846 2078 } 1847 2079 … … 1858 2090 ssock, 1859 2091 &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 }1865 2092 1866 2093 if (status != PJ_SUCCESS) … … 1893 2120 &ssock->timer, 1894 2121 &ssock->param.timeout); 1895 if (status != PJ_SUCCESS) 2122 if (status != PJ_SUCCESS) { 1896 2123 ssock->timer.id = TIMER_NONE; 2124 status = PJ_SUCCESS; 2125 } 1897 2126 } 1898 2127 … … 1903 2132 1904 2133 on_return: 1905 if (ssock && status != PJ_EPENDING) 2134 if (ssock && status != PJ_EPENDING) { 1906 2135 on_handshake_complete(ssock, status); 2136 } 1907 2137 1908 2138 /* Must return PJ_TRUE whatever happened, as active socket must … … 2045 2275 2046 2276 /* Set SSL socket credentials. */ 2047 PJ_DE CL(pj_status_t) pj_ssl_sock_set_certificate(2277 PJ_DEF(pj_status_t) pj_ssl_sock_set_certificate( 2048 2278 pj_ssl_sock_t *ssock, 2049 2279 pj_pool_t *pool, … … 2055 2285 2056 2286 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)); 2058 2288 pj_strdup_with_null(pool, &cert_->CA_file, &cert->CA_file); 2059 2289 pj_strdup_with_null(pool, &cert_->CA_path, &cert->CA_path); … … 2149 2379 } 2150 2380 2381 /* Get available curves. */ 2382 PJ_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. */ 2408 PJ_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. */ 2426 PJ_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. */ 2444 PJ_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 } 2151 2460 2152 2461 /* … … 2180 2489 status = pj_lock_create_recursive_mutex(pool, pool->obj_name, 2181 2490 &ssock->write_mutex); 2182 if (status != PJ_SUCCESS) 2491 if (status != PJ_SUCCESS) { 2492 pj_pool_release(pool); 2183 2493 return status; 2494 } 2184 2495 2185 2496 /* 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 2187 2505 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 ¶m->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 } 2200 2512 2201 2513 /* Finally */ … … 2212 2524 PJ_DEF(pj_status_t) pj_ssl_sock_close(pj_ssl_sock_t *ssock) 2213 2525 { 2214 pj_pool_t *pool;2215 2216 2526 PJ_ASSERT_RETURN(ssock, PJ_EINVAL); 2217 2527 … … 2225 2535 2226 2536 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 } 2233 2542 2234 2543 return PJ_SUCCESS; … … 2618 2927 int addr_len) 2619 2928 { 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 */ 2938 PJ_DEF(pj_status_t) 2939 pj_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 { 2620 2945 pj_activesock_cb asock_cb; 2621 2946 pj_activesock_cfg asock_cfg; … … 2623 2948 2624 2949 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 } 2625 2958 2626 2959 /* Create socket */ … … 2692 3025 2693 3026 /* Start accepting */ 3027 pj_ssl_sock_param_copy(pool, &ssock->newsock_param, newsock_param); 3028 ssock->newsock_param.grp_lock = NULL; 2694 3029 status = pj_activesock_start_accept(ssock->asock, pool); 2695 3030 if (status != PJ_SUCCESS) … … 2716 3051 * Starts asynchronous socket connect() operation. 2717 3052 */ 2718 PJ_DE CL(pj_status_t) pj_ssl_sock_start_connect(pj_ssl_sock_t *ssock,3053 PJ_DEF(pj_status_t) pj_ssl_sock_start_connect( pj_ssl_sock_t *ssock, 2719 3054 pj_pool_t *pool, 2720 3055 const pj_sockaddr_t *localaddr, … … 2792 3127 &ssock->timer, 2793 3128 &ssock->param.timeout); 2794 if (status != PJ_SUCCESS) 3129 if (status != PJ_SUCCESS) { 2795 3130 ssock->timer.id = TIMER_NONE; 3131 status = PJ_SUCCESS; 3132 } 2796 3133 } 2797 3134
Note: See TracChangeset
for help on using the changeset viewer.