10000 start searching for the local port of a socket (#21833) · arangodb/arangodb@b14b418 · GitHub
[go: up one dir, main page]

Skip to content

Commit b14b418

Browse files
dothebartjbajic
andauthored
start searching for the local port of a socket (#21833)
* start searching for the local port of a socket * more fiddling * add conversion option * move to proper place * add local endpoint to the output for better tcpdump compareability * avoid nullptrs * fix capturing rendering of values * acquire connection string while the connection is still active * fix type * lint * add dummy implementations of new method * add dummy implementations of new method * lint * lint * convert from network byte order * Update 3rdParty/fuerte/src/AsioSockets.h Co-authored-by: Jure Bajic <jure.bajic94@gmail.com> --------- Co-authored-by: Jure Bajic <jure.bajic94@gmail.com>
1 parent 340d175 commit b14b418

File tree

12 files changed

+96
-34
lines changed

12 files changed

+96
-34
lines changed

3rdParty/fuerte/include/fuerte/asio_ns.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include <asio/steady_timer.hpp>
4848
#include <asio/streambuf.hpp>
4949
#include <asio/write.hpp>
50+
#include <asio/detail/socket_ops.hpp>
5051

5152
namespace asio_ns = asio;
5253

@@ -57,6 +58,7 @@ namespace asio_ns = asio;
5758
#include <boost/asio/ssl.hpp>
5859
#include <boost/asio/steady_timer.hpp>
5960
#include <boost/asio/streambuf.hpp>
61+
#include <boost/asio/detail/socket_ops.hpp>
6062

6163
namespace boost { namespace asio {
6264
using error_code = boost::system::error_code;

3rdParty/fuerte/include/fuerte/connection.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ class Connection : public std::enable_shared_from_this<Connection> {
9393
/// @brief endpoint we are connected to
9494
std::string endpoint() const;
9595

96+
/// @brief endpoint which we connect from
97+
virtual std::string localEndpoint() = 0;
98+
9699
protected:
97100
Connection(detail::ConnectionConfiguration const& conf) : _config(conf) {}
98101

3rdParty/fuerte/include/fuerte/types.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ struct ConnectionConfiguration {
210210
_maxConnectRetries(3),
211211
#ifdef ARANGODB_USE_GOOGLE_TESTS
212212
_failConnectAttempts(0),
213-
#endif
213+
#endif
214214
_useIdleTimeout(true),
215215
_authenticationType(AuthenticationType::None),
216216
_user(""),
@@ -232,7 +232,7 @@ struct ConnectionConfiguration {
232232
unsigned _maxConnectRetries;
233233
#ifdef ARANGODB_USE_GOOGLE_TESTS
234234
unsigned _failConnectAttempts;
235-
#endif
235+
#endif
236236
bool _useIdleTimeout;
237237

238238
AuthenticationType _authenticationType;

3rdParty/fuerte/src/AsioSockets.h

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ template <typename SocketT, typename F, typename IsAbortedCb>
3434
void resolveConnect(detail::ConnectionConfiguration const& config,
3535
asio_ns::ip::tcp::resolver& resolver, SocketT& socket,
3636
F&& done, IsAbortedCb&& isAborted) {
37-
auto cb = [&socket,
37+
auto cb = [&socket,
3838
#ifdef ARANGODB_USE_GOOGLE_TESTS
3939
fail = config._failConnectAttempts > 0,
40-
#endif
40+
#endif
4141
done = std::forward<F>(done),
4242
isAborted = std::forward<IsAbortedCb>(isAborted)](auto ec, auto it) mutable {
4343
#ifdef ARANGODB_USE_GOOGLE_TESTS
@@ -90,6 +90,17 @@ void resolveConnect(detail::ConnectionConfiguration const& config,
9090
resolver.async_resolve(config._host, config._port, std::move(cb));
9191
#endif
9292
}
93+
94+
template <typename SocketT>
95+
std::string getConnectionNameS(SocketT& socket) {
96+
boost::system::error_code ec;
97+
asio_ns::ip::tcp::endpoint local_endpoint = socket.lowest_layer().local_endpoint(ec);
98+
99+
if (ec) {
100+
return "Error getting local endpoint: " + ec.message();
101+
}
102+
return local_endpoint.address().to_string() + ":" + std::to_string(local_endpoint.port());
103+
}
93104
} // namespace
94105

95106
enum class ConnectTimerRole {
@@ -105,9 +116,9 @@ struct Socket<SocketType::Tcp> {
105116
Socket(EventLoopService&, asio_ns::io_context& ctx)
106117
: resolver(ctx), socket(ctx), timer(ctx) {}
107118

108-
~Socket() {
119+
~Socket() {
109120
try {
110-
this->cancel();
121+
this->cancel();
111122
} catch (std::exception const& ex) {
112123
FUERTE_LOG_ERROR << "caught exception during tcp socket shutdown: " << ex.what() << "\n";
113124
}
@@ -136,13 +147,17 @@ struct Socket<SocketType::Tcp> {
136147
});
137148
}
138149

150+
std::string getConnectionName() {
151+
return getConnectionNameS(socket);
152+
}
153+
139154
bool isOpen() const {
140155
return socket.is_open();
141156
}
142157

143158
void rearm() {
144159
canceled = false;
145-
}
160+
}
146161

147162
void cancel() {
148163
canceled = true;
@@ -173,7 +188,7 @@ struct Socket<SocketType::Tcp> {
173188
}
174189
} catch (std::exception const& ex) {
175190
// an exception is unlikely to occur here, as we are using the error-code
176-
// variants of cancel/shutdown/close above
191+
// variants of cancel/shutdown/close above
177192
FUERTE_LOG_ERROR << "caught exception during tcp socket shutdown: " << ex.what() << "\n";
178193
}
179194
std::forward<F>(cb)(ec);
@@ -192,9 +207,9 @@ struct Socket<fuerte::SocketType::Ssl> {
192207
: resolver(ctx), socket(ctx, loop.sslContext()), timer(ctx), ctx(ctx),
193208
sslContext(loop.sslContext()), cleanupDone(false) {}
194209

195-
~Socket() {
210+
~Socket() {
196211
try {
197-
this->cancel();
212+
this->cancel();
198213
} catch (std::exception const& ex) {
199214
FUERTE_LOG_ERROR << "caught exception during ssl socket shutdown: " << ex.what() << "\n";
200215
}
< 6377 button class="Button Button--iconOnly Button--invisible ExpandableHunkHeaderDiffLine-module__expand-button-line--iUeM1 ExpandableHunkHeaderDiffLine-module__expand-button-unified--zEXxI ExpandableHunkHeaderDiffLine-module__expand-up-and-down--_W5im" aria-label="Expand file down from line 215" data-direction="down" aria-hidden="true" tabindex="-1">
@@ -249,11 +264,15 @@ struct Socket<fuerte::SocketType::Ssl> {
249264
}
250265
socket.async_handshake(asio_ns::ssl::stream_base::client,
251266
std::move(done));
252-
}, [this]() {
253-
return canceled;
267+
}, [this]() {
268+
return canceled;
254269
});
255270
}
256-
271+
272+
std::string getConnectionName() {
273+
return getConnectionNameS(socket);
274+
}
275+
257276
bool isOpen() const {
258277
return socket.lowest_layer().is_open();
259278
}
@@ -263,7 +282,7 @@ struct Socket<fuerte::SocketType::Ssl> {
263282
socket = asio_ns::ssl::stream<asio_ns::ip::tcp::socket>(this->ctx, this->sslContext);
264283
canceled = false;
265284
}
266-
285+
267286
void cancel() {
268287
canceled = true;
269288
try {
@@ -287,18 +306,18 @@ struct Socket<fuerte::SocketType::Ssl> {
287306
// socket is a member. This means that the allocation of the connection and
288307
// this of the socket is kept until all asynchronous operations are completed
289308
// (or aborted).
290-
309+
291310
// ec is an out parameter here that is passed to the methods so they
292311
// can fill in whatever error happened. we ignore it here anyway. we
293312
// use the ec-variants of the methods here to prevent exceptions.
294-
asio_ns::error_code ec;
313+
asio_ns::error_code ec;
295314

296315
if (!socket.lowest_layer().is_open()) {
297316
timer.cancel(ec);
298317
std::forward<F>(cb)(ec);
299318
return;
300319
}
301-
320+
302321
socket.lowest_layer().cancel(ec);
303322
cleanupDone = false;
304323
// implicitly cancels any previous timers
@@ -340,10 +359,10 @@ struct Socket<fuerte::SocketType::Unix> {
340359
Socket(EventLoopService&, asio_ns::io_context& ctx)
341360
: socket(ctx), timer(ctx) {}
342361

343-
~Socket() {
362+
~Socket() {
344363
canceled = true;
345364
try {
346-
this->cancel();
365+
this->cancel();
347366
} catch (std::exception const& ex) {
348367
FUERTE_LOG_ERROR << "caught exception during unix socket shutdown: " << ex.what() << "\n";
349368
}
@@ -356,19 +375,23 @@ struct Socket<fuerte::SocketType::Unix> {
356375
done(asio_ns::error::operation_aborted);
357376
return;
358377
}
359-
378+
360379
asio_ns::local::stream_protocol::endpoint ep(config._host);
361380
socket.async_connect(ep, std::forward<F>(done));
362381
}
363-
382+
383+
std::string getConnectionName() {
384+
return "no local connection name";
385+
}
386+
364387
bool isOpen() const {
365388
return socket.is_open();
366389
}
367390

368391
void rearm() {
369392
canceled = false;
370393
}
371-
394+
372395
void cancel() {
373396
canceled = true;
374397
try {
@@ -387,7 +410,7 @@ struct Socket<fuerte::SocketType::Unix> {
387410
// ec is an out parameter here that is passed to the methods so they
388411
// can fill in whatever error happened. we ignore it here anyway. we
389412
// use the ec-variants of the methods here to prevent exceptions.
390-
asio_ns::error_code ec;
413+
asio_ns::error_code ec;
391414
try {
392415
timer.cancel(ec);
393416
if (socket.is_open()) {
@@ -397,7 +420,7 @@ struct Socket<fuerte::SocketType::Unix> {
397420
}
398421
} catch (std::exception const& ex) {
399422
// an exception is unlikely to occur here, as we are using the error-code
400-
// variants of cancel/shutdown/close above
423+
// variants of cancel/shutdown/close above
401424
FUERTE_LOG_ERROR << "caught exception during unix socket shutdown: " << ex.what() << "\n";
402425
}
403426
std::forward<F>(cb)(ec);

3rdParty/fuerte/src/GeneralConnection.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ class GeneralConnection : public fuerte::Connection {
103103
return _state.load(std::memory_order_acquire);
104104
}
105105

106+
virtual std::string localEndpoint() override final {
107+
return _proto.getConnectionName();
108+
}
109+
106110
/// The following public methods can be called from any thread:
107111

108112
// Start an asynchronous request.
@@ -349,7 +353,7 @@ class GeneralConnection : public fuerte::Connection {
349353
if (me._failConnectAttempts > 0) {
350354
--me._failConnectAttempts;
351355
}
352-
#endif
356+
#endif
353357

354358
FUERTE_LOG_DEBUG << "tryConnect (" << retries << "), connecting failed: " << ec.message() << "\n";
355359
if (retries > 1 && ec != asio_ns::error::operation_aborted) {
@@ -377,7 +381,7 @@ class GeneralConnection : public fuerte::Connection {
377381
me.shutdownConnection(Error::CouldNotConnect, msg);
378382
}
379383
});
380-
384+
381385
// only if we are still in the connect phase, we want to schedule a timer
382386
// for the connect timeout. if the connect already failed and scheduled a
383387
// timer for the reconnect timeout, we do not want to mess with the timer here.
@@ -394,7 +398,7 @@ class GeneralConnection : public fuerte::Connection {
394398
if (me._proto.connectTimerRole == ConnectTimerRole::kConnect) {
395399
FUERTE_LOG_DEBUG << "tryConnect, connect timeout this=" << self.get() << "\n";
396400
me._proto.cancel();
397-
}
401+
}
398402
}
399403
});
400404
}

3rdParty/fuerte/src/connection.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,5 @@ std::string Connection::endpoint() const {
8888
}
8989
return endpoint;
9090
}
91+
9192
}}} // namespace arangodb::fuerte::v1

client-tools/Shell/V8ClientConnection.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ std::shared_ptr<fu::Connection> V8ClientConnection::createConnection(
206206
setCustomError(500, "unable to create connection");
207207
LOG_TOPIC("9daaa", DEBUG, arangodb::Logger::HTTPCLIENT)
208208
<< "Connection attempt to endpoint '" << _client.endpoint()
209-
<< "' failed fatally";
209+
<< "' failed fatally from: " << newConnection->localEndpoint();
210210
return nullptr;
211211
}
212212

@@ -237,7 +237,8 @@ std::shared_ptr<fu::Connection> V8ClientConnection::createConnection(
237237
setCustomError(_lastHttpReturnCode, errorMessage);
238238
LOG_TOPIC("9daab", DEBUG, arangodb::Logger::HTTPCLIENT)
239239
<< "Connection attempt to endpoint '" << _client.endpoint()
240-
<< "' failed: " << errorMessage;
240+
<< "' failed: " << errorMessage
241+
<< " from: " << newConnection->localEndpoint();
241242
return nullptr;
242243
}
243244
}
@@ -250,7 +251,8 @@ std::shared_ptr<fu::Connection> V8ClientConnection::createConnection(
250251
setCustomError(503, msg);
251252
LOG_TOPIC("9daac", DEBUG, arangodb::Logger::HTTPCLIENT)
252253
<< "Connection attempt to endpoint '" << _client.endpoint()
253-
<< "' failed: " << msg;
254+
<< "' failed: " << msg
255+
<< " from: " << newConnection->localEndpoint();
254256
return nullptr;
255257
}
256258

@@ -303,7 +305,8 @@ std::shared_ptr<fu::Connection> V8ClientConnection::createConnection(
303305
_currentConnectionId.erase();
304306
LOG_TOPIC("9daad", DEBUG, arangodb::Logger::HTTPCLIENT)
305307
<< "Connection attempt to endpoint '" << _client.endpoint()
306-
<< "' failed: " << msg;
308+
<< "' failed: " << msg
309+
<< " from: " << newConnection->localEndpoint();
307310
return nullptr;
308311
} else {
309312
newConnection = _builder.connect(_loop);
@@ -1423,7 +1426,8 @@ static void ClientConnection_httpFuzzRequests(
14231426
// during testing.
14241427
LOG_TOPIC("39e50", WARN, arangodb::Logger::FIXME)
14251428
<< "fuzzer producing " << numReqs << " requests(s) with " << numIts
1426-
<< " iteration(s) each, using seed " << fuzzer.getSeed();
1429+
<< " iteration(s) each, using seed " << fuzzer.getSeed()
1430+
<< " from: " << v8connection->getLocalEndpoint();
14271431
}
14281432
std::unordered_map<uint32_t, uint32_t> fuzzReturnCodesCount;
14291433

@@ -2812,6 +2816,7 @@ uint32_t V8ClientConnection::sendFuzzRequest(fuzzer::RequestFuzzer& fuzzer) {
28122816
return kFuzzNotConnected;
28132817
}
28142818

2819+
auto localEndpoint = getLocalEndpoint();
28152820
auto req = fuzzer.createRequest();
28162821
auto req_copy = *req;
28172822

@@ -2823,12 +2828,14 @@ uint32_t V8ClientConnection::sendFuzzRequest(fuzzer::RequestFuzzer& fuzzer) {
28232828
rc = ec;
28242829
if (rc != fu::Error::NoError) {
28252830
LOG_TOPIC("39e53", WARN, arangodb::Logger::FIXME)
2826-
<< "rc: " << static_cast<uint32_t>(rc);
2831+
<< "rc: " << static_cast<uint32_t>(rc)
2832+
<< " from: " << getLocalEndpoint();
28272833
}
28282834
}
28292835
if (!connection || connection->state() == fu::Connection::State::Closed) {
28302836
LOG_TOPIC("39e51", WARN, arangodb::Logger::FIXME)
2831-
<< "connection closed after " << fuerte::v1::to_string(req_copy);
2837+
<< "connection closed after " << fuerte::v1::to_string(req_copy)
2838+
<< " from: " << localEndpoint;
28322839
if (response) {
28332840
LOG_TOPIC("39e52", WARN, arangodb::Logger::FIXME)
28342841
<< "Server responce: " << response;

client-tools/Shell/V8ClientConnection.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,13 @@ class V8ClientConnection {
9898
std::string const& role() const { return _role; }
9999
std::string endpointSpecification() const;
100100

101+
std::string getLocalEndpoint() {
102+
if (_connection) {
103+
return _connection->localEndpoint();
104+
} else {
105+
return "not connected";
106+
}
107+
}
101108
ArangoshServer& server();
102109

103110
v8::Handle<v8::Value> getData(

tests/AsyncAgencyComm/AsyncAgencyCommTest.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ struct AsyncAgencyCommPoolMock final : public network::ConnectionPool {
115115
_mock(mock),
116116
_endpoint(std::move(endpoint)) {}
117117

118+
virtual std::string localEndpoint() override final {
119+
return "not implemented";
120+
};
118121
std::size_t requestsLeft() const override { return 1; }
119122
State state() const override {
120123
return fuerte::Connection::State::Connected;

tests/IResearch/AgencyMock.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ struct AsyncAgencyStorePoolConnection final
5454
void sendRequest(std::unique_ptr<arangodb::fuerte::Request> req,
5555
arangodb::fuerte::RequestCallback cb) override;
5656

57+
virtual std::string localEndpoint() override final {
58+
return "not implemented";
59+
};
60+
5761
arangodb::AgencyCache& _cache;
5862
std::string _endpoint;
5963
};

0 commit comments

Comments
 (0)
0