Changeset 2986 for pjproject/trunk/pjlib/src/pj/ssl_sock_ossl.c
- Timestamp:
- Nov 4, 2009 5:08:32 PM (14 years ago)
- File:
-
- 1 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);
Note: See TracChangeset
for help on using the changeset viewer.