@@ -767,16 +767,6 @@ void ApiListener::NewClientHandlerInternal(
767767 return ;
768768 }
769769
770- Defer shutdownSslConn ([&sslConn, &yc]() {
771- // Ignore the error, but do not throw an exception being swallowed at all cost.
772- // https://github.com/Icinga/icinga2/issues/7351
773- boost::system::error_code ec;
774-
775- // Using async_shutdown() instead of AsioTlsStream::GracefulDisconnect() as this whole function
776- // is already guarded by a timeout based on the connect timeout.
777- sslConn.async_shutdown (yc[ec]);
778- });
779-
780770 std::shared_ptr<X509 > cert (sslConn.GetPeerCertificate ());
781771 bool verify_ok = false ;
782772 String identity;
@@ -828,8 +818,46 @@ void ApiListener::NewClientHandlerInternal(
828818
829819 ClientType ctype;
830820
831- try {
832- if (role == RoleClient) {
821+ if (role == RoleClient) {
822+ JsonRpc::SendMessage (client, new Dictionary ({
823+ { " jsonrpc" , " 2.0" },
824+ { " method" , " icinga::Hello" },
825+ { " params" , new Dictionary ({
826+ { " version" , (double )l_AppVersionInt },
827+ { " capabilities" , (double )ApiCapabilities::MyCapabilities }
828+ }) }
829+ }), yc);
830+
831+ client->async_flush (yc);
832+
833+ ctype = ClientJsonRpc;
834+ } else {
835+ {
836+ boost::system::error_code ec;
837+
838+ if (client->async_fill (yc[ec]) == 0u ) {
839+ if (identity.IsEmpty ()) {
840+ Log (LogInformation, " ApiListener" )
841+ << " No data received on new API connection " << conninfo << " : " << ec.message ()
842+ << " . Ensure that the remote endpoints are properly configured in a cluster setup." ;
843+ } else {
844+ Log (LogWarning, " ApiListener" )
845+ << " No data received on new API connection " << conninfo << " for identity '" << identity << " ': " << ec.message ()
846+ << " . Ensure that the remote endpoints are properly configured in a cluster setup." ;
847+ }
848+
849+ return ;
850+ }
851+ }
852+
853+ char firstByte = 0 ;
854+
855+ {
856+ asio::mutable_buffer firstByteBuf (&firstByte, 1 );
857+ client->peek (firstByteBuf);
858+ }
859+
860+ if (firstByte >= ' 0' && firstByte <= ' 9' ) {
833861 JsonRpc::SendMessage (client, new Dictionary ({
834862 { " jsonrpc" , " 2.0" },
835863 { " method" , " icinga::Hello" },
@@ -843,58 +871,15 @@ void ApiListener::NewClientHandlerInternal(
843871
844872 ctype = ClientJsonRpc;
845873 } else {
846- {
847- boost::system::error_code ec;
848-
849- if (client->async_fill (yc[ec]) == 0u ) {
850- if (identity.IsEmpty ()) {
851- Log (LogInformation, " ApiListener" )
852- << " No data received on new API connection " << conninfo << " : " << ec.message ()
853- << " . Ensure that the remote endpoints are properly configured in a cluster setup." ;
854- } else {
855- Log (LogWarning, " ApiListener" )
856- << " No data received on new API connection " << conninfo << " for identity '" << identity << " ': " << ec.message ()
857- << " . Ensure that the remote endpoints are properly configured in a cluster setup." ;
858- }
859-
860- return ;
861- }
862- }
863-
864- char firstByte = 0 ;
865-
866- {
867- asio::mutable_buffer firstByteBuf (&firstByte, 1 );
868- client->peek (firstByteBuf);
869- }
870-
871- if (firstByte >= ' 0' && firstByte <= ' 9' ) {
872- JsonRpc::SendMessage (client, new Dictionary ({
873- { " jsonrpc" , " 2.0" },
874- { " method" , " icinga::Hello" },
875- { " params" , new Dictionary ({
876- { " version" , (double )l_AppVersionInt },
877- { " capabilities" , (double )ApiCapabilities::MyCapabilities }
878- }) }
879- }), yc);
880-
881- client->async_flush (yc);
882-
883- ctype = ClientJsonRpc;
884- } else {
885- ctype = ClientHttp;
886- }
887- }
888- } catch (const boost::system::system_error& systemError) {
889- if (systemError.code () == boost::asio::error::operation_aborted) {
890- shutdownSslConn.Cancel ();
874+ ctype = ClientHttp;
891875 }
892-
893- throw ;
894876 }
895877
896878 std::shared_lock wgLock (*m_ListenerWaitGroup, std::try_to_lock);
897879 if (!wgLock) {
880+ // Close the connection cleanly, signals to the other endpoint that it wasn't closed due to an error.
881+ client->GracefulDisconnect (*strand, yc);
882+
898883 return ;
899884 }
900885
@@ -929,20 +914,19 @@ void ApiListener::NewClientHandlerInternal(
929914 << " Ignoring anonymous JSON-RPC connection " << conninfo
930915 << " . Max connections (" << GetMaxAnonymousClients () << " ) exceeded." ;
931916
932- aclient = nullptr ;
933- }
917+ // Close the connection cleanly, signals to the other endpoint that it wasn't closed due to an error.
918+ client-> GracefulDisconnect (*strand, yc);
934919
935- if (aclient) {
936- aclient->Start ();
937- shutdownSslConn.Cancel ();
920+ return ;
938921 }
922+
923+ aclient->Start ();
939924 } else {
940925 Log (LogNotice, " ApiListener" , " New HTTP client" );
941926
942927 HttpServerConnection::Ptr aclient = new HttpServerConnection (m_WaitGroup, identity, verify_ok, client);
943928 AddHttpClient (aclient);
944929 aclient->Start ();
945- shutdownSslConn.Cancel ();
946930 }
947931}
948932
0 commit comments