@@ -41,6 +41,30 @@ using namespace sttp::transport::tssc;
4141constexpr float32_t MissingCacheWarningInterval = 20.0 ;
4242const DataSubscriberPtr DataSubscriber::NullPtr = nullptr ;
4343
44+ class ReverseConnection ;
45+ typedef SharedPtr<ReverseConnection> ReverseConnectionPtr;
46+
47+ class ReverseConnection : public boost ::enable_shared_from_this<ReverseConnection>
48+ {
49+ private:
50+ TcpSocket m_socket;
51+
52+ public:
53+ explicit ReverseConnection (IOContext& service) :
54+ m_socket(service)
55+ {
56+ }
57+
58+ TcpSocket& GetSocket ()
59+ {
60+ return m_socket;
61+ }
62+
63+ static ReverseConnectionPtr New (IOContext& service) {
64+ return NewSharedPtr<ReverseConnection, IOContext&>(service);
65+ }
66+ };
67+
4468DataSubscriber::DataSubscriber () :
4569 m_subscriberID(Empty::Guid),
4670 m_compressPayloadData(true ),
@@ -127,7 +151,8 @@ void DataSubscriber::RunCommandChannelResponseThread()
127151 ReadPayloadHeader (error, bytesTransferred);
128152 });
129153
130- m_commandChannelService.run ();
154+ if (!m_listening)
155+ m_commandChannelService.run ();
131156}
132157
133158// Callback for async read of the payload header.
@@ -1096,7 +1121,7 @@ void DataSubscriber::Connect(const string& hostname, const uint16_t port, const
10961121 EstablishConnection (hostEndpoint, false );
10971122}
10981123
1099- void DataSubscriber::Listen (const sttp::TcpEndPoint& endpoint )
1124+ void DataSubscriber::Listen (const sttp::TcpEndPoint& endPoint )
11001125{
11011126 // This function fails by exception, consumers should try/catch calls to Start
11021127 if (IsListening ())
@@ -1115,14 +1140,14 @@ void DataSubscriber::Listen(const sttp::TcpEndPoint& endpoint)
11151140#endif
11161141
11171142 // TODO: Add TLS implementation options
1118- m_clientAcceptor = TcpAcceptor (m_commandChannelService, endpoint , false ); // -V601
1143+ m_clientAcceptor = TcpAcceptor (m_commandChannelService, endPoint , false ); // -V601
11191144
11201145 // Run command channel accept thread
11211146 m_commandChannelAcceptThread = Thread ([this ]
1122- {
1123- StartAccept ();
1124- m_commandChannelService.run ();
1125- });
1147+ {
1148+ StartAccept ();
1149+ m_commandChannelService.run ();
1150+ });
11261151
11271152 m_listening = true ;
11281153}
@@ -1139,49 +1164,53 @@ void DataSubscriber::Listen(const std::string& networkInterfaceIP, const uint16_
11391164
11401165void DataSubscriber::StartAccept ()
11411166{
1142- TcpSocket commandChannelSocket (m_commandChannelService);
1167+ ReverseConnectionPtr reverseConnection = ReverseConnection::New (m_commandChannelService);
11431168
1144- m_clientAcceptor.async_accept (commandChannelSocket , [this , &commandChannelSocket ]<typename T0>(T0 && error)
1169+ m_clientAcceptor.async_accept (reverseConnection-> GetSocket () , [this , reverseConnection ]<typename T0>(T0 && error)
11451170 {
1146- AcceptConnection (commandChannelSocket , error);
1171+ AcceptConnection (&reverseConnection-> GetSocket () , error);
11471172 });
11481173}
11491174
1150- void DataSubscriber::AcceptConnection (TcpSocket& commandChannelSocket, const ErrorCode& error)
1175+ void DataSubscriber::AcceptConnection (TcpSocket* commandChannelSocket, const ErrorCode& error)
11511176{
11521177 if (!IsListening ())
11531178 return ;
11541179
1180+ // TODO: For secured connections, validate certificate and IP information here to assign subscriberID
1181+ const TcpEndPoint endPoint = commandChannelSocket->remote_endpoint ();
1182+ string address = " <unknown>" ;
1183+ string errorMessage = " closed." ;
1184+
1185+ auto closeSocket = [&]
1186+ {
1187+ try
1188+ {
1189+ address = ResolveDNSName (m_commandChannelService, endPoint);
1190+ commandChannelSocket->close ();
1191+ }
1192+ catch (SystemError& ex)
1193+ {
1194+ errorMessage = " close error: " + string (ex.what ());
1195+ }
1196+ catch (...)
1197+ {
1198+ errorMessage = " close error: " + boost::current_exception_diagnostic_information (true );
1199+ }
1200+ };
1201+
11551202 if (error)
11561203 {
1157- DispatchErrorMessage (" Error while attempting to accept DataPublisher connection for reverse connection: " + string (SystemError (error).what ()));
1204+ closeSocket ();
1205+ DispatchErrorMessage (" Error while attempting to accept DataPublisher connection for reverse connection: " + string (SystemError (error).what ()) + " - connection " + errorMessage);
11581206 }
11591207 else
11601208 {
1161- // TODO: For secured connections, validate certificate and IP information here to assign subscriberID
1162- const TcpEndPoint endPoint = commandChannelSocket.remote_endpoint ();
1163-
11641209 // Will only accept one active connection at a time, this may be indicative
11651210 // of a rouge connection attempt - consumer should log warning
11661211 if (IsConnected ())
11671212 {
1168- string address = " <unknown>" ;
1169- string errorMessage = " closed." ;
1170-
1171- try
1172- {
1173- address = ResolveDNSName (m_commandChannelService, endPoint);
1174- commandChannelSocket.close ();
1175- }
1176- catch (SystemError& ex)
1177- {
1178- errorMessage = " close error: " + string (ex.what ());
1179- }
1180- catch (...)
1181- {
1182- errorMessage = " close error: " + boost::current_exception_diagnostic_information (true );
1183- }
1184-
1213+ closeSocket ();
11851214 DispatchErrorMessage (" WARNING: Duplicate connection attempt detected from: \" " + address + " \" . Existing data publisher connection already established, data subscriber will only accept one connection at a time - connection " + errorMessage);
11861215 }
11871216 else
@@ -1194,7 +1223,7 @@ void DataSubscriber::AcceptConnection(TcpSocket& commandChannelSocket, const Err
11941223 SetupConnection ();
11951224
11961225 // Hold on to primary socket
1197- m_commandChannelSocket = std::move (commandChannelSocket);
1226+ m_commandChannelSocket = std::move (* commandChannelSocket);
11981227
11991228 // Create new command channel
12001229 EstablishConnection (endPoint, true );
0 commit comments