1010#include < netdb.h>
1111#include < string>
1212#include < unistd.h>
13+ #include < glog/logging.h>
1314
1415#include " comm/Exception.h"
1516#include " util/gcc_util.h"
@@ -31,35 +32,64 @@ TLSConnection::TLSConnection(
3132{
3233}
3334
35+ static long msec_diff (const struct timespec & a,
36+ const struct timespec & b)
37+ {
38+ return
39+ (a.tv_sec - b.tv_sec ) * 1000 +
40+ (a.tv_nsec - b.tv_nsec ) / 1000000 ;
41+ }
42+
3443size_t TLSConnection::read (uint8_t * buffer, size_t length)
3544{
45+ again:
46+ timespec t1;
47+ clock_gettime (CLOCK_REALTIME_COARSE, &t1);
48+
49+ errno = 0 ;
3650 auto count = SSL_read (_tls_socket->_ssl , buffer, length);
51+ int errno_r = errno;
3752
3853 if (count <= 0 ) {
3954 auto error = SSL_get_error (_tls_socket->_ssl , count);
4055
41- DISABLE_WARNING (logical-op)
4256 if (error == SSL_ERROR_ZERO_RETURN) {
43- THROW_EXCEPTION (ConnectionShutDown, " Closing Connection." );
57+ THROW_EXCEPTION (ConnectionShutDown, // FIXME -- misleading 'ConnectionShutDown'
58+ errno_r, " SSL_read()" , error); // Peer closed conn for writing, so no more reads
4459 }
45- else if (error == SSL_ERROR_SYSCALL && (!errno || errno == EAGAIN)) {
46- THROW_EXCEPTION (ConnectionShutDown, " Closing Connection." );
60+ else if (error == SSL_ERROR_WANT_READ) {
61+ if (errno_r == EAGAIN) {
62+ timespec t2;
63+ clock_gettime (CLOCK_REALTIME_COARSE, &t2);
64+ auto dt = msec_diff (t2, t1);
65+ VLOG (3 ) << " SSL_read(): no activity for " << dt << " msec. Going back to reading" ;
66+ goto again;
67+ } else {
68+ // This error is recoverable. Consider handling it.
69+ THROW_EXCEPTION (ReadFail, errno_r, " SSL_read()" , error);
70+ }
71+ }
72+ else if (error == SSL_ERROR_SYSCALL ||
73+ error == SSL_ERROR_SSL) {
74+ THROW_EXCEPTION (ConnectionShutDown, errno_r, " SSL_read()" , error);
75+ // FIXME: *we* must close the conn
4776 }
4877 else {
49- THROW_EXCEPTION (ReadFail);
78+ THROW_EXCEPTION (ReadFail, errno_r, " SSL_read() " , error );
5079 }
51- ENABLE_WARNING (logical-op)
5280 }
5381
5482 return static_cast <size_t >(count);
5583}
5684
5785size_t TLSConnection::write (const uint8_t * buffer, size_t length)
5886{
87+ errno = 0 ;
5988 auto count = SSL_write (_tls_socket->_ssl , buffer, static_cast <int >(length));
60-
89+ int errno_r = errno;
6190 if (count <= 0 ) {
62- THROW_EXCEPTION (WriteFail, " Error sending message." );
91+ auto error = SSL_get_error (_tls_socket->_ssl , count);
92+ THROW_EXCEPTION (WriteFail, errno_r, " SSL_write()" , error);
6393 }
6494
6595 return static_cast <size_t >(count);
0 commit comments