Skip to content

Commit c225906

Browse files
authored
Merge pull request #597 from mtconnect/594_re-resolve_address_when_disconnect
594 re resolve address when disconnect
2 parents 82db1d3 + f84cccb commit c225906

File tree

9 files changed

+62
-20
lines changed

9 files changed

+62
-20
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
set(AGENT_VERSION_MAJOR 2)
33
set(AGENT_VERSION_MINOR 7)
44
set(AGENT_VERSION_PATCH 0)
5-
set(AGENT_VERSION_BUILD 4)
5+
set(AGENT_VERSION_BUILD 5)
66
set(AGENT_VERSION_RC "")
77

88
# This minimum version is to support Visual Studio 2019 and C++ feature checking and FetchContent

demo/compose/adapter/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ COPY --chown=adapter:adapter "./demo/agent/${LOG_FILE}" machine.log
2727

2828
EXPOSE 7878
2929

30-
CMD ["ruby", "run_scenario.rb", "-l", "-m", "30", "machine.log"]
30+
CMD ["ruby", "run_scenario.rb", "-l", "-m", "1", "machine.log"]
3131

3232

3333

docker/ubuntu/Dockerfile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
# base image - ubuntu has amd64, arm64 etc.
3030
# 22.04 is the current long term support release, maintained until 2025-04.
31-
FROM ubuntu:22.04 AS os
31+
FROM ubuntu:24.04 AS os
3232

