• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

libbitcoin / libbitcoin-network / 42707057166

09 Nov 2026 09:55PM UTC coverage: 93.577% (-0.2%) from 93.746%
42707057166

push

github

web-flow
Merge pull request #1016 from evoskuil/master

Add testnet5 network settings.

8 of 8 new or added lines in 2 files covered. (100.0%)

35 existing lines in 5 files now uncovered.

14642 of 15647 relevant lines covered (93.58%)

2258.96 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.95
/src/net/socket_stop.cpp
1
/**
2
 * Copyright (c) 2011-2026 libbitcoin developers
3
 *
4
 * This file is part of libbitcoin.
5
 *
6
 * This program is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU Affero General Public License as published by
8
 * 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 Affero General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU Affero General Public License
17
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
#include <bitcoin/network/net/socket.hpp>
20

21
#include <bitcoin/network/config/config.hpp>
22
#include <bitcoin/network/define.hpp>
23

24
namespace libbitcoin {
25
namespace network {
26

27
BC_PUSH_WARNING(NO_THROW_IN_NOEXCEPT)
28

29
using namespace system;
30
using namespace std::placeholders;
31

32
constexpr size_t drain_size = 1024;
33

34
// The socket does not (must not) stop itself.
35

36
// Stop (async).
37
// ----------------------------------------------------------------------------
38
// Hard stop (no graceful websocket/tls closure).
39

40
void socket::stop() NOEXCEPT
656 ✔
41
{
42
    // Stop flag accelerates work stoppage, as it does not wait on strand.
43
    if (stopped_.exchange(true) && !lazy_.exchange(false))
656 ✔
44
        return;
45

46
    // Stop is posted to strand to protect the socket.
47
    io::post(strand_,
474 ✔
48
        std::bind(&socket::do_stop, shared_from_this()));
948 ✔
49
}
50

51
// private
52
void socket::do_stop() NOEXCEPT
519 ✔
53
{
54
    BC_ASSERT(stranded());
519 ✔
55

56
    watch_->stop();
519 ✔
57
    timer_->stop();
519 ✔
58

59
    code ignore{};
519 ✔
60
    auto& layer = get_base();
519 ✔
61
    layer.shutdown(io::socket::shutdown_type::both, ignore);
519 ✔
62
    layer.close(ignore);
519 ✔
63
}
519 ✔
64

65
// Stop (lazy).
66
// ----------------------------------------------------------------------------
67
// Lazy stop (graceful websocket/tls closure).
68

69
void socket::lazy_stop() NOEXCEPT
46 ✔
70
{
71
    // Stop flag accelerates work stoppage, as it does not wait on strand.
72
    if (stopped_.exchange(true))
46 ✔
73
        return;
74

75
    lazy_.store(true);
45 ✔
76

77
    // Async stop is dispatched to strand to protect the socket.
78
    io::dispatch(strand_,
45 ✔
79
        std::bind(&socket::do_lazy_stop, shared_from_this()));
90 ✔
80
}
81

82
// private
83
void socket::do_lazy_stop() NOEXCEPT
45 ✔
84
{
85
    BC_ASSERT(stranded());
45 ✔
86

87
    // The peer is not required to answer a close, so the wait is bounded.
88
    if (is_zero(timer_->timeout().count()))
45 ✔
89
    {
90
        do_stop();
42 ✔
91
        return;
42 ✔
92
    }
93

94
    timer_->start(std::bind(&socket::handle_lazy_timer,
3 ✔
95
        shared_from_this(), _1));
6 ✔
96

97
    do_ws_stop();
3 ✔
98
}
99

100
// private
101
// Socket stop cancels the pending close, which completes its handler.
102
void socket::handle_lazy_timer(const code& ec) NOEXCEPT
3 ✔
103
{
104
    if (!ec)
3 ✔
UNCOV
105
        stop();
×
106
}
3 ✔
107

108
// private
109
void socket::do_ws_stop() NOEXCEPT
3 ✔
110
{
111
    BC_ASSERT(stranded());
3 ✔
112
    if (!websocket())
3 ✔
113
    {
114
        do_tls_stop();
1 ✔
115
        return;
1 ✔
116
    }
117

118
    // A close already sent (answering the peer) is not repeated.
119
    if (ws_closing_)
2 ✔
120
    {
121
        do_tls_stop();
×
122
        return;
×
123
    }
124

125
    ws_closing_ = true;
2 ✔
126
    ws_send(ws::opcode::close, ws::close_payload(ws::close_code::normal),
2 ✔
127
        std::bind(&socket::handle_ws_close, shared_from_this(), _1));
4 ✔
128
}
129

130
// private
131
void socket::handle_ws_close(const code& ec) NOEXCEPT
2 ✔
132
{
133
    BC_ASSERT(stranded());
2 ✔
134
    if (ec && ec != error::peer_disconnect && ec != error::channel_stopped)
2 ✔
135
    {
136
        LOGX("WS close [" << endpoint() << "] " << ec.message());
×
137
    }
138

139
    do_tls_stop();
2 ✔
140
}
2 ✔
141

142
// private
143
void socket::do_tls_stop() NOEXCEPT
3 ✔
144
{
145
    BC_ASSERT(stranded());
3 ✔
146
    if (!secure())
3 ✔
147
    {
148
        do_linger();
3 ✔
149
        return;
3 ✔
150
    }
151

UNCOV
152
    get_tls().async_shutdown(
×
UNCOV
153
        std::bind(&socket::handle_tls_close,
×
UNCOV
154
            shared_from_this(), _1));
×
155
}
156

157
// private
UNCOV
158
void socket::handle_tls_close(const code& ec) NOEXCEPT
×
159
{
UNCOV
160
    BC_ASSERT(stranded());
×
UNCOV
161
    if (ec && ec != error::peer_disconnect && ec != error::operation_canceled)
×
162
        logx("tls_stop", ec);
×
163

UNCOV
164
    do_linger();
×
UNCOV
165
}
×
166

167
// private
168
// Lingering close (rfc9112 9.6): send is closed and receive is drained to the
169
// peer's close, so unread bytes do not reset the connection under a response.
170
void socket::do_linger() NOEXCEPT
3 ✔
171
{
172
    BC_ASSERT(stranded());
3 ✔
173

174
    code ignore{};
3 ✔
175
    auto& layer = get_base();
3 ✔
176
    layer.cancel(ignore);
3 ✔
177
    layer.shutdown(io::socket::shutdown_type::send, ignore);
3 ✔
178
    do_drain(emplace_shared<data_chunk>(drain_size));
3 ✔
179
}
3 ✔
180

181
// private
182
void socket::do_drain(const chunk_ptr& sink) NOEXCEPT
5 ✔
183
{
184
    BC_ASSERT(stranded());
5 ✔
185

186
    get_base().async_read_some(io::buffer(*sink),
10 ✔
187
        std::bind(&socket::handle_drain,
10 ✔
188
            shared_from_this(), _1, sink));
10 ✔
189
}
5 ✔
190

191
// private
192
void socket::handle_drain(const code& ec,
5 ✔
193
    const chunk_ptr& sink) NOEXCEPT
194
{
195
    BC_ASSERT(stranded());
5 ✔
196

197
    if (ec)
5 ✔
198
    {
199
        do_stop();
3 ✔
200
        return;
3 ✔
201
    }
202

203
    do_drain(sink);
2 ✔
204
}
205

206
BC_POP_WARNING()
207

208
} // namespace network
209
} // namespace libbitcoin
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc