Harden Tunnel against unexpected events 15/309515/5
authorKrzysztof Malysa <k.malysa@samsung.com>
Thu, 11 Apr 2024 16:59:27 +0000 (18:59 +0200)
committerKrzysztof Małysa <k.malysa@samsung.com>
Tue, 16 Apr 2024 09:20:37 +0000 (09:20 +0000)
There were cases where there were unexpected events indicating errors
and the connection did hang instead of failing immediately. This commit
fixes such cases.

Change-Id: I91a17a5208eda15d199cd9d1fc65795246ad6d44

srcs/tunnel.cpp

index 289ef07b5edc2bb66dbd81a08ff95350a4c97fc8..993d6936c70df20350453edfcbc96e9c736bc799 100644 (file)
@@ -101,7 +101,7 @@ Tunnel::~Tunnel()
         Disconnect();
         m_ws->SetListener(nullptr);
     } catch (...) {
-        TRY_LOG_ERROR("Unexpected exception catched");
+        TRY_LOG_ERROR("Unexpected exception caught");
     }
 }
 
@@ -190,6 +190,7 @@ void Tunnel::Disconnect()
 
 void Tunnel::Cancel()
 {
+    LogDebug("Cancelling");
     std::lock_guard<std::mutex> guard(m_mutex);
 
     if (m_cancelled)
@@ -210,6 +211,29 @@ bool Tunnel::HandleEvent(Lws *wsi, enum lws_callback_reasons reason, void *in, s
             LogDebug(it->second);
 
         switch (reason) {
+        case LWS_CALLBACK_PROTOCOL_INIT:
+        case LWS_CALLBACK_CLIENT_HTTP_BIND_PROTOCOL:
+        case LWS_CALLBACK_CONNECTING:
+        case LWS_CALLBACK_SERVER_NEW_CLIENT_INSTANTIATED:
+        case LWS_CALLBACK_WSI_CREATE:
+        case LWS_CALLBACK_OPENSSL_PERFORM_SERVER_CERT_VERIFICATION:
+        case LWS_CALLBACK_ESTABLISHED_CLIENT_HTTP:
+        case LWS_CALLBACK_CLIENT_FILTER_PRE_ESTABLISH:
+            if (m_state != State::DISCONNECTED) {
+                LogError("Unexpected event");
+                m_state = State::FAILED;
+                return true;
+            }
+            break;
+
+        case LWS_CALLBACK_VHOST_CERT_AGING:
+            if (m_state != State::CONNECTED && m_state != State::WRITING) {
+                LogError("Unexpected event");
+                m_state = State::FAILED;
+                return true;
+            }
+            break;
+
         case LWS_CALLBACK_WS_PEER_INITIATED_CLOSE: {
             std::string description = "Unknown";
             uint16_t code; // network order
@@ -285,13 +309,15 @@ bool Tunnel::HandleEvent(Lws *wsi, enum lws_callback_reasons reason, void *in, s
                                  << " last:" << last);
 
             if (m_state != State::CONNECTED && m_state != State::WRITING) {
-                LogDebug("Unexpected data");
-                break;
+                LogError("Unexpected data");
+                m_state = State::FAILED;
+                return true;
             }
 
             if (!binary) {
-                LogDebug("Not binary");
-                break;
+                LogError("Not binary");
+                m_state = State::FAILED;
+                return true;
             }
 
             if (first) {
@@ -304,7 +330,7 @@ bool Tunnel::HandleEvent(Lws *wsi, enum lws_callback_reasons reason, void *in, s
                 if (!data) {
                     LogError("Empty data");
                     m_state = State::FAILED;
-                    break;
+                    return true;
                 }
                 auto size = m_in.size();
                 m_in.resize(size + len);
@@ -364,16 +390,25 @@ bool Tunnel::HandleEvent(Lws *wsi, enum lws_callback_reasons reason, void *in, s
                 m_state = State::FAILED;
                 return true;
             }
+            // LWS_CALLBACK_EVENT_WAIT_CANCELLED may happen during successful connecting
+            if (m_state != State::DISCONNECTED) {
+                LogError("Unexpected event");
+                m_state = State::FAILED;
+                return true;
+            }
             break;
         }
 
-        default: break;
+        default:
+            LogError("Unexpected event");
+            m_state = State::FAILED;
+            return true;
         }
         return false;
     } catch (const std::exception &ex) {
-        TRY_LOG_ERROR("std::exception catched: " << ex.what());
+        TRY_LOG_ERROR("std::exception caught: " << ex.what());
     } catch (...) {
-        TRY_LOG_ERROR("Unknown exception catched");
+        TRY_LOG_ERROR("Unknown exception caught");
     }
     m_state = State::FAILED;
     return true;