SNode.C
Loading...
Searching...
No Matches
SocketReader.cpp
Go to the documentation of this file.
1
/*
2
* SNode.C - a slim toolkit for network communication
3
* Copyright (C) Volker Christian <me@vchrist.at>
4
* 2020, 2021, 2022, 2023, 2024, 2025
5
*
6
* This program is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU Lesser General Public License as published
8
* by the Free Software Foundation, either version 3 of the License, or
9
* (at your option) any later version.
10
*
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU Lesser General Public License for more details.
15
*
16
* You should have received a copy of the GNU Lesser General Public License
17
* along with this program. If not, see <http://www.gnu.org/licenses/>.
18
*/
19
20
#
include
"core/socket/stream/tls/SocketReader.h"
21
22
#
ifndef
DOXYGEN_SHOULD_SKIP_THIS
23
24
#
include
"core/socket/stream/tls/ssl_utils.h"
25
#
include
"log/Logger.h"
26
#
include
"utils/PreserveErrno.h"
27
28
#
include
<
cerrno
>
29
#
include
<
limits
>
30
#
include
<
openssl
/
ssl
.
h
>
31
#
include
<
string
>
32
33
#
endif
// DOXYGEN_SHOULD_SKIP_THIS
34
35
namespace
core::socket::
stream
::
tls
{
36
37
ssize_t
SocketReader
::
read
(
char
*
chunk
,
std
::
size_t
chunkLen
) {
38
ssize_t
ret
= 0;
39
40
if
((
SSL_get_shutdown
(
ssl
) & SSL_RECEIVED_SHUTDOWN) != 0) {
41
ret
=
Super
::
read
(
chunk
,
chunkLen
);
42
}
else
{
43
chunkLen
=
chunkLen
>
std
::
numeric_limits
<
int
>::
max
() ?
std
::
numeric_limits
<
int
>::
max
() :
chunkLen
;
44
ret
=
SSL_read
(
ssl
,
chunk
,
static_cast
<
int
>(
chunkLen
));
45
46
if
(
ret
<= 0) {
47
const
int
ssl_err
=
SSL_get_error
(
ssl
,
static_cast
<
int
>(
ret
));
48
49
switch
(
ssl_err
) {
50
case
SSL_ERROR_WANT_READ:
51
errno = EAGAIN;
52
ret
= -1;
53
break
;
54
case
SSL_ERROR_WANT_WRITE:
55
LOG(
TRACE
) <<
getName
() <<
" SSL/TLS: Start renegotiation on read"
;
56
doSSLHandshake
(
57
[
this
]() {
58
LOG(
DEBUG
) <<
getName
() <<
" SSL/TLS: Renegotiation on read success"
;
59
},
60
[
this
]() {
61
LOG(
WARNING
) <<
getName
() <<
" SSL/TLS: Renegotiation on read timed out"
;
62
},
63
[
this
](
int
ssl_err
) {
64
ssl_log
(
getName
() +
" SSL/TLS: Renegotiation on read"
,
ssl_err
);
65
});
66
errno = EAGAIN;
67
ret
= -1;
68
break
;
69
case
SSL_ERROR_ZERO_RETURN:
// received close_notify
70
LOG(
DEBUG
) <<
getName
() <<
" SSL/TLS: Close_notify is"
<< (
closeNotifyIsEOF
?
" "
:
" not "
) <<
"EOF"
;
71
onReadShutdown
();
72
errno =
closeNotifyIsEOF
? 0 : EAGAIN;
73
ret
=
closeNotifyIsEOF
? 0 : -1;
74
break
;
75
case
SSL_ERROR_SYSCALL:
// When SSL_get_error(ssl, ret) returns SSL_ERROR_SYSCALL
76
// and ret is 0, it indicates that the underlying TCP connection
77
// was closed unexpectedly by the peer. This situation typically
78
// happens when the peer closes (FIN) the connection without
79
// sending a close_notify alert, which violates the SSL/TLS
80
// protocol’s graceful shutdown procedure.
81
// In case ret is -1 a real syscall error (RST = ECONNRESET)
82
{
83
const
utils
::
PreserveErrno
pe
;
84
85
if
(
ret
== 0) {
86
PLOG(
DEBUG
) <<
getName
() <<
" SSL/TLS: EOF detected: Connection closed by peer."
;
87
}
else
{
88
PLOG(
WARNING
) <<
getName
() +
" SSL/TLS: Syscall error on read"
;
89
}
90
}
91
ret
= -1;
92
break
;
93
case
SSL_ERROR_SSL:
94
ssl_log
(
getName
() +
" SSL/TLS: Read failed"
,
ssl_err
);
95
onReadShutdown
();
96
ret
= -1;
97
break
;
98
default
:
99
ssl_log
(
getName
() +
" SSL/TLS: Unexpected error"
,
ssl_err
);
100
onReadShutdown
();
101
errno = EIO;
102
ret
= -1;
103
break
;
104
}
105
}
106
}
107
108
return
ret
;
109
}
110
111
}
// namespace core::socket::stream::tls
core::socket::stream::SocketClient
Definition
SocketClient.h:48
core::socket::stream::tls
Definition
SocketReader.cpp:35
core
socket
stream
tls
SocketReader.cpp
Generated on Mon Feb 10 2025 20:20:50 for SNode.C by
1.11.0