Changeset 656
- Timestamp:
- 02/26/07 14:44:51 (2 years ago)
- Files:
-
- cherokee/trunk/ChangeLog (modified) (1 diff)
- cherokee/trunk/cherokee/buffer.c (modified) (1 diff)
- cherokee/trunk/cherokee/common-internal.h (modified) (1 diff)
- cherokee/trunk/cherokee/connection.c (modified) (8 diffs)
- cherokee/trunk/cherokee/downloader.c (modified) (3 diffs)
- cherokee/trunk/cherokee/fcgi_manager.c (modified) (2 diffs)
- cherokee/trunk/cherokee/handler_fcgi.c (modified) (2 diffs)
- cherokee/trunk/cherokee/handler_mirror.c (modified) (2 diffs)
- cherokee/trunk/cherokee/handler_scgi.c (modified) (2 diffs)
- cherokee/trunk/cherokee/macros.h (modified) (1 diff)
- cherokee/trunk/cherokee/socket.c (modified) (19 diffs)
- cherokee/trunk/cherokee/socket.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
cherokee/trunk/ChangeLog
r655 r656 1 2007-02-26 A.D.F <adefacc@tin.it> 2 3 * cherokee/macros.h: 4 - increase DEFAULT_RECV_SIZE from 1024 to 2048; 5 6 * cherokee/socket.h: 7 - renamed cherokee_socket_read() to cherokee_socket_bufread(); 8 - renamed cherokee_socket_write() to cherokee_socket_bufwrite(); 9 - renamed cherokee_read() to cherokee_socket_read(); 10 - renamed cherokee_write() to cherokee_socket_write(); 11 - renamed cherokee_writev() to cherokee_socket_writev(); 12 13 * cherokee/socket.c: 14 - HAVE_GNUTLS and HAVE_OPENSSL defines are mutually 15 exclusive, so apply #if ... #elif sections consistently; 16 - micro speed-up of cherokee_socket_*read() and 17 cherokee_socket_*write*() by adding likely / unlikely 18 and by shortening fast path; 19 - now cherokee_socket_read() and cherokee_socket_write*() 20 don't accept NULL pointers anymore; it was a waste 21 to handle those cases only for lingering reads; 22 - cherokee_socket_writev(), 23 fixed calculation of data sent to socket. 24 25 * cherokee/connection.c: 26 - cherokee_connection_linger_read(), 27 removed static buffer shared by all threads, 28 now linger data is read into thread->tmp_buf1; 29 - renamed a few cherokee_socket_*() functions; 30 31 * cherokee/downloader.c, cherokee/fcgi_manager.c, 32 cherokee/handler_fcgi.c, cherokee/handler_mirror.c, 33 cherokee/handler_scgi.c, - renamed a few cherokee_socket_*() 34 functions. 35 1 36 2007-02-22 Alvaro Lopez Ortega <alvaro@alobbs.com> 2 37 cherokee/trunk/cherokee/buffer.c
r646 r656 634 634 635 635 /* Maybe it doesn't need it 636 */ 637 if (size <= buf->len) 636 * if buf->size == 0 and size == 0 then buf can be NULL. 637 */ 638 if (size <= buf->size) 638 639 return ret_ok; 639 640 cherokee/trunk/cherokee/common-internal.h
r597 r656 123 123 #else 124 124 # define SOCK_ERRNO() errno 125 # define CLOSE_ON_EXEC(h) fcntl (h, F_SETFD, FD_CLOEXEC , 1)125 # define CLOSE_ON_EXEC(h) fcntl (h, F_SETFD, FD_CLOEXEC) 126 126 #endif 127 127 cherokee/trunk/cherokee/connection.c
r646 r656 601 601 */ 602 602 if (cherokee_buffer_is_empty (&conn->buffer)) { 603 ret = cherokee_ write (&conn->socket, conn->mmaped, conn->mmaped_len, &re);603 ret = cherokee_socket_write (&conn->socket, conn->mmaped, conn->mmaped_len, &re); 604 604 switch (ret) { 605 605 case ret_eof: … … 630 630 bufs[1].iov_len = conn->mmaped_len; 631 631 632 ret = cherokee_ writev (&conn->socket, bufs, 2, &re);632 ret = cherokee_socket_writev (&conn->socket, bufs, 2, &re); 633 633 634 634 switch (ret) { … … 695 695 { 696 696 ret_t ret; 697 size_t readed = 0;698 699 ret = cherokee_socket_ read (&conn->socket, buffer, DEFAULT_RECV_SIZE, &readed);697 size_t cnt_read = 0; 698 699 ret = cherokee_socket_bufread (&conn->socket, buffer, DEFAULT_RECV_SIZE, &cnt_read); 700 700 701 701 switch (ret) { 702 702 case ret_ok: 703 cherokee_connection_rx_add (conn, readed);704 *len = readed;703 cherokee_connection_rx_add (conn, cnt_read); 704 *len = cnt_read; 705 705 return ret_ok; 706 706 … … 767 767 /* Send the buffer content 768 768 */ 769 ret = cherokee_socket_ write (&conn->socket, &conn->buffer, &sent);769 ret = cherokee_socket_bufwrite (&conn->socket, &conn->buffer, &sent); 770 770 if (unlikely(ret != ret_ok)) return ret; 771 771 … … 796 796 /* Send the buffer content 797 797 */ 798 ret = cherokee_socket_ write (&conn->socket, &conn->buffer, &sent);798 ret = cherokee_socket_bufwrite (&conn->socket, &conn->buffer, &sent); 799 799 if (unlikely(ret != ret_ok)) return ret; 800 800 … … 847 847 ret_t ret; 848 848 int retries = 2; 849 size_t readed = 0; 850 849 cherokee_thread_t *thread = CONN_THREAD(conn); 850 cherokee_buffer_t *tmp1 = THREAD_TMP_BUF1(thread); 851 851 852 while (true) { 853 size_t cnt_read = 0; 854 852 855 /* Read from the socket to nowhere 853 856 */ 854 ret = cherokee_socket_read (&conn->socket, NULL, DEFAULT_RECV_SIZE, &readed);857 ret = cherokee_socket_read (&conn->socket, tmp1->buf, tmp1->size, &cnt_read); 855 858 switch (ret) { 856 859 case ret_eof: … … 861 864 return ret; 862 865 case ret_eagain: 863 TRACE(ENTRIES, "read ed %d, eagain\n", readed);866 TRACE(ENTRIES, "read %u, eagain\n", cnt_read); 864 867 return ret; 865 868 case ret_ok: 866 TRACE(ENTRIES, "read ed %d, ok/eagain\n", readed);867 if ( readed > 0 && --retries > 0)869 TRACE(ENTRIES, "read %u, ok\n", cnt_read); 870 if (cnt_read > 0 && --retries > 0) 868 871 continue; 869 872 return ret; 870 873 default: 871 874 RET_UNKNOWN(ret); 875 break; 872 876 } 873 877 return ret_error; … … 1405 1409 ret = cherokee_header_copy_request (&conn->header, &conn->request); 1406 1410 if (unlikely (ret < ret_ok)) goto error; 1411 1412 printf ("len %d\n", conn->request.len); 1413 printf ("buf %d\n", conn->request.buf); 1407 1414 1408 1415 ret = cherokee_header_copy_query_string (&conn->header, &conn->query_string); cherokee/trunk/cherokee/downloader.c
r618 r656 242 242 cherokee_socket_t *sock = &downloader->socket;; 243 243 244 ret = cherokee_socket_ write (sock, buf, &written);244 ret = cherokee_socket_bufwrite (sock, buf, &written); 245 245 switch (ret) { 246 246 case ret_ok: … … 271 271 cherokee_socket_t *sock = &downloader->socket; 272 272 273 ret = cherokee_socket_ read (sock, &downloader->reply_header, DEFAULT_RECV_SIZE, &readed);273 ret = cherokee_socket_bufread (sock, &downloader->reply_header, DEFAULT_RECV_SIZE, &readed); 274 274 switch (ret) { 275 275 case ret_eof: … … 357 357 cherokee_socket_t *sock = &downloader->socket; 358 358 359 ret = cherokee_socket_ read (sock, &downloader->body, DEFAULT_RECV_SIZE, &readed);359 ret = cherokee_socket_bufread (sock, &downloader->body, DEFAULT_RECV_SIZE, &readed); 360 360 switch (ret) { 361 361 case ret_eagain: cherokee/trunk/cherokee/fcgi_manager.c
r597 r656 438 438 439 439 if (mgr->read_buffer.len < sizeof(FCGI_Header)) { 440 ret = cherokee_socket_ read (&mgr->socket, &mgr->read_buffer, DEFAULT_READ_SIZE, &size);440 ret = cherokee_socket_bufread (&mgr->socket, &mgr->read_buffer, DEFAULT_READ_SIZE, &size); 441 441 switch (ret) { 442 442 case ret_ok: … … 473 473 size_t written = 0; 474 474 475 ret = cherokee_socket_ write (&mgr->socket, buf, &written);475 ret = cherokee_socket_bufwrite (&mgr->socket, buf, &written); 476 476 switch (ret) { 477 477 case ret_ok: cherokee/trunk/cherokee/handler_fcgi.c
r625 r656 174 174 cherokee_handler_fcgi_t *fcgi = HDL_FCGI(cgi); 175 175 176 ret = cherokee_socket_ read (&fcgi->socket, &fcgi->write_buffer, DEFAULT_READ_SIZE, &read);176 ret = cherokee_socket_bufread (&fcgi->socket, &fcgi->write_buffer, DEFAULT_READ_SIZE, &read); 177 177 178 178 switch (ret) { … … 548 548 cherokee_connection_t *conn = HANDLER_CONN(hdl); 549 549 550 ret = cherokee_socket_ write (&hdl->socket, buffer, &written);550 ret = cherokee_socket_bufwrite (&hdl->socket, buffer, &written); 551 551 switch (ret) { 552 552 case ret_ok: cherokee/trunk/cherokee/handler_mirror.c
r597 r656 172 172 return ret_ok; 173 173 174 ret = cherokee_socket_ write (&hdl->socket, header, &written);174 ret = cherokee_socket_bufwrite (&hdl->socket, header, &written); 175 175 if (ret != ret_ok) { 176 176 conn->error_code = http_bad_gateway; … … 268 268 size_t got = 0; 269 269 270 ret = cherokee_socket_ read (&hdl->socket, buffer, DEFAULT_READ_SIZE, &got);270 ret = cherokee_socket_bufread (&hdl->socket, buffer, DEFAULT_READ_SIZE, &got); 271 271 switch (ret) { 272 272 case ret_ok: cherokee/trunk/cherokee/handler_scgi.c
r597 r656 131 131 cherokee_handler_scgi_t *scgi = HDL_SCGI(cgi_base); 132 132 133 ret = cherokee_socket_ read (&scgi->socket, buffer, 4096, &read);133 ret = cherokee_socket_bufread (&scgi->socket, buffer, 4096, &read); 134 134 135 135 switch (ret) { … … 300 300 cherokee_connection_t *conn = HANDLER_CONN(hdl); 301 301 302 ret = cherokee_socket_ write (&hdl->socket, &hdl->header, &written);302 ret = cherokee_socket_bufwrite (&hdl->socket, &hdl->header, &written); 303 303 if (ret != ret_ok) { 304 304 conn->error_code = http_bad_gateway; cherokee/trunk/cherokee/macros.h
r642 r656 85 85 #endif 86 86 87 #define DEFAULT_RECV_SIZE 102487 #define DEFAULT_RECV_SIZE 2048 88 88 #define DEFAULT_READ_SIZE 8192 89 89 #define MAX_HEADER_LEN 4096 cherokee/trunk/cherokee/socket.c
r637 r656 122 122 #endif 123 123 124 #if def HAVE_GNUTLS124 #if defined (HAVE_GNUTLS) 125 125 socket->session = NULL; 126 #endif 127 128 #ifdef HAVE_OPENSSL 126 #elif defined (HAVE_OPENSSL) 129 127 socket->session = NULL; 130 128 socket->ssl_ctx = NULL; … … 138 136 cherokee_socket_mrproper (cherokee_socket_t *socket) 139 137 { 140 #if def HAVE_GNUTLS138 #if defined (HAVE_GNUTLS) 141 139 if (socket->session != NULL) { 142 140 gnutls_deinit (socket->session); 143 141 socket->session = NULL; 144 142 } 145 #endif 146 147 #ifdef HAVE_OPENSSL 143 #elif defined (HAVE_OPENSSL) 148 144 if (socket->session != NULL) { 149 145 SSL_free (socket->session); … … 193 189 #endif 194 190 195 #if def HAVE_GNUTLS191 #if defined (HAVE_GNUTLS) 196 192 if (socket->session != NULL) { 197 193 gnutls_deinit (socket->session); 198 194 socket->session = NULL; 199 195 } 200 #endif 201 202 #ifdef HAVE_OPENSSL 196 #elif defined (HAVE_OPENSSL) 203 197 if (socket->session != NULL) { 204 198 SSL_free (socket->session); … … 211 205 } 212 206 #endif 213 207 214 208 return ret_ok; 215 209 } … … 408 402 } 409 403 410 # ifdef HAVE_GNUTLS 404 # if defined (HAVE_GNUTLS) 405 411 406 re = gnutls_handshake (socket->session); 412 407 … … 422 417 return ret_error; 423 418 } 424 # endif 425 426 # ifdef HAVE_OPENSSL 419 420 # elif defined (HAVE_OPENSSL) 421 427 422 re = SSL_accept (socket->session); 428 423 … … 442 437 } 443 438 # endif 444 #endif 439 440 #endif /* HAVE_TLS */ 445 441 return ret_ok; 446 442 } … … 456 452 } 457 453 454 458 455 ret_t 459 456 cherokee_socket_close (cherokee_socket_t *socket) … … 465 462 } 466 463 464 #ifdef HAVE_TLS 467 465 if (socket->is_tls == TLS) { 468 #ifdef HAVE_GNUTLS 466 467 #if defined (HAVE_GNUTLS) 468 469 469 gnutls_bye (socket->session, GNUTLS_SHUT_WR); 470 470 gnutls_deinit (socket->session); 471 471 socket->session = NULL; 472 #endif 473 474 #ifdef HAVE_OPENSSL 472 473 #elif defined (HAVE_OPENSSL) 474 475 475 SSL_shutdown (socket->session); 476 #endif 477 } 476 477 #endif 478 } 479 #endif /* HAVE_TLS */ 478 480 479 481 #ifdef _WIN32 … … 656 658 } 657 659 658 /* Disable Nagle's algorithm for this connection .659 * Written data to the network is not buffered pending660 * acknowledgement of previously written data.660 /* Disable Nagle's algorithm for this connection 661 * so that there is no delay involved when sending data 662 * which don't fill up a full IP datagram. 661 663 */ 662 664 setsockopt (new_socket, IPPROTO_TCP, TCP_NODELAY, (const void *)&tmp, sizeof(tmp)); 663 664 /* Close-on-exec 665 666 /* Close-on-exec, really needed only 667 * if *CGI and / or process pipes are used. 665 668 */ 666 669 CLOSE_ON_EXEC (new_socket); … … 669 672 */ 670 673 cherokee_fd_set_nonblocking (new_socket); 671 674 672 675 *new_fd = new_socket; 673 676 return ret_ok; … … 840 843 841 844 845 /* WARNING: all parameters MUST be valid, 846 * NULL pointers lead to a crash. 847 */ 842 848 ret_t 843 cherokee_ write (cherokee_socket_t *socket, const char *buf, int buf_len, size_t *written)849 cherokee_socket_write (cherokee_socket_t *socket, const char *buf, int buf_len, size_t *pcnt_written) 844 850 { 845 851 ssize_t len; … … 847 853 return_if_fail (buf != NULL, ret_error); 848 854 849 if (socket->is_tls == TLS) { 850 #ifdef HAVE_GNUTLS 851 len = gnutls_record_send (socket->session, buf, buf_len); 852 853 if (len < 0) { 854 switch (len) { 855 #ifdef HAVE_TLS 856 if (likely (socket->is_tls != TLS) { 857 #endif 858 len = send (SOCKET_FD(socket), buf, buf_len, 0); 859 if (likely (len > 0) ) { 860 /* Return info 861 */ 862 *pcnt_written = len; 863 return ret_ok; 864 } 865 if (len == 0) { 866 socket->status = socket_closed; 867 return ret_eof; 868 } 869 /* else len < 0 */ 870 { 871 int err = SOCK_ERRNO(); 872 873 switch (err) { 874 #if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) 875 case EWOULDBLOCK: 876 #endif 877 case EAGAIN: 878 case EINTR: 879 return ret_eagain; 880 881 case EPIPE: 882 #ifdef ENOTCONN 883 case ENOTCONN: 884 #endif 885 case ETIMEDOUT: 886 case ECONNRESET: 887 case EHOSTUNREACH: 888 socket->status = socket_closed; 889 return ret_error; 890 } 891 892 PRINT_ERROR ("ERROR: write(%d, ..) -> errno=%d '%s'\n", 893 SOCKET_FD(socket), err, strerror(err)); 894 return ret_error; 895 } 896 897 #ifdef HAVE_TLS 898 } 899 900 /* TLS connection. 901 */ 902 #if defined (HAVE_GNUTLS) 903 len = gnutls_record_send (socket->session, buf, buf_len); 904 if (likely (len > 0) ) { 905 /* Return info 906 */ 907 *pcnt_written = len; 908 return ret_ok; 909 } 910 911 if (len == 0) { 912 socket->status = socket_closed; 913 return ret_eof; 914 } 915 916 { /* len < 0 */ 917 switch (len) { 855 918 case GNUTLS_E_PUSH_ERROR: 856 919 case GNUTLS_E_INTERRUPTED: … … 860 923 case GNUTLS_E_AGAIN: 861 924 return ret_eagain; 862 } 863 864 PRINT_ERROR ("ERROR: GNUTLS: gnutls_record_send(%d, ..) -> err=%d '%s'\n", 865 SOCKET_FD(socket), (int)len, gnutls_strerror(len)); 866 return ret_error; 867 868 } else if (len == 0) { 925 } 926 927 PRINT_ERROR ("ERROR: GNUTLS: gnutls_record_send(%d, ..) -> err=%d '%s'\n", 928 SOCKET_FD(socket), (int)len, gnutls_strerror(len)); 929 return ret_error; 930 } 931 932 #elif defined (HAVE_OPENSSL) 933 934 len = SSL_write (socket->session, buf, buf_len); 935 936 if (likely (len > 0) ) { 937 /* Return info 938 */ 939 *pcnt_written = len; 940 return ret_ok; 941 } 942 943 if (len == 0) { 944 socket->status = socket_closed; 945 return ret_eof; 946 } 947 948 { /* len < 0 */ 949 int re; 950 951 re = SSL_get_error (socket->session, len); 952 switch (re) { 953 case SSL_ERROR_WANT_WRITE: return ret_eagain; 954 case SSL_ERROR_SSL: return ret_error; 955 } 956 957 PRINT_ERROR ("ERROR: SSL_write (%d, ..) -> err=%d '%s'\n", 958 SOCKET_FD(socket), len, ERR_error_string(re, NULL)); 959 return ret_error; 960 } 961 #else 962 return ret_error; 963 #endif 964 965 #endif /* HAVE_TLS */ 966 967 } 968 969 970 /* WARNING: all parameters MUST be valid, 971 * NULL pointers lead to a crash. 972 */ 973 ret_t 974 cherokee_socket_read (cherokee_socket_t *socket, char *buf, int buf_size, size_t *pcnt_read) 975 { 976 ssize_t len; 977 978 return_if_fail (buf != NULL, ret_error); 979 980 if (unlikely (socket->status == socket_closed)) 981 return ret_eof; 982 983 *pcnt_read = 0; 984 985 #ifdef HAVE_TLS 986 if (likely (socket->is_tls != TLS)) { 987 #endif 988 /* Plain read 989 */ 990 len = recv (SOCKET_FD(socket), buf, buf_size, 0); 991 992 if (likely (len > 0)) { 993 *pcnt_read = len; 994 return ret_ok; 995 } 996 997 if (len == 0) { 869 998 socket->status = socket_closed; 870 999 return ret_eof; 871 1000 } 872 #endif 873 874 #ifdef HAVE_OPENSSL 875 len = SSL_write (socket->session, buf, buf_len); 876 877 if (len < 0) { 878 int re; 879 880 re = SSL_get_error (socket->session, len); 881 switch (re) { 882 case SSL_ERROR_WANT_WRITE: return ret_eagain; 883 case SSL_ERROR_SSL: return ret_error; 1001 1002 { /* len < 0 */ 1003 int err = SOCK_ERRNO(); 1004 1005 switch (err) { 1006 #if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) 1007 case EWOULDBLOCK: 1008 #endif 1009 case EINTR: 1010 case EAGAIN: 1011 return ret_eagain; 1012 1013 case EBADF: 1014 case EPIPE: 1015 case ENOTSOCK: 1016 #ifdef ENOTCONN 1017 case ENOTCONN: 1018 #endif 1019 case ETIMEDOUT: 1020 case ECONNRESET: 1021 case EHOSTUNREACH: 1022 socket->status = socket_closed; 1023 return ret_error; 884 1024 } 885 1025 886 PRINT_ERROR ("ERROR: SSL_write (%d, ..) -> err=%d '%s'\n",887 SOCKET_FD(socket), len, ERR_error_string(re, NULL));1026 PRINT_ERROR ("ERROR: read(%d, ..) -> errno=%d '%s'\n", 1027 SOCKET_FD(socket), err, strerror(err)); 888 1028 return ret_error; 889 890 } else if (len == 0) { 1029 } 1030 1031 #ifdef HAVE_TLS 1032 } 1033 1034 /* socket->is_tls == TLS 1035 */ 1036 #if defined (HAVE_GNUTLS) 1037 1038 len = gnutls_record_recv (socket->session, buf, buf_size); 1039 1040 if (likely (len > 0)) { 1041 *pcnt_read = len; 1042 return ret_ok; 1043 } 1044 1045 if (len == 0) { 1046 socket->status = socket_closed; 1047 return ret_eof; 1048 } 1049 1050 { /* len < 0 */ 1051 switch (len) { 1052 case GNUTLS_E_PUSH_ERROR: 1053 case GNUTLS_E_INTERRUPTED: 1054 case GNUTLS_E_INVALID_SESSION: 1055 case GNUTLS_E_UNEXPECTED_PACKET_LENGTH: 891 1056 socket->status = socket_closed; 892 1057 return ret_eof; 893 } 894 #endif 895 896 goto out; 897 } 898 899 len = send (SOCKET_FD(socket), buf, buf_len, 0); 900 if (len < 0) { 901 int err = SOCK_ERRNO(); 902 903 switch (err) { 904 #if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) 905 case EWOULDBLOCK: 906 #endif 907 case EAGAIN: 908 case EINTR: 1058 case GNUTLS_E_AGAIN: 909 1059 return ret_eagain; 910 911 case EPIPE: 912 #ifdef ENOTCONN 913 case ENOTCONN: 914 #endif 915 case ETIMEDOUT: 916 case ECONNRESET: 917 case EHOSTUNREACH: 918 socket->status = socket_closed; 919 return ret_error; 920 } 921 922 PRINT_ERROR ("ERROR: write(%d, ..) -> errno=%d '%s'\n", 923 SOCKET_FD(socket), err, strerror(err)); 924 return ret_error; 925 926 } else if (len == 0) { 1060 } 1061 1062 PRINT_ERROR ("ERROR: GNUTLS: gnutls_record_recv(%d, ..) -> err=%d '%s'\n", 1063 SOCKET_FD(socket), (int)len, gnutls_strerror(len)); 1064 return ret_error; 1065 } 1066 1067 #elif defined (HAVE_OPENSSL) 1068 len = SSL_read (socket->session, buf, buf_size); 1069 1070 if (likely (len > 0)) { 1071 *pcnt_read = len; 1072 return ret_ok; 1073 } 1074 1075 if (len == 0) { 927 1076 socket->status = socket_closed; 928 1077 return ret_eof; 929 1078 } 930 1079 931 out: 932 /* Return info 933 */ 934 *written = len; 935 return ret_ok; 936 } 937 938 939 ret_t 940 cherokee_read (cherokee_socket_t *socket, char *buf, int buf_size, size_t *done) 941 { 942 ssize_t len; 943 944 if (unlikely (socket->status == socket_closed)) 945 return ret_eof; 946 947 if ((socket->is_tls == TLS) && (buf != NULL)) { 948 #ifdef HAVE_GNUTLS 949 len = gnutls_record_recv (socket->session, buf, buf_size); 950 if (len < 0) { 951 switch (len) { 952 case GNUTLS_E_PUSH_ERROR: 953 case GNUTLS_E_INTERRUPTED: 954 case GNUTLS_E_INVALID_SESSION: 955 case GNUTLS_E_UNEXPECTED_PACKET_LENGTH: 956 socket->status = socket_closed; 957 return ret_eof; 958 case GNUTLS_E_AGAIN: 959 return ret_eagain; 960 } 961 962 PRINT_ERROR ("ERROR: GNUTLS: gnutls_record_recv(%d, ..) -> err=%d '%s'\n", 963 SOCKET_FD(socket), (int)len, gnutls_strerror(len)); 964 return ret_error; 965 966 } else if (len == 0) { 1080 { /* len < 0 */ 1081 int re; 1082 1083 re = SSL_get_error (socket->session, len); 1084 switch (re) { 1085 case SSL_ERROR_WANT_READ: 1086 return ret_eagain; 1087 case SSL_ERROR_ZERO_RETURN: 967 1088 socket->status = socket_closed; 968 1089 return ret_eof; 969 } 970 #endif 971 972 #ifdef HAVE_OPENSSL 973 len = SSL_read (socket->session, buf, buf_size); 974 if (len < 0) { 975 int re; 976 977 re = SSL_get_error (socket->session, len); 978 switch (re) { 979 case SSL_ERROR_WANT_READ: 980 return ret_eagain; 981 case SSL_ERROR_ZERO_RETURN: 982 socket->status = socket_closed; 983 return ret_eof; 984 case SSL_ERROR_SSL: 985 return ret_error; 986 } 987 988 PRINT_ERROR ("ERROR: OpenSSL: SSL_read (%d, ..) -> err=%d '%s'\n", 989 SOCKET_FD(socket), len, ERR_error_string(re, NULL)); 1090 case SSL_ERROR_SSL: 990 1091 return ret_error; 991 992 } else if (len == 0) { 993 socket->status = socket_closed; 994 return ret_eof; 995 } 996 #endif 997 goto out; 998 } 999 1000 /* Plain read 1001 */ 1002 if (unlikely (buf == NULL)) { 1003 static char trash[4096]; 1004 len = recv (SOCKET_FD(socket), trash, sizeof(trash), 0); 1005 } else { 1006 len = recv (SOCKET_FD(socket), buf, buf_size, 0); 1007 } 1008 1009 if (len < 0) { 1010 int err = SOCK_ERRNO(); 1011 1012 switch (err) { 1013 #if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) 1014 case EWOULDBLOCK: 1015 #endif 1016 case EINTR: 1017 case EAGAIN: 1018 return ret_eagain; 1019 1020 case EBADF: 1021 case EPIPE: 1022 case ENOTSOCK: 1023 #ifdef ENOTCONN 1024 case ENOTCONN: 1025 #endif 1026 case ETIMEDOUT: 1027 case ECONNRESET: 1028 case EHOSTUNREACH: 1029 socket->status = socket_closed; 1030 return ret_error; 1031 } 1032 1033 PRINT_ERROR ("ERROR: read(%d, ..) -> errno=%d '%s'\n", 1034 SOCKET_FD(socket), err, strerror(err)); 1035 return ret_error; 1036 1037 } else if (len == 0) { 1038 socket->status = socket_closed; 1039 return ret_eof; 1040 } 1041 1042 out: 1043 /* Return info 1044 */ 1045 if (done != NULL) 1046 *done = len; 1047 1048 return ret_ok; 1049 } 1050 1051 1092 } 1093 1094 PRINT_ERROR ("ERROR: OpenSSL: SSL_read (%d, ..) -> err=%d '%s'\n", 1095 SOCKET_FD(socket), len, ERR_error_string(re, NULL)); 1096 return ret_error; 1097 } 1098 #else 1099 return ret_error; 1100 #endif 1101 1102 #endif /* HAVE_TLS */ 1103 1104 } 1105 1106 1107 /* WARNING: all parameters MUST be valid, 1108 * NULL pointers lead to a crash. 1109 */ 1052 1110 ret_t 1053 cherokee_ writev (cherokee_socket_t *socket, const struct iovec *vector, uint16_t vector_len, size_t *written)1111 cherokee_socket_writev (cherokee_socket_t *socket, const struct iovec *vector, uint16_t vector_len, size_t *pcnt_written) 1054 1112 { 1055 1113 int re; … … 1064 1122 break; 1065 1123 total += re; 1066 } 1067 if (re >= 0) 1068 re = total; 1124 if (re != vector->iov_len) 1125 break; 1126 } 1127 *pcnt_written = total; 1128 1129 /* if we have sent at least one byte, 1130 * then return OK. 1131 */ 1132 if (likely (total > 0)) 1133 return ret_ok; 1134 1135 if (re == 0) { 1136 int err = SOCK_ERRNO(); 1137 if (i == vector_len) 1138 return ret_ok; 1139 /* Retry later. 1140 */ 1141 return ret_eagain; 1142 } 1069 1143 #else 1144 *pcnt_written = 0; 1145 1070 1146 re = writev (SOCKET_FD(socket), vector, vector_len); 1071 #endif 1072 1073 if (re <= 0) { 1147 1148 if (likely (re > 0)) { 1149 *pcnt_written = (size_t) re; 1150 return ret_ok; 1151 } 1152 if (re == 0) 1153 return ret_eagain; 1154 #endif 1155 1156 if (re < 0) { 1074 1157 int err = SOCK_ERRNO(); 1075 1158 … … 1097 1180 } 1098 1181 1099 *written = re; 1100 return ret_ok; 1101 } 1102 1103 1182 return ret_ok; 1183 } 1184 1185 1186 /* WARNING: all parameters MUST be valid, 1187 * NULL pointers lead to a crash. 1188 */ 1104 1189 ret_t 1105 cherokee_socket_ write (cherokee_socket_t *socket, cherokee_buffer_t *buf, size_t *written)1190 cherokee_socket_bufwrite (cherokee_socket_t *socket, cherokee_buffer_t *buf, size_t *pcnt_written) 1106 1191 { 1107 1192 ret_t ret; 1108 size_t tmp = 0; 1109 1110 ret = cherokee_write (socket, buf->buf, buf->len, &tmp); 1111 1112 TRACE (ENTRIES",write", "write fd=%d len=%d ret=%d done=%d\n", socket->socket, buf->len, ret, tmp); 1113 1114 *written = tmp; 1193 1194 ret = cherokee_socket_write (socket, buf->buf, buf->len, pcnt_written); 1195 1196 TRACE (ENTRIES",bufwrite", "write fd=%d len=%d ret=%d written=%u\n", socket->socket, buf->len, ret, *pcnt_written);