Changeset 2986
- Timestamp:
- Nov 4, 2009 5:08:32 PM (15 years ago)
- Location:
- pjproject/trunk/pjlib/src
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib/src/pj/ssl_sock_ossl.c
r2972 r2986 193 193 PJ_ERRNO_SPACE_SIZE*6) 194 194 195 #define PJ_SSL_ERRNO_SPACE_SIZE 5000 196 197 #define PJ_STATUS_FROM_OSSL(ossl_err) (ossl_err == SSL_ERROR_NONE? \ 198 PJ_SUCCESS : \ 199 (PJ_SSL_ERRNO_START + ossl_err)) 200 201 #define PJ_STATUS_TO_OSSL(status) (status == PJ_SUCCESS? \ 202 SSL_ERROR_NONE : \ 203 (status - PJ_SSL_ERRNO_START)) 204 195 #define PJ_SSL_ERRNO_SPACE_SIZE PJ_ERRNO_SPACE_SIZE 196 197 #define GET_SSL_STATUS(status) { \ 198 unsigned long e = ERR_get_error();\ 199 status = ERR_GET_LIB(e)*300 + ERR_GET_REASON(e);\ 200 pj_assert(status < PJ_SSL_ERRNO_SPACE_SIZE);\ 201 if (status) status += PJ_SSL_ERRNO_START;\ 202 } 205 203 206 204 /* … … 211 209 { 212 210 pj_str_t errstr; 213 unsigned long ssl_err = PJ_STATUS_TO_OSSL(status); 211 unsigned long ssl_err = status; 212 213 if (ssl_err) { 214 unsigned long l, r; 215 ssl_err -= PJ_SSL_ERRNO_START; 216 l = ssl_err/300; 217 r = ssl_err%300; 218 ssl_err = ERR_PACK(l, 0, r); 219 } 214 220 215 221 #if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0) 216 222 217 ERR_error_string_n(ssl_err, buf, bufsize); 218 errstr = pj_str(buf); 219 220 #else 223 { 224 const char *tmp = NULL; 225 tmp = ERR_reason_error_string(ssl_err); 226 227 if (tmp) { 228 pj_ansi_strncpy(buf, tmp, bufsize); 229 errstr = pj_str(buf); 230 return errstr; 231 } 232 } 233 234 #endif /* PJ_HAS_ERROR_STRING */ 221 235 222 236 errstr.ptr = buf; … … 224 238 "Unknown OpenSSL error %d", 225 239 ssl_err); 226 227 #endif /* PJ_HAS_ERROR_STRING */228 240 229 241 return errstr; … … 337 349 pj_ssl_cert_t *cert; 338 350 int mode, rc; 351 pj_status_t status; 339 352 340 353 pj_assert(ssock && p_ctx); … … 370 383 ctx = SSL_CTX_new(ssl_method); 371 384 if (ctx == NULL) { 372 PJ_LOG(1,(ssock->pool->obj_name, "Error creating OpenSSL context"));373 return PJ_STATUS_FROM_OSSL(ERR_get_error());385 GET_SSL_STATUS(status); 386 return status; 374 387 } 375 388 … … 382 395 383 396 if (rc != 1) { 397 GET_SSL_STATUS(status); 384 398 PJ_LOG(1,(ssock->pool->obj_name, "Error loading CA list file " 385 399 "'%s'", cert->CA_file.ptr)); 386 400 SSL_CTX_free(ctx); 387 return PJ_STATUS_FROM_OSSL(ERR_get_error());401 return status; 388 402 } 389 403 } … … 403 417 404 418 if(rc != 1) { 419 GET_SSL_STATUS(status); 405 420 PJ_LOG(1,(ssock->pool->obj_name, "Error loading certificate " 406 421 "chain file '%s'", cert->cert_file.ptr)); 407 422 SSL_CTX_free(ctx); 408 return PJ_STATUS_FROM_OSSL(ERR_get_error());423 return status; 409 424 } 410 425 } … … 418 433 419 434 if(rc != 1) { 435 GET_SSL_STATUS(status); 420 436 PJ_LOG(1,(ssock->pool->obj_name, "Error adding private key " 421 437 "from '%s'", cert->privkey_file.ptr)); 422 438 SSL_CTX_free(ctx); 423 return PJ_STATUS_FROM_OSSL(ERR_get_error());439 return status; 424 440 } 425 441 } … … 543 559 /* Finally, set chosen cipher list */ 544 560 ret = SSL_set_cipher_list(ssock->ossl_ssl, buf); 545 if (ret < 1) 546 return PJ_STATUS_FROM_OSSL(SSL_get_error(ssock->ossl_ssl, ret)); 561 if (ret < 1) { 562 pj_status_t status; 563 GET_SSL_STATUS(status); 564 return status; 565 } 547 566 548 567 return PJ_SUCCESS; … … 688 707 if (status != PJ_SUCCESS) { 689 708 /* Handshake failed in accepting, destroy our self silently. */ 709 710 char errmsg[PJ_ERR_MSG_SIZE]; 711 char buf[PJ_INET6_ADDRSTRLEN+10]; 712 713 pj_strerror(status, errmsg, sizeof(errmsg)); 714 PJ_LOG(3,(ssock->pool->obj_name, "Handshake failed in accepting " 715 "%s: %s", 716 pj_sockaddr_print(&ssock->rem_addr, buf, sizeof(buf), 3), 717 errmsg)); 718 690 719 pj_ssl_sock_close(ssock); 691 720 return PJ_FALSE; … … 875 904 { 876 905 /* Handshake fails */ 906 GET_SSL_STATUS(status); 877 907 pj_lock_release(ssock->write_mutex); 878 return PJ_STATUS_FROM_OSSL(err);908 return status; 879 909 } 880 910 } … … 922 952 nwritten = BIO_write(ssock->ossl_rbio, data, size); 923 953 if (nwritten < size) { 924 status = PJ_STATUS_FROM_OSSL(ERR_get_error());954 GET_SSL_STATUS(status); 925 955 goto on_error; 926 956 } … … 995 1025 if (err != SSL_ERROR_NONE && err != SSL_ERROR_WANT_READ) 996 1026 { 997 char errmsg[PJ_ERR_MSG_SIZE];998 999 pj_strerror(status, errmsg, sizeof(errmsg));1000 PJ_LOG(1,(ssock->pool->obj_name, "SSL_read() failed: %s",1001 errmsg));1002 1003 1027 /* Reset SSL socket state, then return PJ_FALSE */ 1028 GET_SSL_STATUS(status); 1004 1029 reset_ssl_sock_state(ssock); 1005 1030 goto on_error; … … 1018 1043 1019 1044 if (status != PJ_SUCCESS && status != PJ_EPENDING) { 1020 char errmsg[PJ_ERR_MSG_SIZE]; 1021 1022 pj_strerror(status, errmsg, sizeof(errmsg)); 1023 PJ_LOG(1,(ssock->pool->obj_name, "Failed to flush " 1024 "delayed send: %s", errmsg)); 1045 pj_perror(1, ssock->pool->obj_name, status, 1046 "Failed to flush delayed send", 0); 1025 1047 goto on_error; 1026 1048 } 1027 1049 } else if (status != PJ_EPENDING) { 1028 char errmsg[PJ_ERR_MSG_SIZE]; 1029 1030 pj_strerror(status, errmsg, sizeof(errmsg)); 1031 PJ_LOG(1,(ssock->pool->obj_name, "Renegotiation failed: " 1032 "%s", errmsg)); 1050 pj_perror(1, ssock->pool->obj_name, status, 1051 "Renegotiation failed", 0); 1033 1052 goto on_error; 1034 1053 } … … 1122 1141 unsigned i; 1123 1142 pj_status_t status; 1124 char buf[64];1125 1143 1126 1144 PJ_UNUSED_ARG(src_addr_len); 1127 1128 PJ_LOG(4,(ssock_parent->pool->obj_name, "Incoming connection from %s",1129 pj_sockaddr_print(src_addr, buf, sizeof(buf), 3)));1130 1145 1131 1146 /* Create new SSL socket instance */ … … 1150 1165 status = pj_sock_getsockname(ssock->sock, &ssock->local_addr, 1151 1166 &ssock->addr_len); 1152 if (status != PJ_SUCCESS) 1153 goto on_return; 1167 if (status != PJ_SUCCESS) { 1168 /* This fails on few envs, e.g: win IOCP, just tolerate this and 1169 * use parent local address instead. 1170 */ 1171 pj_sockaddr_cp(&ssock->local_addr, &ssock_parent->local_addr); 1172 } 1154 1173 1155 1174 /* Set remote address */ … … 1164 1183 ssock->ossl_ssl = SSL_new(ssock->ossl_ctx); 1165 1184 if (ssock->ossl_ssl == NULL) { 1166 PJ_LOG(1,(ssock->pool->obj_name, "Error creating SSL instance")); 1167 status = PJ_STATUS_FROM_OSSL(ERR_get_error()); 1185 GET_SSL_STATUS(status); 1168 1186 goto on_return; 1169 1187 } … … 1245 1263 SSL_set_accept_state(ssock->ossl_ssl); 1246 1264 status = do_handshake(ssock); 1247 if (status != PJ_EPENDING) 1248 goto on_return; 1249 1265 1266 on_return: 1267 if (ssock && status != PJ_EPENDING) 1268 on_handshake_complete(ssock, status); 1269 1270 /* Must return PJ_TRUE whatever happened, as active socket must 1271 * continue listening. 1272 */ 1250 1273 return PJ_TRUE; 1251 1252 on_return:1253 return on_handshake_complete(ssock, status);1254 1274 } 1255 1275 … … 1280 1300 ssock->ossl_ssl = SSL_new(ssock->ossl_ctx); 1281 1301 if (ssock->ossl_ssl == NULL) { 1282 PJ_LOG(1,(ssock->pool->obj_name, "Error creating SSL instance")); 1283 status = PJ_STATUS_FROM_OSSL(ERR_get_error()); 1302 GET_SSL_STATUS(status); 1284 1303 goto on_return; 1285 1304 } … … 1723 1742 } else { 1724 1743 /* Some problem occured */ 1725 status = PJ_STATUS_FROM_OSSL(err);1744 GET_SSL_STATUS(status); 1726 1745 } 1727 1746 } else { … … 2018 2037 ret = SSL_renegotiate(ssock->ossl_ssl); 2019 2038 if (ret <= 0) { 2020 status = PJ_STATUS_FROM_OSSL(SSL_get_error(ssock->ossl_ssl, ret));2039 GET_SSL_STATUS(status); 2021 2040 } else { 2022 2041 status = do_handshake(ssock); -
pjproject/trunk/pjlib/src/pjlib-test/ssl_sock.c
r2981 r2986 151 151 } 152 152 153 /* Start reading data */ 154 read_buf[0] = st->read_buf; 155 status = pj_ssl_sock_start_read2(ssock, st->pool, sizeof(st->read_buf), (void**)read_buf, 0); 156 if (status != PJ_SUCCESS) { 157 app_perror("...ERROR pj_ssl_sock_start_read2()", status); 158 goto on_return; 159 } 160 153 161 /* Start sending data */ 154 162 while (st->sent < st->send_str_len) { … … 169 177 } 170 178 171 /* Start reading data */172 read_buf[0] = st->read_buf;173 status = pj_ssl_sock_start_read2(ssock, st->pool, sizeof(st->read_buf), (void**)read_buf, 0);174 if (status != PJ_SUCCESS && status != PJ_EPENDING) {175 app_perror("...ERROR pj_ssl_sock_start_read2()", status);176 goto on_return;177 }178 179 179 on_return: 180 180 st->err = status; … … 196 196 { 197 197 struct test_state *parent_st = (struct test_state*) 198 198 pj_ssl_sock_get_user_data(ssock); 199 199 struct test_state *st; 200 200 void *read_buf[1]; … … 237 237 dump_cert_info(".......", &info.remote_cert_info); 238 238 } 239 } 240 241 /* Start reading data */ 242 read_buf[0] = st->read_buf; 243 status = pj_ssl_sock_start_read2(newsock, st->pool, sizeof(st->read_buf), (void**)read_buf, 0); 244 if (status != PJ_SUCCESS) { 245 app_perror("...ERROR pj_ssl_sock_start_read2()", status); 246 goto on_return; 239 247 } 240 248 … … 255 263 else 256 264 break; 257 }258 259 /* Start reading data */260 read_buf[0] = st->read_buf;261 status = pj_ssl_sock_start_read2(newsock, st->pool, sizeof(st->read_buf), (void**)read_buf, 0);262 if (status != PJ_SUCCESS && status != PJ_EPENDING) {263 app_perror("...ERROR pj_ssl_sock_start_read2()", status);264 goto on_return;265 265 } 266 266 … … 422 422 #define HTTP_SERVER_PORT 443 423 423 424 static int https_client_test( void)424 static int https_client_test(unsigned ms_timeout) 425 425 { 426 426 pj_pool_t *pool = NULL; 427 427 pj_ioqueue_t *ioqueue = NULL; 428 pj_timer_heap_t *timer = NULL; 428 429 pj_ssl_sock_t *ssock = NULL; 429 430 pj_ssl_sock_param param; … … 436 437 437 438 status = pj_ioqueue_create(pool, 4, &ioqueue); 439 if (status != PJ_SUCCESS) { 440 goto on_return; 441 } 442 443 status = pj_timer_heap_create(pool, 4, &timer); 438 444 if (status != PJ_SUCCESS) { 439 445 goto on_return; … … 452 458 param.user_data = &state; 453 459 param.server_name = pj_str((char*)HTTP_SERVER_ADDR); 460 param.timer_heap = timer; 461 param.timeout.sec = 0; 462 param.timeout.msec = ms_timeout; 463 pj_time_val_normalize(¶m.timeout); 454 464 455 465 status = pj_ssl_sock_create(pool, ¶m, &ssock); … … 476 486 pj_time_val delay = {0, 100}; 477 487 pj_ioqueue_poll(ioqueue, &delay); 488 pj_timer_heap_poll(timer, &delay); 478 489 #endif 479 490 } … … 492 503 if (ioqueue) 493 504 pj_ioqueue_destroy(ioqueue); 505 if (timer) 506 pj_timer_heap_destroy(timer); 494 507 if (pool) 495 508 pj_pool_release(pool); … … 633 646 } 634 647 648 /* Clean up sockets */ 649 { 650 pj_time_val delay = {0, 100}; 651 while (pj_ioqueue_poll(ioqueue, &delay) > 0); 652 } 653 635 654 if (state_serv.err || state_cli.err) { 636 655 if (state_serv.err != PJ_SUCCESS) … … 683 702 st->err = status; 684 703 704 if (st->err != PJ_SUCCESS || st->done) { 705 pj_activesock_close(asock); 706 if (!st->is_server) 707 clients_num--; 708 return PJ_FALSE; 709 } 710 685 711 return PJ_TRUE; 686 712 } … … 694 720 695 721 if (status == PJ_SUCCESS) { 696 status = pj_activesock_start_read(asock, st->pool, 1, 0); 722 void *read_buf[1]; 723 724 /* Start reading data */ 725 read_buf[0] = st->read_buf; 726 status = pj_activesock_start_read2(asock, st->pool, sizeof(st->read_buf), (void**)read_buf, 0); 727 if (status != PJ_SUCCESS) { 728 app_perror("...ERROR pj_ssl_sock_start_read2()", status); 729 } 697 730 } 698 731 699 732 st->err = status; 733 734 if (st->err != PJ_SUCCESS) { 735 pj_activesock_close(asock); 736 if (!st->is_server) 737 clients_num--; 738 return PJ_FALSE; 739 } 700 740 701 741 return PJ_TRUE; … … 846 886 if (ssock_serv) 847 887 pj_ssl_sock_close(ssock_serv); 848 if (asock_cli )888 if (asock_cli && !state_cli.err && !state_cli.done) 849 889 pj_activesock_close(asock_cli); 850 890 if (timer) … … 859 899 860 900 901 /* Test will perform multiple clients trying to connect to single server. 902 * Once SSL connection established, echo test will be performed. 903 */ 861 904 static int perf_test(unsigned clients, unsigned ms_handshake_timeout) 862 905 { … … 1023 1066 } 1024 1067 1068 /* Clean up sockets */ 1069 { 1070 pj_time_val delay = {0, 500}; 1071 while (pj_ioqueue_poll(ioqueue, &delay) > 0); 1072 } 1073 1025 1074 if (state_serv.err != PJ_SUCCESS) { 1026 1075 status = state_serv.err; … … 1078 1127 return ret; 1079 1128 1080 // Disable this test as requiring internet connection.1081 #if 01082 1129 PJ_LOG(3,("", "..https client test")); 1083 ret = https_client_test(); 1084 if (ret != 0) 1085 return ret; 1086 #endif 1130 ret = https_client_test(30000); 1131 // Ignore test result as internet connection may not be available. 1132 //if (ret != 0) 1133 //return ret; 1134 1135 #ifndef PJ_SYMBIAN 1087 1136 1088 1137 PJ_LOG(3,("", "..echo test w/ TLSv1 and TLS_RSA_WITH_DES_CBC_SHA cipher")); … … 1110 1159 return PJ_EBUG; 1111 1160 1112 PJ_LOG(3,("", "..client non-SSL timeout in 5 secs"));1161 PJ_LOG(3,("", "..client non-SSL (handshake timeout 5 secs)")); 1113 1162 ret = client_non_ssl(5000); 1114 1163 if (ret != 0) … … 1119 1168 if (ret != 0) 1120 1169 return ret; 1170 1171 #endif 1121 1172 1122 1173 return 0;
Note: See TracChangeset
for help on using the changeset viewer.