3333
# tzinfo hangs without this
3434
ARG DEBIAN_FRONTEND='noninteractive'
@@ -62,7 +62,7 @@ RUN apt clean && apt update \
6262
rake \
6363
ruby \
6464
&& rm -rf /var/lib/apt/lists/* \
65-
&& pip install conan
65+
&& pip install --break-system-packages --root-user-action ignore conan
6666

6767
# make an agent directory and cd into it
6868
WORKDIR /root/agent
@@ -108,8 +108,8 @@ LABEL author='mtconnect' description='MTConnect C++ Agent'
108108
# change to a new non-root user for better security.
109109
# this also adds the user to a group with the same name.
110110
# --create-home creates a home folder, ie /home/<username>
111-
ARG UID=1000
112-
ARG GID=1000
111+
ARG UID=1001
112+
ARG GID=1001
113113

114114
RUN groupadd \
115115
--gid $GID \

src/mtconnect/configuration/async_context.hpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,19 +85,19 @@ namespace mtconnect::configuration {
8585
catch (FatalException &e)
8686
{
8787
LOG(fatal) << "Fatal exception occurred: " << e.what();
88-
stop();
88+
stop(false);
8989
m_exitCode = 1;
9090
}
9191
catch (std::exception &e)
9292
{
9393
LOG(fatal) << "Uncaught exception occurred: " << e.what();
94-
stop();
94+
stop(false);
9595
m_exitCode = 1;
9696
}
9797
catch (...)
9898
{
9999
LOG(fatal) << "Unknown fatal exception occurred";
100-
stop();
100+
stop(false);
101101
m_exitCode = 1;
102102
}
103103
}));
@@ -137,19 +137,19 @@ namespace mtconnect::configuration {
137137
catch (FatalException &e)
138138
{
139139
LOG(fatal) << "Fatal exception occurred: " << e.what();
140-
stop();
140+
stop(false);
141141
m_exitCode = 1;
142142
}
143143
catch (std::exception &e)
144144
{
145145
LOG(fatal) << "Uncaught exception occurred: " << e.what();
146-
stop();
146+
stop(false);
147147
m_exitCode = 1;
148148
}
149149
catch (...)
150150
{
151151
LOG(fatal) << "Unknown fatal exception occurred";
152-
stop();
152+
stop(false);
153153
m_exitCode = 1;
154154
}
155155

src/mtconnect/sink/rest_sink/session_impl.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ namespace mtconnect::sink::rest_sink {
197197
}
198198

199199
auto &msg = m_parser->get();
200-
const auto &remote = beast::get_lowest_layer(derived().stream()).socket().remote_endpoint();
200+
const auto &remote = m_remote;
201201

202202
// Check for put, post, or delete
203203
if (msg.method() != http::verb::get)
@@ -495,7 +495,13 @@ namespace mtconnect::sink::rest_sink {
495495
: SessionImpl<HttpsSession>(std::move(buffer), list, dispatch, error),
496496
m_stream(std::move(socket), context)
497497
{
498-
m_remote = beast::get_lowest_layer(m_stream).socket().remote_endpoint();
498+
NAMED_SCOPE("HttpsSession::HttpsSession");
499+
boost::system::error_code ec;
500+
m_remote = beast::get_lowest_layer(m_stream).socket().remote_endpoint(ec);
501+
if (ec)
502+
{
503+
LOG(error) << "Failed to get remote endpoint for https session: " << ec.message();
504+
}
499505
}
500506
/// @brief get a shared pointer to the https session
501507
/// @return shared pointer

src/mtconnect/sink/rest_sink/session_impl.hpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,13 @@ namespace mtconnect {
131131
: SessionImpl<HttpSession>(std::move(buffer), list, dispatch, error),
132132
m_stream(std::move(stream))
133133
{
134-
m_remote = m_stream.socket().remote_endpoint();
134+
NAMED_SCOPE("HttpSession::HttpSession");
135+
boost::system::error_code ec;
136+
m_remote = m_stream.socket().remote_endpoint(ec);
137+
if (ec)
138+
{
139+
LOG(error) << "Failed to get remote endpoint: " << ec.message();
140+
}
135141
}
136142
/// @brief Get a pointer cast as an HTTP Session
137143
/// @return shared pointer to an http session

src/mtconnect/source/adapter/agent_adapter/session_impl.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ namespace mtconnect::source::adapter::agent_adapter {
8484
LOG(error) << "Agent Adapter Target: " << m_request->getTarget(m_url);
8585
LOG(error) << "Agent Adapter " << what << ": " << ec.message() << "\n";
8686
m_request.reset();
87+
88+
// Clear cached DNS resolution so hostname is re-resolved on reconnect.
89+
// This handles DHCP environments where IP addresses may change.
90+
m_resolution.reset();
91+
8792
if (m_failed)
8893
m_failed(ec);
8994
}

src/mtconnect/source/adapter/shdr/connector.cpp

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ namespace mtconnect::source::adapter::shdr {
136136
return true;
137137
}
138138

139+
/// @brief Attempt to reconnect after a delay. If the server is a hostname, re-resolve it to get the current IP
140+
/// address in case it has changed. If the server is a static IP address, just reconnect.
139141
inline void Connector::asyncTryConnect()
140142
{
141143
NAMED_SCOPE("Connector::asyncTryConnect");
@@ -145,7 +147,21 @@ namespace mtconnect::source::adapter::shdr {
145147
if (ec != boost::asio::error::operation_aborted)
146148
{
147149
LOG(info) << "reconnect: retrying connection";
148-
asio::dispatch(m_strand, boost::bind(&Connector::connect, this));
150+
// Re-resolve hostname to handle DHCP/dynamic IP environments.
151+
// If the server is a hostname (not a static IP), re-resolve to get
152+
// the current IP address in case it has changed.
153+
boost::system::error_code addrEc;
154+
ip::make_address(m_server, addrEc);
155+
if (addrEc)
156+
{
157+
// m_server is a hostname, re-resolve it
158+
asio::dispatch(m_strand, boost::bind(&Connector::resolve, this));
159+
}
160+
else
161+
{
162+
// m_server is a static IP address, just reconnect
163+
asio::dispatch(m_strand, boost::bind(&Connector::connect, this));
164+
}
149165
}
150166
});
151167
}
@@ -183,7 +199,16 @@ namespace mtconnect::source::adapter::shdr {
183199
}
184200
else
185201
{
186-
LOG(info) << "Connected with: " << m_socket.remote_endpoint();
202+
boost::system::error_code rec;
203+
auto remote = m_socket.remote_endpoint(rec);
204+
if (rec)
205+
{
206+
LOG(error) << "Failed to get remote endpoint: " << rec.message();
207+
}
208+
else
209+
{
210+
LOG(info) << "Connected with: " << remote;
211+
}
187212
m_timer.cancel();
188213

189214
m_socket.set_option(asio::ip::tcp::no_delay(true));

src/mtconnect/utilities.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ namespace mtconnect {
198198
/// @brief Convert text to upper case
199199
/// @param[in,out] text text
200200
/// @return upper-case of text as string
201-
constexpr std::string &toUpperCase(std::string &text)
201+
inline std::string &toUpperCase(std::string &text)
202202
{
203203
std::transform(text.begin(), text.end(), text.begin(),
204204
[](unsigned char c) { return std::toupper(c); });
@@ -209,7 +209,7 @@ namespace mtconnect {
209209
/// @brief Simple check if a number as a string is negative
210210
/// @param s the numbeer
211211
/// @return `true` if positive
212-
constexpr bool isNonNegativeInteger(const std::string &s)
212+
inline bool isNonNegativeInteger(const std::string &s)
213213
{
214214
for (const char c : s)
215215
{
@@ -223,7 +223,7 @@ namespace mtconnect {
223223
/// @brief Checks if a string is a valid integer
224224
/// @param s the string
225225
/// @return `true` if is `[+-]\d+`
226-
constexpr bool isInteger(const std::string &s)
226+
inline bool isInteger(const std::string &s)
227227
{
228228
auto iter = s.cbegin();
229229
if (*iter == '-' || *iter == '+')

0 commit comments

Comments
 (0)