diff --git a/pjlib/src/pj/ssl_sock_apple.m b/pjlib/src/pj/ssl_sock_apple.m index 93eed7b231..7570ccdcb2 100644 --- a/pjlib/src/pj/ssl_sock_apple.m +++ b/pjlib/src/pj/ssl_sock_apple.m @@ -297,7 +297,7 @@ pj_status_t ssl_network_event_poll() if (ssock->is_closing || !ssock->pool || (!ssock->is_server && !assock->connection) || - (ssock->is_server && !assock->listener)) + (ssock->is_server && !assock->listener && !assock->connection)) { PJ_LOG(3, (THIS_FILE, "Warning: Discarding SSL event type %d of " "a closing socket %p", event->type, ssock)); @@ -804,10 +804,8 @@ static pj_status_t network_start_read(pj_ssl_sock_t *ssock, if (is_complete && (context == NULL || nw_content_context_get_is_final(context))) { - return; - } - - if (error != NULL) { + status = PJ_EEOF; + } else if (error != NULL) { errno = nw_error_get_error_code(error); if (errno == 89) { /* Since error 89 is network intentionally cancelled by @@ -823,7 +821,7 @@ static pj_status_t network_start_read(pj_ssl_sock_t *ssock, dispatch_block_t schedule_next_receive = ^{ /* If there was no error in receiving, request more data. */ - if (!error && !is_complete && assock->connection) { + if (!error && !is_complete && status != PJ_EEOF) { network_start_read(ssock, async_count, buff_size, readbuf, flags); } @@ -1000,9 +998,11 @@ static pj_status_t network_create_params(pj_ssl_sock_t * ssock, */ sec_protocol_options_set_tls_resumption_enabled(sec_options, false); - /* SSL verification options */ - sec_protocol_options_set_peer_authentication_required(sec_options, - true); + /* SSL peer authentication options */ + if (ssock->is_server && ssock->param.require_client_cert) { + sec_protocol_options_set_peer_authentication_required(sec_options, + true); + } /* Handshake flow: * 1. Server's challenge block, provide server's trust @@ -1164,10 +1164,8 @@ static pj_status_t network_setup_connection(pj_ssl_sock_t *ssock, errno = nw_error_get_error_code(error); warn("Connection failed %p", assock); status = PJ_STATUS_FROM_OS(errno); -#if SSL_DEBUG - PJ_LOG(3, (THIS_FILE, "SSL state and errno %d %d", state, errno)); -#endif - call_cb = PJ_TRUE; + if (ssock->ssl_state == SSL_STATE_HANDSHAKING) + call_cb = PJ_TRUE; } if (state == nw_connection_state_ready) { @@ -1398,7 +1396,8 @@ static pj_status_t network_start_connect(pj_ssl_sock_t *ssock, assock = PJ_POOL_ZALLOC_T(pool, applessl_sock_t); - assock->queue = dispatch_queue_create("ssl_queue", DISPATCH_QUEUE_SERIAL); + assock->queue = dispatch_queue_create("ssl_queue", + DISPATCH_QUEUE_CONCURRENT); assock->ev_semaphore = dispatch_semaphore_create(0); if (!assock->queue || !assock->ev_semaphore) { ssl_destroy(&assock->base); @@ -1430,7 +1429,6 @@ static void close_connection(applessl_sock_t *assock) assock->connection = nil; nw_connection_force_cancel(conn); - nw_release(conn); /* We need to wait until the connection is at cancelled state, * otherwise events will still be delivered even though we @@ -1448,6 +1446,9 @@ static void close_connection(applessl_sock_t *assock) "%p %d", assock, assock->con_state)); } + nw_connection_set_state_changed_handler(conn, nil); + nw_release(conn); + #if SSL_DEBUG PJ_LOG(3, (THIS_FILE, "SSL connection %p closed", assock)); #endif diff --git a/pjlib/src/pjlib-test/ssl_sock.c b/pjlib/src/pjlib-test/ssl_sock.c index 5a95d07149..2ca31e9664 100644 --- a/pjlib/src/pjlib-test/ssl_sock.c +++ b/pjlib/src/pjlib-test/ssl_sock.c @@ -466,7 +466,6 @@ static int https_client_test(unsigned ms_timeout) param.timer_heap = timer; param.timeout.sec = 0; param.timeout.msec = ms_timeout; - param.proto = PJ_SSL_SOCK_PROTO_SSL23; pj_time_val_normalize(¶m.timeout); status = pj_ssl_sock_create(pool, ¶m, &ssock); @@ -658,6 +657,12 @@ static int echo_test(pj_ssl_sock_proto srv_proto, pj_ssl_sock_proto cli_proto, pj_str_t privkey_file = pj_str(CERT_PRIVKEY_FILE); pj_str_t privkey_pass = pj_str(CERT_PRIVKEY_PASS); +#if (PJ_SSL_SOCK_IMP == PJ_SSL_SOCK_IMP_APPLE) + /* We store private key in Keychain. */ + privkey_file = pj_str(""); + privkey_pass = pj_str(""); +#endif + #if (defined(TEST_LOAD_FROM_FILES) && TEST_LOAD_FROM_FILES==1) status = pj_ssl_cert_load_from_files(pool, &ca_file, &cert_file, &privkey_file, &privkey_pass, @@ -810,8 +815,10 @@ static int echo_test(pj_ssl_sock_proto srv_proto, pj_ssl_sock_proto cli_proto, /* Clean up sockets */ { - pj_time_val delay = {0, 100}; + /* The delay must be at least PJ_SSL_SOCK_DELAYED_CLOSE_TIMEOUT. */ + pj_time_val delay = {0, 500}; while (pj_ioqueue_poll(ioqueue, &delay) > 0); + pj_timer_heap_poll(timer, &delay); } if (state_serv.err || state_cli.err) {