@@ -747,7 +747,10 @@ class session : public enable_shared_from_this<session>, public session_impl {
747
747
748
748
session (session_type t, shared_ptr<tls::certificate_credentials> creds,
749
749
std::unique_ptr<net::connected_socket_impl> sock, tls_options options = {})
750
- : _sock(std::move(sock))
750
+ : _logger(this )
751
+ , _sock(std::move(sock))
752
+ , _local_address(fmt::format(" {}" , _sock->local_address ()))
753
+ , _remote_address(fmt::format(" {}" , _sock->remote_address ()))
751
754
, _creds(creds->_impl)
752
755
, _in(_sock->source ())
753
756
, _out(_sock->sink ())
@@ -815,11 +818,17 @@ class session : public enable_shared_from_this<session>, public session_impl {
815
818
assert (_output_pending.available ());
816
819
}
817
820
821
+ const char * get_type_string () const {
822
+ return _type == session_type::CLIENT ? " Client" : " Server" ;
823
+ }
824
+
818
825
// This function waits for the _output_pending future to resolve
819
826
// If an error occurs, it is saved off into _error and returned
820
827
future<> wait_for_output () {
828
+ _logger.trace (" wait_for_output" );
821
829
return std::exchange (_output_pending, make_ready_future ())
822
830
.handle_exception ([this ](auto ep) {
831
+ _logger.debug (" wait_for_output error: {}" , ep);
823
832
_error = ep;
824
833
return make_exception_future (ep);
825
834
});
@@ -891,7 +900,9 @@ class session : public enable_shared_from_this<session>, public session_impl {
891
900
// will attempt to send the provided packet. If a renegotiation is needed
892
901
// any unprocessed part of the packet is returned.
893
902
future<net::packet> do_put (net::packet p) {
903
+ _logger.trace (" do_put" );
894
904
if (!connected ()) {
905
+ _logger.debug (" do_put: not connected" );
895
906
return make_ready_future<net::packet>(std::move (p));
896
907
}
897
908
assert (_output_pending.available ());
@@ -910,8 +921,10 @@ class session : public enable_shared_from_this<session>, public session_impl {
910
921
size_t bytes_written = 0 ;
911
922
auto write_rc = SSL_write_ex (
912
923
_ssl.get (), frag_view.data (), frag_view.size (), &bytes_written);
924
+ _logger.trace (" do_put: SSL_write_ex: {}" , write_rc);
913
925
if (write_rc != 1 ) {
914
926
const auto ssl_err = SSL_get_error (_ssl.get (), write_rc);
927
+ _logger.trace (" do_put: SSL_get_error: {}" , ssl_err);
915
928
if (ssl_err == SSL_ERROR_WANT_WRITE) {
916
929
return wait_for_output ().then ([] {
917
930
return stop_iteration::no;
@@ -922,6 +935,7 @@ class session : public enable_shared_from_this<session>, public session_impl {
922
935
}
923
936
return handle_do_put_ssl_err (ssl_err);
924
937
} else {
938
+ _logger.trace (" do_put: bytes_written: {}" , bytes_written);
925
939
frag_view.remove_prefix (bytes_written);
926
940
p.trim_front (bytes_written);
927
941
return wait_for_output ().then ([] {
@@ -930,7 +944,8 @@ class session : public enable_shared_from_this<session>, public session_impl {
930
944
}
931
945
});
932
946
}
933
- ).then ([&p] {
947
+ ).then ([this , &p] {
948
+ _logger.trace (" do_put: returning packet of size: {}" , p.len ());
934
949
return std::move (p);
935
950
});
936
951
}
@@ -940,6 +955,7 @@ class session : public enable_shared_from_this<session>, public session_impl {
940
955
// Used to push unencrypted data through OpenSSL, which will
941
956
// encrypt it and then place it into the output bio.
942
957
future<> put (net::packet p) override {
958
+ _logger.trace (" put" );
943
959
constexpr size_t openssl_max_record_size = 16 * 1024 ;
944
960
if (_error) {
945
961
return make_exception_future (_error);
@@ -949,6 +965,7 @@ class session : public enable_shared_from_this<session>, public session_impl {
949
965
std::system_error (EPIPE, std::system_category ()));
950
966
}
951
967
if (!connected ()) {
968
+ _logger.trace (" put: not connected, performing handshake" );
952
969
return handshake ().then (
953
970
[this , p = std::move (p)]() mutable { return put (std::move (p)); });
954
971
}
@@ -966,8 +983,10 @@ class session : public enable_shared_from_this<session>, public session_impl {
966
983
return do_put (std::move (p));
967
984
}).then ([this ](net::packet p) {
968
985
if (eof () || p.len () == 0 ) {
986
+ _logger.trace (" put: eof: {}, p.len(): {}" , eof (), p.len ());
969
987
return make_ready_future ();
970
988
} else {
989
+ _logger.trace (" put: not completed packet sending, re-doing handshake" );
971
990
return handshake ().then ([this , p = std::move (p)]() mutable {
972
991
return put (std::move (p));
973
992
});
@@ -979,7 +998,9 @@ class session : public enable_shared_from_this<session>, public session_impl {
979
998
// This function will walk through the handshake with a remote peer
980
999
// If EOF is encountered, ENOTCONN is thrown
981
1000
future<> do_handshake () {
1001
+ _logger.trace (" do_handshake" );
982
1002
if (eof ()) {
1003
+ _logger.trace (" do_handshake: eof encountered" );
983
1004
// if we have experienced and eof, set the error and return
984
1005
// GnuTLS will probably return GNUTLS_E_PREMATURE_TERMINATION
985
1006
// from gnutls_handshake in this situation.
@@ -989,15 +1010,18 @@ class session : public enable_shared_from_this<session>, public session_impl {
989
1010
" EOF encountered during handshake" ));
990
1011
return make_exception_future (_error);
991
1012
} else if (connected ()) {
1013
+ _logger.trace (" do_handshake: already connected" );
992
1014
return make_ready_future<>();
993
1015
}
994
1016
return do_until (
995
1017
[this ] { return connected () || eof (); },
996
1018
[this ] {
997
1019
try {
998
1020
auto n = SSL_do_handshake (_ssl.get ());
1021
+ _logger.trace (" do_handshake: SSL_do_handshake: {}" , n);
999
1022
if (n <= 0 ) {
1000
1023
auto ssl_error = SSL_get_error (_ssl.get (), n);
1024
+ _logger.trace (" do_handshake: SSL_get_error: {}" , ssl_error);
1001
1025
switch (ssl_error) {
1002
1026
case SSL_ERROR_NONE:
1003
1027
// probably shouldn't have gotten here
@@ -1020,6 +1044,7 @@ class session : public enable_shared_from_this<session>, public session_impl {
1020
1044
case SSL_ERROR_SSL:
1021
1045
{
1022
1046
auto ec = ERR_GET_REASON (ERR_peek_error ());
1047
+ _logger.debug (" do_handshake: ERR_GET_REASON: {}" , ec);
1023
1048
switch (ec) {
1024
1049
case SSL_R_UNEXPECTED_EOF_WHILE_READING:
1025
1050
// well in this situation, the remote end closed
@@ -1062,17 +1087,21 @@ class session : public enable_shared_from_this<session>, public session_impl {
1062
1087
// This function will attempt to pull data off of the _in stream
1063
1088
// if there isn't already data needing to be processed first.
1064
1089
future<> wait_for_input () {
1090
+ _logger.trace (" wait_for_input" );
1065
1091
// If we already have data, then it needs to be processed
1066
1092
if (!_input.empty ()) {
1093
+ _logger.trace (" wait_for_input: input not empty" );
1067
1094
return make_ready_future ();
1068
1095
}
1069
1096
return _in.get ()
1070
1097
.then ([this ](buf_type buf) {
1071
1098
// Set EOF if it's empty
1099
+ _logger.debug (" wait_for_input: buffer {}empty" , buf.empty () ? " is " : " " );
1072
1100
_eof |= buf.empty ();
1073
1101
_input = std::move (buf);
1074
1102
})
1075
1103
.handle_exception ([this ](auto ep) {
1104
+ _logger.debug (" wait_for_input: exception: {}" , ep);
1076
1105
_error = ep;
1077
1106
return make_exception_future (ep);
1078
1107
});
@@ -1083,12 +1112,14 @@ class session : public enable_shared_from_this<session>, public session_impl {
1083
1112
// SSL session using SSL_read. If ther eis no data, then
1084
1113
// we will call perform_pull and wait for data to arrive.
1085
1114
future<buf_type> do_get () {
1115
+ _logger.trace (" do_get" );
1086
1116
// Data is available to be pulled of the SSL session if there is pending
1087
1117
// data on the SSL session or there is data in the in_bio() which SSL reads
1088
1118
// from
1089
1119
auto data_to_pull = (BIO_ctrl_pending (in_bio ()) + SSL_pending (_ssl.get ())) > 0 ;
1090
1120
auto f = make_ready_future<>();
1091
1121
if (!data_to_pull) {
1122
+ _logger.trace (" do_get: no data to pull, waiting for input" );
1092
1123
// If nothing is in the SSL buffers then we may have to wait for
1093
1124
// data to come in
1094
1125
f = wait_for_input ();
@@ -1098,12 +1129,16 @@ class session : public enable_shared_from_this<session>, public session_impl {
1098
1129
return make_ready_future<buf_type>();
1099
1130
}
1100
1131
auto avail = BIO_ctrl_pending (in_bio ()) + SSL_pending (_ssl.get ());
1132
+ _logger.trace (" do_get: available: {}" , avail);
1101
1133
buf_type buf (avail);
1102
1134
size_t bytes_read = 0 ;
1103
1135
auto read_result = SSL_read_ex (
1104
1136
_ssl.get (), buf.get_write (), avail, &bytes_read);
1137
+ _logger.trace (" do_get: SSL_read_ex: {}" , read_result);
1138
+ _logger.trace (" do_get: SSL_read_ex bytes_ready: {}" , bytes_read);
1105
1139
if (read_result != 1 ) {
1106
1140
const auto ssl_err = SSL_get_error (_ssl.get (), read_result);
1141
+ _logger.trace (" do_get: SSL_get_error: {}" , ssl_err);
1107
1142
switch (ssl_err) {
1108
1143
case SSL_ERROR_ZERO_RETURN:
1109
1144
// Remote end has closed
@@ -1164,37 +1199,45 @@ class session : public enable_shared_from_this<session>, public session_impl {
1164
1199
1165
1200
// Called by user applications to pull data off of the TLS session
1166
1201
future<buf_type> get () override {
1202
+ _logger.trace (" get" );
1167
1203
if (_error) {
1168
1204
return make_exception_future<buf_type>(_error);
1169
1205
}
1170
1206
if (_shutdown || eof ()) {
1171
1207
return make_ready_future<buf_type>(buf_type ());
1172
1208
}
1173
1209
if (!connected ()) {
1210
+ _logger.trace (" get: not connected, performing handshake" );
1174
1211
return handshake ().then (std::bind (&session::get, this ));
1175
1212
}
1176
1213
return with_semaphore (_in_sem, 1 , std::bind (&session::do_get, this ))
1177
1214
.then ([this ](buf_type buf) {
1178
1215
if (buf.empty () && !eof ()) {
1216
+ _logger.trace (" get: buffer empty and not eof, performing handshake" );
1179
1217
return handshake ().then (std::bind (&session::get, this ));
1180
1218
}
1219
+ _logger.trace (" get: returning buffer of size {}" , buf.size ());
1181
1220
return make_ready_future<buf_type>(std::move (buf));
1182
1221
});
1183
1222
}
1184
1223
1185
1224
// Performs shutdown
1186
1225
future<> do_shutdown () {
1226
+ _logger.trace (" do_shutdown" );
1187
1227
if (_error || !connected ()) {
1228
+ _logger.trace (" do_shutdown: error exists or not connected" );
1188
1229
return make_ready_future ();
1189
1230
}
1190
1231
1191
1232
auto res = SSL_shutdown (_ssl.get ());
1233
+ _logger.trace (" do_shutdown: SSL_shutdown: {}" , res);
1192
1234
if (res == 1 ) {
1193
1235
return wait_for_output ();
1194
1236
} else if (res == 0 ) {
1195
1237
return yield ().then ([this ] { return do_shutdown (); });
1196
1238
} else {
1197
1239
auto ssl_err = SSL_get_error (_ssl.get (), res);
1240
+ _logger.trace (" do_shutdown: SSL_get_error: {}" , ssl_err);
1198
1241
switch (ssl_err) {
1199
1242
case SSL_ERROR_NONE:
1200
1243
// this is weird, yield and try again
@@ -1242,12 +1285,15 @@ class session : public enable_shared_from_this<session>, public session_impl {
1242
1285
}
1243
1286
1244
1287
void verify () {
1288
+ _logger.trace (" verify" );
1245
1289
if (!_creds->_enable_certificate_verification ) {
1290
+ _logger.debug (" verify: certificate verification disabled, skipping" );
1246
1291
return ;
1247
1292
}
1248
1293
// A success return code (0) does not signify if a cert was presented or not, that
1249
1294
// must be explicitly queried via SSL_get_peer_certificate
1250
1295
auto res = SSL_get_verify_result (_ssl.get ());
1296
+ _logger.trace (" verify: SSL_get_verify_result: {}" , res);
1251
1297
if (res != X509_V_OK) {
1252
1298
auto stat_str (X509_verify_cert_error_string (res));
1253
1299
auto dn = extract_dn_information ();
@@ -1264,6 +1310,7 @@ class session : public enable_shared_from_this<session>, public session_impl {
1264
1310
}
1265
1311
throw verification_error (stat_str);
1266
1312
} else if (SSL_get0_peer_certificate (_ssl.get ()) == nullptr ) {
1313
+ _logger.trace (" verify: No peer certificate" );
1267
1314
// If a peer certificate was not presented,
1268
1315
// SSL_get_verify_result will return X509_V_OK:
1269
1316
// https://www.openssl.org/docs/man3.0/man3/SSL_get_verify_result.html
@@ -1294,6 +1341,7 @@ class session : public enable_shared_from_this<session>, public session_impl {
1294
1341
// This function waits for eof() to occur on the input stream
1295
1342
// Unless wait_for_eof_on_shutdown is false
1296
1343
future<> wait_for_eof () {
1344
+ _logger.trace (" wait_for_eof" );
1297
1345
if (!_options.wait_for_eof_on_shutdown ) {
1298
1346
// Seastar option to allow users to just bypass EOF waiting
1299
1347
return make_ready_future ();
@@ -1305,12 +1353,15 @@ class session : public enable_shared_from_this<session>, public session_impl {
1305
1353
return do_until (
1306
1354
[this ] { return eof (); },
1307
1355
[this ] { return do_get ().discard_result (); });
1356
+ }).finally ([this ] {
1357
+ _logger.trace (" wait_for_eof: complete" );
1308
1358
});
1309
1359
}
1310
1360
1311
1361
// This function is called to kick off the handshake. It will obtain
1312
1362
// locks on the _in_sem and _out_sem semaphores and start the handshake.
1313
1363
future<> handshake () {
1364
+ _logger.trace (" handshake" );
1314
1365
if (_creds->need_load_system_trust ()) {
1315
1366
if (!SSL_CTX_set_default_verify_paths (_ctx.get ())) {
1316
1367
throw make_ossl_error (
@@ -1332,6 +1383,7 @@ class session : public enable_shared_from_this<session>, public session_impl {
1332
1383
}
1333
1384
1334
1385
future<> shutdown () {
1386
+ _logger.trace (" shutdown" );
1335
1387
// first, make sure any pending write is done.
1336
1388
// bye handshake is a flush operation, but this
1337
1389
// allows us to not pay extra attention to output state
@@ -1351,8 +1403,10 @@ class session : public enable_shared_from_this<session>, public session_impl {
1351
1403
}
1352
1404
1353
1405
void close () noexcept override {
1406
+ _logger.trace (" close" );
1354
1407
// only do once.
1355
1408
if (!std::exchange (_shutdown, true )) {
1409
+ _logger.trace (" close: performing shutdown" );
1356
1410
// running in background. try to bye-handshake us nicely, but after 10s we forcefully close.
1357
1411
engine ().run_in_background (with_timeout (
1358
1412
timer<>::clock ::now () + std::chrono::seconds (10 ), shutdown ())
@@ -1465,6 +1519,14 @@ class session : public enable_shared_from_this<session>, public session_impl {
1465
1519
});
1466
1520
}
1467
1521
1522
+ const sstring& local_address () const noexcept {
1523
+ return _local_address;
1524
+ }
1525
+
1526
+ const sstring& remote_address () const noexcept {
1527
+ return _remote_address;
1528
+ }
1529
+
1468
1530
private:
1469
1531
std::vector<subject_alt_name> do_get_alt_name_information (const x509_ptr &peer_cert,
1470
1532
const std::unordered_set<subject_alt_name_type> &types) const {
@@ -1711,7 +1773,10 @@ class session : public enable_shared_from_this<session>, public session_impl {
1711
1773
BIO* out_bio () { return SSL_get_wbio (_ssl.get ()); }
1712
1774
1713
1775
private:
1776
+ tls_session_logger<session> _logger;
1714
1777
std::unique_ptr<net::connected_socket_impl> _sock;
1778
+ sstring _local_address;
1779
+ sstring _remote_address;
1715
1780
shared_ptr<tls::certificate_credentials::impl> _creds;
1716
1781
data_source _in;
1717
1782
data_sink _out;
@@ -1855,9 +1920,11 @@ int bio_create(BIO*) {
1855
1920
// / and set the retry write flag.
1856
1921
int bio_write_ex (BIO* b, const char * data, size_t dlen, size_t * written) {
1857
1922
auto session = unwrap_bio_ptr (b);
1923
+ session->_logger .trace (" bio_write_ex: dlen {}" , dlen);
1858
1924
BIO_clear_retry_flags (b);
1859
1925
1860
1926
if (!session->_output_pending .available ()) {
1927
+ session->_logger .trace (" bio_write_ex: nothing pending in output" );
1861
1928
BIO_set_retry_write (b);
1862
1929
return 0 ;
1863
1930
}
@@ -1870,9 +1937,11 @@ int bio_write_ex(BIO* b, const char * data, size_t dlen, size_t * written) {
1870
1937
msg.append (std::string_view (data, dlen));
1871
1938
n = msg.size ();
1872
1939
session->_output_pending = session->_out .put (std::move (msg).release ());
1940
+ session->_logger .trace (" bio_write_ex: Appended {} bytes to output pending" , n);
1873
1941
}
1874
1942
1875
1943
if (session->_output_pending .failed ()) {
1944
+ session->_logger .debug (" bio_write_ex: output pending has error" );
1876
1945
std::rethrow_exception (session->_output_pending .get_exception ());
1877
1946
}
1878
1947
@@ -1882,9 +1951,11 @@ int bio_write_ex(BIO* b, const char * data, size_t dlen, size_t * written) {
1882
1951
1883
1952
return 1 ;
1884
1953
} catch (const std::system_error & e) {
1954
+ session->_logger .debug (" bio_write_ex: system error occurred: {}" , e.what ());
1885
1955
ERR_raise_data (ERR_LIB_SYS, e.code ().value (), e.what ());
1886
1956
session->_output_pending = make_exception_future<>(std::current_exception ());
1887
1957
} catch (...) {
1958
+ session->_logger .debug (" bio_write_ex: unknown error occurred" );
1888
1959
ERR_raise (ERR_LIB_SYS, EIO);
1889
1960
session->_output_pending = make_exception_future<>(std::current_exception ());
1890
1961
}
@@ -1900,13 +1971,16 @@ int bio_write_ex(BIO* b, const char * data, size_t dlen, size_t * written) {
1900
1971
// / the _input buffer and return it to the caller.
1901
1972
int bio_read_ex (BIO* b, char * data, size_t dlen, size_t *readbytes) {
1902
1973
auto session = unwrap_bio_ptr (b);
1974
+ session->_logger .trace (" bio_read_ex: dlen: {}" , dlen);
1903
1975
BIO_clear_retry_flags (b);
1904
1976
if (session->eof ()) {
1977
+ session->_logger .trace (" bio_read_ex: eof" );
1905
1978
BIO_set_flags (b, BIO_FLAGS_IN_EOF);
1906
1979
return 0 ;
1907
1980
}
1908
1981
1909
1982
if (session->_input .empty ()) {
1983
+ session->_logger .trace (" bio_read_ex: input empty" );
1910
1984
BIO_set_retry_read (b);
1911
1985
return 0 ;
1912
1986
}
@@ -1918,6 +1992,7 @@ int bio_read_ex(BIO* b, char * data, size_t dlen, size_t *readbytes) {
1918
1992
*readbytes = n;
1919
1993
}
1920
1994
1995
+ session->_logger .trace (" bio_read_ex: read {} bytes from input" , n);
1921
1996
return 1 ;
1922
1997
}
1923
1998
0 commit comments