Add thread logic for callbacks (#32)
author강용구/Security&Privacy팀(SR)/삼성전자 <ygace.kang@samsung.com>
Fri, 5 Jan 2024 07:35:46 +0000 (16:35 +0900)
committerGitHub Enterprise <noreply-CODE@samsung.com>
Fri, 5 Jan 2024 07:35:46 +0000 (16:35 +0900)
* Add functions and Minor fix
* Add callbacks in creating thread at client-side
* Add callbacks in creating thread at server-side
* Remove service-thread
* Modify SocketManager for remove service-thread

srcs/client/client-request.h
srcs/client/client.cpp
srcs/server/service-thread.h [deleted file]
srcs/server/service.cpp
srcs/server/service.h
srcs/server/socket-manager.cpp
srcs/server/socket-manager.h

index 25829885a80219c7dd75b59baf56ea9a28e4f451..eee33872c012305f37d62a0976192b0bf5e2c3ce 100644 (file)
@@ -34,7 +34,7 @@
 
 namespace WA {
 
-class ClientRequest {    
+class ClientRequest {
 public:
     explicit ClientRequest(WebAuthnCall action)
     {
@@ -44,9 +44,11 @@ public:
         Serialization::Serialize(m_buffer, static_cast<int>(action));
         LogDebug("ClientRequest " << WebAuthnCallToString(action));
     }
+
     ~ClientRequest()
     {
-        delete m_conn;
+        if(!m_conn)
+            delete m_conn;
     }
 
     int getStatus() const
@@ -75,30 +77,44 @@ public:
     template <typename... T> ClientRequest &send(const T&... args)
     {
         Serialization::Serialize(m_buffer, args...);
-        return send();        
+        return send();
     }
 
-    template <typename... T> ClientRequest &recv(T&... args)
+    ClientRequest &recv()
     {
         if (!m_sent)
             throw std::logic_error(
                 "Call to ClientRequest::send() must happen before call to ClientRequest::recv()");
-
         if (failed())
             throw std::logic_error(
                 "ClientRequest::recv() not allowed if the request failed");
-
         m_status = m_conn->recv(m_buffer);
         if (failed())
+        {
             LogError("Error in recv. Error code: " << m_status);
-        else            
+            if (m_status < 0)
+                m_status = WAUTHN_ERROR_SOCKET;
+        }
+        else
             Deserialization::Deserialize(m_buffer, m_status);
+        return *this;
+    }
 
+    template <typename... T> ClientRequest &recv(T&... args)
+    {
+        recv();
         Deserialization::Deserialize(m_buffer, args...);
-
         return *this;
     }
 
+    template <typename... T> ClientRequest &sendRequest(const T&... args)
+    {
+        Serialization::Serialize(m_buffer, args...);
+        if (send().failed())
+            return *this;
+        return recv();
+    }
+
 private:
     bool m_sent = false;
     int m_status = WAUTHN_ERROR_NONE;
index cc9660044287a1ca21e12bdbf6e8661b888324be..46679c40bc46f5ef71933597c35fc64d62086f73 100644 (file)
 #include <webauthn-log.h>
 #include <client-request.h>
 #include <utils.h>
+#include <unistd.h>
+#include <thread>
+
+template <typename A, typename B>
+void cb_worker(std::shared_ptr<ClientRequest> request, A &callbacks, B &cred)
+{
+    LogDebug("IN");
+    if (callbacks == nullptr || callbacks->response_callback == nullptr){
+        LogError("Invalid parameter");
+        return;
+    }
+    if (callbacks->qrcode_callback == nullptr)
+        LogDebug("There is no qrcode_callback");
+    else{ //callbacks->qrcode_callback != nullptr
+        std::string qr_code;
+        LogDebug("----------------------------recv qr code");
+        if (request->recv(qr_code).failed())
+            LogError("Error on receive qrcode");
+        LogDebug("Receive : qr_code: " << qr_code);
+        callbacks->qrcode_callback(qr_code.c_str(), callbacks->user_data);
+    }
+
+    /* TODO: Receive wauthn_pubkey_credential_attestaion_s or wauthn_pubkey_credential_assertion_s */
+    //if(request->recv(cred).failed())
+    if(request->recv().failed())
+        LogError("Error on receive response");
+    callbacks->response_callback(cred, wauthn_error_e(request->getStatus()), callbacks->user_data);
+}
 
 int wauthn_make_credential( const wauthn_client_data_s *client_data,
                             const wauthn_pubkey_cred_creation_options_s *options,
                             wauthn_mc_callbacks_s *callbacks)
-{    
-    LogDebug("Entry");
-    /* Test Code Start */
-    return try_catch([&]() -> int {        
-        ClientRequest request(WebAuthnCall::MAKE_CREDENTIAL);
-        LogDebug("send");
-        if (request.send(std::string("Request(MAKE_CREDENTIAL) to server")).failed())
-            return request.getStatus();
+{
+    
+    if (client_data == nullptr || options == nullptr || callbacks == nullptr ||
+        callbacks->response_callback == nullptr)
+        return WAUTHN_ERROR_INVALID_PARAMETER;
 
-        unsigned long timeouts;
-        LogDebug("----------------------------recv result");
-        if (request.recv(timeouts).failed())
-            return request.getStatus();
-        LogDebug("Receive : timeouts: " << timeouts);
-        
-        std::string qr_code;
-        LogDebug("----------------------------recv qr code");
-        if (request.recv(qr_code).failed())
-            return request.getStatus();
-        LogDebug("Receive : qr_code: " << qr_code);
+    return try_catch([&]() -> int {
         
+        std::shared_ptr<ClientRequest> request 
+            = std::make_shared<ClientRequest>(WebAuthnCall::MAKE_CREDENTIAL);
+
+        LogDebug("sendRequest");
+        // TODO: send client_data, options 
+        //if (request->sendRequest(client_data, options)).failed())
+        if (request->sendRequest(std::string("sendRequest(MC) to server")).failed())
+            return request->getStatus();
+        LogDebug("RET: " << wauthn_error_to_string(request->getStatus()));
+
+        wauthn_pubkey_credential_attestaion_s *cred = NULL;
+        std::thread worker([request, callbacks, cred]{cb_worker(request, callbacks, cred);});
+        worker.detach();
+        LogDebug("Main thread OUT");
+
         return WAUTHN_ERROR_NONE;
     });
-    /* Test Code End */
-    if (client_data == nullptr || options == nullptr || callbacks == nullptr)
-        return WAUTHN_ERROR_INVALID_PARAMETER;
-
-    // TODO
-    LogDebug("Exit");
-    return WAUTHN_ERROR_NONE;
 }
 
 int wauthn_get_assertion( const wauthn_client_data_s *client_data,
                           const wauthn_pubkey_cred_request_options_s *options,
                           wauthn_ga_callbacks_s *callbacks)
 {
-    if (client_data == nullptr || options == nullptr || callbacks == nullptr)
+    
+    if (client_data == nullptr || options == nullptr || callbacks == nullptr ||
+        callbacks->response_callback == nullptr)
         return WAUTHN_ERROR_INVALID_PARAMETER;
 
-    // TODO
-    return WAUTHN_ERROR_NONE;
+    return try_catch([&]() -> int {
+        std::shared_ptr<ClientRequest> request 
+            = std::make_shared<ClientRequest>(WebAuthnCall::GET_ASSERTION);
+
+        LogDebug("getAssertion");
+        /* TODO: send client_data, options */
+        //if (request->sendRequest(client_data, options)).failed())
+        if (request->sendRequest(std::string("getAssertion(GA) to server")).failed())
+            return request->getStatus();
+        LogDebug("RET: " << wauthn_error_to_string(request->getStatus()));
+
+        wauthn_pubkey_credential_assertion_s *cred = NULL;
+        std::thread worker([request, callbacks, cred]{cb_worker(request, callbacks, cred);});
+        worker.detach();
+        
+        LogDebug("Main thread OUT");
+        return WAUTHN_ERROR_NONE;
+    });
 }
 
 int wauthn_cancel()
diff --git a/srcs/server/service-thread.h b/srcs/server/service-thread.h
deleted file mode 100644 (file)
index 55480bc..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- *  Copyright (c) 2023 Samsung Electronics Co., Ltd. All rights reserved
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License
- *
- * @file        service-thread.h
- * @version     1.0
- * @brief       Implementation of service threads
- */
-
-#pragma once
-
-#include <cassert>
-#include <condition_variable>
-#include <mutex>
-#include <queue>
-#include <thread>
-
-#include <exception.h>
-#include <protocols.h>
-#include <utils.h>
-
-namespace WA {
-
-template <class DerivedService, class Event>
-class ServiceThread {
-    std::mutex m_eventQueueMutex;
-    std::condition_variable m_waitCondition;
-    bool m_quit = false;
-    std::queue<Event *> m_eventQueues;
-    std::thread m_thread; // initialized last
-
-public:
-    ServiceThread() : m_thread(&ServiceThread::ThreadLoop, this) {}
-
-    ~ServiceThread() {
-        {
-            std::lock_guard<std::mutex> lock(m_eventQueueMutex);
-            m_quit = true;
-        }
-        m_waitCondition.notify_one();
-        if (m_thread.joinable()){
-            m_thread.join(); 
-        }
-        // clear the event queue
-        while (!m_eventQueues.empty()) {
-            delete m_eventQueues.front();
-            m_eventQueues.pop();
-        }
-    }
-
-    template <class...T>
-    void PutEvent(T&&...arg) {
-        const auto event = new Event{ std::forward<T>(arg)... };
-        {
-            std::lock_guard<std::mutex> lock(m_eventQueueMutex);
-            m_eventQueues.emplace(event);
-        }
-        m_waitCondition.notify_one();
-    }
-
-private:
-    void ThreadLoop() {
-        for (;;) {
-            Event *event;
-            {
-                std::unique_lock<std::mutex> ulock(m_eventQueueMutex);
-                for (;;) {
-                    if (m_quit)
-                        return;
-                    if (!m_eventQueues.empty()) {
-                        event = m_eventQueues.front();
-                        m_eventQueues.pop();
-                        goto handleOneEvent;
-                    }
-                    m_waitCondition.wait(ulock);
-                }
-            }
-
-        handleOneEvent:
-            UNHANDLED_EXCEPTION_HANDLER_BEGIN
-            {
-                const auto eventGuard = std::make_unique<Event*>(event);
-                static_cast<DerivedService*>(this)->processEvent(std::move(*event));
-            }
-            UNHANDLED_EXCEPTION_HANDLER_END
-        }
-    }
-};
-
-} // namespace WebAuthn
index 23da108ccc9346ecaff92e2633650f867c66a50b..5d04f667d4dda2cf40083178e03890fff2001516 100644 (file)
 #include <serialization.h>
 #include <protocols.h>
 #include <service.h>
+#include <unistd.h>
+#include <webauthn-hal.h>
+#include <webauthn-types.h>
+
+/* Test code start */
+void wah_make_credential(const wauthn_client_data_s *client_data,
+                         const wauthn_pubkey_cred_creation_options_s *options,
+                         wauthn_mc_callbacks_s *callbacks)
+{
+    if (client_data == NULL)
+        LogError("client_data is null");
+    if (options == NULL)
+        LogError("options is null");
+
+    sleep(3);
+    callbacks->qrcode_callback(std::string("FIDO:/..mc....").c_str(), callbacks->user_data);
+    sleep(3);
+    callbacks->response_callback(NULL, WAUTHN_ERROR_NONE, callbacks->user_data);
+}
+
+void wah_get_assertion(const wauthn_client_data_s *client_data,
+                       const wauthn_pubkey_cred_request_options_s *options,
+                       wauthn_ga_callbacks_s *callbacks)
+{
+    if (client_data == NULL)
+        LogError("client_data is null");
+    if (options == NULL)
+        LogError("options is null");
+
+    sleep(3);
+    callbacks->qrcode_callback(std::string("FIDO:/..ga....").c_str(), callbacks->user_data);
+    sleep(3);
+    callbacks->response_callback(NULL, WAUTHN_ERROR_NONE, callbacks->user_data);
+}
+/* Test code end */
 
 namespace WA {
+typedef struct __struct_user_data
+{
+    Service *service;
+    SocketManager::ConnectionID connectionID;
+}user_data_s;
 
 namespace {
 class ServiceException
@@ -36,8 +76,126 @@ public:
 };
 }  // namespace
 
+void cb_display_qrcode(const char *qr_contents, void *user_data)
+{
+    user_data_s *userData = static_cast<user_data_s *>(user_data);
+    LogDebug("QR Code: " << qr_contents);
+
+    int ret = WAUTHN_ERROR_NONE;
+    MessageBuffer buffer(userData->service->getSocketmanager()->newMessage());
+    Serialization::Serialize(buffer, ret);
+    Serialization::Serialize(buffer, std::string(qr_contents));
+    LogDebug("Writing qr_code with sock: " << userData->connectionID.sock);
+    userData->service->getSocketmanager()->Write(userData->connectionID, std::move(buffer));
+}
+
+void cb_mc_on_response(const wauthn_pubkey_credential_attestaion_s *pubkey_cred,
+                       wauthn_error_e result,
+                       void *user_data)
+{
+    LogDebug("result: " << wauthn_error_to_string(result));
+    if (user_data == NULL){
+        LogError("user_data is null");
+        return;
+    }
+    user_data_s *userData = static_cast<user_data_s *>(user_data);
+    MessageBuffer buffer(userData->service->getSocketmanager()->newMessage());
+    if (result == WAUTHN_ERROR_NONE)
+    {
+        if (pubkey_cred == NULL)
+        {
+            LogError("There is no error but pubkey_cred is null");
+            Serialization::Serialize(buffer, WAUTHN_ERROR_UNKNOWN);
+        }
+        else{
+            Serialization::Serialize(buffer, result);
+            //Serialization::Serialize(buffer, pubkey_cred);
+        }
+    }
+    
+    LogDebug("Writing response with sock: " << userData->connectionID.sock);
+    userData->service->getSocketmanager()->Write(userData->connectionID, std::move(buffer));
+}
+
+void cb_ga_on_response(const wauthn_pubkey_credential_assertion_s *pubkey_cred,
+                       wauthn_error_e result,
+                       void *user_data)
+{
+    LogDebug("result: " << wauthn_error_to_string(result));
+    if (user_data == NULL){
+        LogError("user_data is null");
+        return;
+    }
+    user_data_s *userData = static_cast<user_data_s *>(user_data);
+    MessageBuffer buffer(userData->service->getSocketmanager()->newMessage());
+    if (result == WAUTHN_ERROR_NONE)
+    {
+        if (pubkey_cred == NULL)
+        {
+            LogError("There is no error but pubkey_cred is null");
+            Serialization::Serialize(buffer, WAUTHN_ERROR_UNKNOWN);
+        }
+        else{
+            Serialization::Serialize(buffer, result);
+            //Serialization::Serialize(buffer, pubkey_cred);
+        }
+    }
+    
+    LogDebug("Writing response with sock: " << userData->connectionID.sock);
+    userData->service->getSocketmanager()->Write(userData->connectionID, std::move(buffer));
+}
+
 Service::Service(){}
 
+SocketManager *Service::getSocketmanager()
+{
+    return this->m_serviceManager;
+}
+
+void Service::mcWorker(SocketManager::ConnectionID connectionID)
+{
+    LogDebug("IN mcWorker thread, connectionID: " << connectionID.sock);
+
+    //sleep(3);
+    
+    wauthn_mc_callbacks_s *callbacks = NULL;
+    callbacks = (wauthn_mc_callbacks_s*) calloc(1, sizeof(wauthn_mc_callbacks_s));
+    callbacks->qrcode_callback = cb_display_qrcode;
+    callbacks->response_callback = cb_mc_on_response;
+
+    user_data_s *user_data = (user_data_s *) calloc(1, sizeof(user_data_s));
+    user_data->service = this;
+    user_data->connectionID = connectionID;
+    callbacks->user_data = user_data;
+
+    wah_make_credential(NULL, NULL, callbacks);
+
+    //sleep(3);
+    LogDebug("Worker thread OUT");
+}
+
+void Service::gaWorker(SocketManager::ConnectionID connectionID)
+{
+    LogDebug("IN gaWorker thread, connectionID: " << connectionID.sock);
+
+    //sleep(3);
+    
+    wauthn_ga_callbacks_s *callbacks = NULL;
+    callbacks = (wauthn_ga_callbacks_s*) calloc(1, sizeof(wauthn_ga_callbacks_s));
+    callbacks->qrcode_callback = cb_display_qrcode;
+    callbacks->response_callback = cb_ga_on_response;
+    
+    user_data_s *user_data = (user_data_s *) calloc(1, sizeof(user_data_s));
+    user_data->service = this;
+    user_data->connectionID = connectionID;
+    callbacks->user_data = user_data;
+
+    wah_get_assertion(NULL, NULL, callbacks);
+
+    //sleep(3);
+    LogDebug("Worker thread OUT");
+}
+
 void Service::processEvent(Event &&msg)
 {
     LogDebug("Processing message for socket " << msg.connectionID.sock <<
@@ -54,19 +212,21 @@ void Service::processEvent(Event &&msg)
                 break;
             case WebAuthnCall::GET_ASSERTION:
                 LogDebug("call_type: WebAuthnCall::GET_ASSERTION");
-                processGetAssertion(msg.buffer);
+                processGetAssertion(msg.connectionID, msg.buffer);
                 break;
             case WebAuthnCall::CANCEL:
                 LogDebug("call_type: WebAuthnCall::CANCEL");
-                processCancel(msg.buffer);
+                processCancel(msg.connectionID, msg.buffer);
                 break;
             default:
                 LogError("Invalid call: " << call_type_int);
                 Throw(ServiceException::InvalidAction);
         }
         // if we reach this point, the protocol is OK
-        LogDebug("Closing socket after the protocol is Done.");
-        return m_serviceManager->Close(msg.connectionID);
+        //LogDebug("Closing socket after the protocol is Done.");
+        //return m_serviceManager->Close(msg.connectionID);
+        LogDebug("Protocol is Done.");
+        return;
     } Catch(MessageBuffer::Exception::Base) {
         LogError("Broken protocol.");
     } Catch(ServiceException::Base) {
@@ -77,96 +237,73 @@ void Service::processEvent(Event &&msg)
         LogError("Unknown exception");
     }
 
-    LogError("Closing socket because of error");
-    m_serviceManager->Close(msg.connectionID);
+    //LogError("Closing socket because of error");
+    //m_serviceManager->Close(msg.connectionID);
 }
 
 void Service::processMakeCredential(
     SocketManager::ConnectionID connectionID, 
     MessageBuffer &buffer)
 {
-    /* TODO */
-    // * All of Read/Write call requested based on mutex
-    // Read Parameters
-    // Check busy state
-    //  - If busy, Write 0 with return error code(mayby WAUTHN_ERROR_NOT_ALLOWED)
-    // Set busy state
-    // Create Worker thread
-    // In Service thread, Write return code(WAUTHN_ERROR_NONE)
-    // In Worker thread,
-    //  - Call webauthn-ble API: wah_make_credential()
-    //    (optional: with wauthn_cb_display_qrcode callback)
-    //  - (optional) Write QR Code in the callback after called by webauthn-ble
-    //  - Write Response after returned by webauthn-ble
-    //  - Set not busy state
-    //  - Thread terminated
-    //  - The return codes in above write will be setted by webauthn-ble module's return
-    //      - WAUTHN_ERROR_NONE: The request is completed
-    //      - WAUTHN_ERROR_CANCELLED: Cancelled the request
-    
     /* Test Code Start */
+    pid_t pid = getpid();
+    
+    LogDebug("PID: " << pid);
+
+    ucred clientCred;
+    socklen_t length = sizeof(ucred);
+    if (0 > getsockopt(connectionID.sock, SOL_SOCKET, SO_PEERCRED, &clientCred, &length)) {
+        LogError("getsockopt failed");
+        //return -1;
+    }
+    LogDebug("Client PID: " << clientCred.pid);
+
+
+
     std::string recvStr;
     Deserialization::Deserialize(buffer, recvStr);
     LogDebug("Receive :" << recvStr);
 
     buffer.ModeStreaming();
     int ret = WAUTHN_ERROR_NONE;
-    unsigned long timeouts = 30;
     Serialization::Serialize(buffer, ret);
-    Serialization::Serialize(buffer, timeouts);
-    LogDebug("Writing timeouts");
-    m_serviceManager->Write(connectionID, std::move(buffer));
-
-    buffer = m_serviceManager->newMessage();
-    Serialization::Serialize(buffer, ret);
-    Serialization::Serialize(buffer, std::string("FIDO:/..........."));
-    LogDebug("Writing qr_code");
+    LogDebug("Writing ret");
     m_serviceManager->Write(connectionID, std::move(buffer));
+    
+    std::thread worker(&Service::mcWorker, this, connectionID);
+    worker.detach();
+    LogDebug("Main thread Done");
+    
     /* Test Code End */
 }
 
-void Service::processGetAssertion(MessageBuffer &buffer)
+void Service::processGetAssertion(SocketManager::ConnectionID connectionID, 
+    MessageBuffer &buffer)
 {
-    /* TODO */
-    // Read Parameters
-    // Check busy state
-    //  - If busy, Write 0 with return error code(mayby WAUTHN_ERROR_NOT_ALLOWED)
-    // Set busy state
-    // Create Worker thread
-    // In Service thread, Write return code(WAUTHN_ERROR_NONE)
-    // In Worker thread,
-    //  - Call webauthn-ble API: wah_get_assertion()
-    //    (optional: with wauthn_cb_display_qrcode callback)
-    //  - (optional) Write QR Code in the callback after called by webauthn-ble
-    //  - Write response after returned by webauthn-ble
-    //  - Set not busy state
-    //  - Thread terminated
-    //  - The return codes in above write will be setted by webauthn-ble module's return
-    //      - WAUTHN_ERROR_NONE: The request is completed
-    //      - WAUTHN_ERROR_CANCELLED: Cancelled the request
 
     /* Test Code Start */
+    std::string recvStr;
+    Deserialization::Deserialize(buffer, recvStr);
+    LogDebug("Receive :" << recvStr);
+
     buffer.ModeStreaming();
+    int ret = WAUTHN_ERROR_NONE;
+    Serialization::Serialize(buffer, ret);
+    LogDebug("Writing ret");
+    m_serviceManager->Write(connectionID, std::move(buffer));
+    
+    std::thread worker(&Service::gaWorker, this, connectionID);
+    worker.detach();
+    LogDebug("Main thread Done");
+    
     /* Test Code End */
 }
 
-void Service::processCancel(MessageBuffer &buffer)
+void Service::processCancel(SocketManager::ConnectionID connectionID, 
+    MessageBuffer &buffer)
 {
-    /* TODO */
-    // Read Parameter, None
-    // Check busy state
-    //  - If not busy, 
-    //      - return error code(maybe WAUTHN_ERROR_NOT_ALLOWED)
-    //  - If busy,
-    //      - If valid by check Credentials (maybe socket number)
-    //          - Call webauthn-ble API: wah_cancel()
-    //              - Write response after returned by webauthn-ble
-    //                  - WAUTHN_ERROR_NONE: Cancelled the request
-    //                  - WAUTHN_ERROR_NOT_ALLOWED: After a credential made and not returned
-    //      - If invalid by check Credentials
-    //          - Write response (maybe WAUTHN_ERROR_NOT_ALLOWED)
-
     /* Test Code Start */
+    LogDebug("socket: " << connectionID.sock);
     buffer.ModeStreaming();
     /* Test Code End */
 }
index b671df79d2bbd22fb81e543b50e6b2855d042df6..5c87ab6e3762098d036e157d6b9f53b965165fa5 100644 (file)
@@ -21,8 +21,8 @@
 #pragma once
 
 #include <message-buffer.h>
-#include <service-thread.h>
 #include <socket-manager.h>
+#include <protocols.h>
 
 namespace WA {
 
@@ -31,7 +31,7 @@ struct Event {
     MessageBuffer buffer;
 };
 
-class Service final : public ServiceThread<Service, Event>
+class Service final
 {
     SocketManager *m_serviceManager = nullptr;
 public:
@@ -51,6 +51,9 @@ public:
      * @param  msg  A message
      */
     void processEvent(Event &&msg);
+    SocketManager *getSocketmanager();
+    
+    //void Service::cbQRCode(const char *qr_contents, void *user_data);
 
 private:
     /**
@@ -65,13 +68,20 @@ private:
      * Process getting assertion
      * @param buffer Input/output message buffer
      */
-    void processGetAssertion(MessageBuffer &buffer);
+    void processGetAssertion(
+        SocketManager::ConnectionID connectionID,
+        MessageBuffer &buffer);
 
     /**
      * Process cancelling current event
      * @param buffer Input/output message buffer
      */
-    void processCancel(MessageBuffer &buffer);
+    void processCancel(
+        SocketManager::ConnectionID connectionID,
+        MessageBuffer &buffer);
+
+    void mcWorker(SocketManager::ConnectionID connectionID);
+    void gaWorker(SocketManager::ConnectionID connectionID);
 };
 
 } // namespace WebAuthn
index b3e036b1fea6347998bc78ac79fcd4f6ac99ec80..c87ee04a5312ab1a681d9352de75452d1bf26d1c 100644 (file)
@@ -173,8 +173,9 @@ void SocketManager::ReadyForRead(int sock) {
             case MessageBuffer::InputResult::Done:
                 buffer.ModeStreaming();
                 FD_CLR(sock, &m_readSet); // the one and only call on this socket is complete
-                m_service->PutEvent(ConnectionID{sock, desc.counter},
-                        std::move(buffer));
+                const auto event = new Event{ ConnectionID{sock, desc.counter}, std::move(buffer) };
+                //m_service->PutEvent(ConnectionID{sock, desc.counter}, std::move(buffer));
+                m_service->processEvent(std::move(*event));
                 break;
         }
     }
@@ -185,9 +186,11 @@ close:
 }
 
 void SocketManager::ReadyForWrite(int sock) {
+    LogDebug("IN");
     auto &desc = m_socketDescriptionVector[sock];
     desc.isActiveThisGeneration = true;
     auto &buffer = desc.buffer;
+
     ssize_t result = write(sock, buffer.Ptr(), buffer.OutputSize());
     if (result == -1) {
         int err = errno;
@@ -252,8 +255,8 @@ void SocketManager::MainLoop() {
             }
         }
 
-        ProcessQueue();
-        ProcessTimeout();
+        //ProcessQueue();
+        //ProcessTimeout();
     }
 }
 
@@ -324,21 +327,46 @@ void SocketManager::RegisterSocketService(std::unique_ptr<Service> service) {
 }
 
 void SocketManager::Close(ConnectionID connectionID) {
+    std::lock_guard<std::mutex> ulock(m_serverProcessMutex);
+    if (connectionID.counter == m_socketDescriptionVector[connectionID.sock].counter)
+        CloseSocket(connectionID.sock);
+    /*
     m_serverProcessMutex.lock();
     {
         std::lock_guard<std::mutex> ulock(m_eventQueueMutex);
         m_closeQueue.push(connectionID);
     }
     NotifyMe();
+    */
 }
 
 void SocketManager::Write(ConnectionID connectionID, MessageBuffer &&buffer) {
+    std::lock_guard<std::mutex> ulock(m_serverProcessMutex);
+    auto &desc = m_socketDescriptionVector[connectionID.sock];
+    if (desc.counter != connectionID.counter)
+    {
+        LogDebug("Received packet for write but connection is closed. Packet ignored! Socket: "
+                    << connectionID.sock);
+        return;
+    }
+
+    desc.isActiveThisGeneration = true;
+    desc.buffer = std::move(buffer);
+    desc.buffer.ModeOutput();
+    
+    LogDebug("Calling ReadyforWrite");
+    ReadyForWrite(connectionID.sock);
+
+    //FD_SET(connectionID.sock, &m_writeSet);
+    //LogDebug("Ready for Write");
+    /*
     m_serverProcessMutex.lock();
     {
         std::lock_guard<std::mutex> ulock(m_eventQueueMutex);
         m_writeBufferQueue.push(WriteBuffer { connectionID, std::move(buffer) });
     }
     NotifyMe();
+    */
 }
 
 void SocketManager::NotifyMe() {
@@ -384,21 +412,6 @@ void SocketManager::ProcessQueue() {
     }
 }
 
-void SocketManager::ProcessTimeout() {
-    if (const auto now = monotonicCoarseNow(); now > m_nextGenerationStart) {
-        m_nextGenerationStart = now + SOCKET_TIMEOUT;
-        for (int i = 0; i <= m_maxDesc; ++i) {
-            auto &desc = m_socketDescriptionVector[i];
-            if (desc.isOpen) {
-                if (!desc.isActiveThisGeneration)
-                    CloseSocket(i);
-                else
-                    desc.isActiveThisGeneration = false;
-            }
-        }
-    }
-}
-
 void SocketManager::CloseSocket(int sock) {
     auto &desc = m_socketDescriptionVector[sock];
 
index 31f5c47127cbd9524f1b3833f2adf568f0c3332f..45c6d13f8e5d696bdd64ec6ebc430f49a07671b0 100644 (file)
@@ -67,7 +67,6 @@ private:
     void ReadyForAccept();
     bool GotSigTerm() const;
     void ProcessQueue(void);
-    void ProcessTimeout();
     void NotifyMe(void);
     void CloseSocket(int sock);