LCOV - code coverage report
Current view: top level - wirestead/config - uds_config.hpp (source / functions) Coverage Total Hit
Test: Wirestead Coverage Report Lines: 95.3 % 64 61
Test Date: 2026-08-30 10:35:09 Functions: 100.0 % 5 5
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 91.5 % 94 86

             Branch data     Line data    Source code
       1                 :             : /*
       2                 :             :  * Copyright 2025 Jinwoo Sung
       3                 :             :  *
       4                 :             :  * Licensed under the Apache License, Version 2.0 (the "License");
       5                 :             :  * you may not use this file except in compliance with the License.
       6                 :             :  * You may obtain a copy of the License at
       7                 :             :  *
       8                 :             :  *     http://www.apache.org/licenses/LICENSE-2.0
       9                 :             :  *
      10                 :             :  * Unless required by applicable law or agreed to in writing, software
      11                 :             :  * distributed under the License is distributed on an "AS IS" BASIS,
      12                 :             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      13                 :             :  * See the License for the specific language governing permissions and
      14                 :             :  * limitations under the License.
      15                 :             :  */
      16                 :             : 
      17                 :             : #pragma once
      18                 :             : 
      19                 :             : #include <cstdint>
      20                 :             : #include <string>
      21                 :             : 
      22                 :             : #include "wirestead/base/constants.hpp"
      23                 :             : #include "wirestead/util/input_validator.hpp"
      24                 :             : 
      25                 :             : namespace wirestead {
      26                 :             : namespace config {
      27                 :             : 
      28                 :             : /**
      29                 :             :  * @brief Configuration for UDS Client
      30                 :             :  */
      31                 :             : struct UdsClientConfig {
      32                 :             :   std::string socket_path = "/tmp/wirestead.sock";
      33                 :             :   unsigned retry_interval_ms = base::constants::DEFAULT_RETRY_INTERVAL_MS;
      34                 :             :   unsigned connection_timeout_ms = base::constants::DEFAULT_CONNECTION_TIMEOUT_MS;
      35                 :             :   int max_retries = base::constants::DEFAULT_MAX_RETRIES;
      36                 :             :   size_t backpressure_threshold = base::constants::DEFAULT_BACKPRESSURE_THRESHOLD;
      37                 :             :   base::constants::BackpressureStrategy backpressure_strategy = base::constants::BackpressureStrategy::Reliable;
      38                 :             :   bool enable_memory_pool = true;
      39                 :             :   // Size of the per-connection userspace read buffer that each
      40                 :             :   // async_read_some() fills. Raising this reduces read completions and
      41                 :             :   // callback dispatches on bulk transfers, at the cost of that much memory
      42                 :             :   // per connection.
      43                 :             :   size_t read_buffer_size = base::constants::DEFAULT_READ_BUFFER_SIZE;
      44                 :             : 
      45                 :         147 :   UdsClientConfig() = default;
      46                 :             : 
      47                 :          48 :   bool is_valid() const {
      48                 :          95 :     return read_buffer_size >= base::constants::MIN_READ_BUFFER_SIZE &&
      49         [ +  + ]:          47 :            read_buffer_size <= base::constants::MAX_READ_BUFFER_SIZE &&
      50         [ +  + ]:          46 :            util::InputValidator::is_valid_uds_path(socket_path) &&
      51         [ +  + ]:          44 :            retry_interval_ms >= base::constants::MIN_RETRY_INTERVAL_MS &&
      52         [ +  + ]:          43 :            retry_interval_ms <= base::constants::MAX_RETRY_INTERVAL_MS &&
      53         [ +  + ]:          42 :            connection_timeout_ms >= base::constants::MIN_CONNECTION_TIMEOUT_MS &&
      54         [ +  - ]:          41 :            connection_timeout_ms <= base::constants::MAX_CONNECTION_TIMEOUT_MS &&
      55         [ +  + ]:          41 :            backpressure_threshold >= base::constants::MIN_BACKPRESSURE_THRESHOLD &&
      56   [ +  +  +  + ]:         134 :            backpressure_threshold <= base::constants::MAX_BACKPRESSURE_THRESHOLD &&
      57   [ +  +  +  +  :          87 :            (max_retries == -1 || (max_retries >= 0 && max_retries <= base::constants::MAX_RETRIES_LIMIT));
                   +  - ]
      58                 :             :   }
      59                 :             : 
      60                 :          45 :   void validate_and_clamp() {
      61         [ +  + ]:          45 :     if (read_buffer_size < base::constants::MIN_READ_BUFFER_SIZE) {
      62                 :           1 :       read_buffer_size = base::constants::MIN_READ_BUFFER_SIZE;
      63         [ +  + ]:          44 :     } else if (read_buffer_size > base::constants::MAX_READ_BUFFER_SIZE) {
      64                 :           1 :       read_buffer_size = base::constants::MAX_READ_BUFFER_SIZE;
      65                 :             :     }
      66         [ +  + ]:          45 :     if (retry_interval_ms < base::constants::MIN_RETRY_INTERVAL_MS) {
      67                 :           2 :       retry_interval_ms = base::constants::MIN_RETRY_INTERVAL_MS;
      68         [ +  + ]:          43 :     } else if (retry_interval_ms > base::constants::MAX_RETRY_INTERVAL_MS) {
      69                 :           1 :       retry_interval_ms = base::constants::MAX_RETRY_INTERVAL_MS;
      70                 :             :     }
      71                 :             : 
      72         [ +  + ]:          45 :     if (connection_timeout_ms < base::constants::MIN_CONNECTION_TIMEOUT_MS) {
      73                 :           1 :       connection_timeout_ms = base::constants::MIN_CONNECTION_TIMEOUT_MS;
      74         [ -  + ]:          44 :     } else if (connection_timeout_ms > base::constants::MAX_CONNECTION_TIMEOUT_MS) {
      75                 :           0 :       connection_timeout_ms = base::constants::MAX_CONNECTION_TIMEOUT_MS;
      76                 :             :     }
      77                 :             : 
      78         [ +  + ]:          45 :     if (backpressure_threshold < base::constants::MIN_BACKPRESSURE_THRESHOLD) {
      79                 :           1 :       backpressure_threshold = base::constants::MIN_BACKPRESSURE_THRESHOLD;
      80         [ +  + ]:          44 :     } else if (backpressure_threshold > base::constants::MAX_BACKPRESSURE_THRESHOLD) {
      81                 :           1 :       backpressure_threshold = base::constants::MAX_BACKPRESSURE_THRESHOLD;
      82                 :             :     }
      83                 :             : 
      84   [ +  +  +  + ]:          45 :     if (max_retries != -1 && max_retries > base::constants::MAX_RETRIES_LIMIT) {
      85                 :           1 :       max_retries = base::constants::MAX_RETRIES_LIMIT;
      86                 :             :     }
      87                 :          45 :   }
      88                 :             : };
      89                 :             : 
      90                 :             : /**
      91                 :             :  * @brief Configuration for UDS Server
      92                 :             :  */
      93                 :             : struct UdsServerConfig {
      94                 :             :   std::string socket_path = "/tmp/wirestead.sock";
      95                 :             :   size_t backpressure_threshold = base::constants::DEFAULT_BACKPRESSURE_THRESHOLD;
      96                 :             :   base::constants::BackpressureStrategy backpressure_strategy = base::constants::BackpressureStrategy::Reliable;
      97                 :             :   bool enable_memory_pool = true;
      98                 :             :   // Size of the per-connection userspace read buffer that each
      99                 :             :   // async_read_some() fills. Raising this reduces read completions and
     100                 :             :   // callback dispatches on bulk transfers, at the cost of that much memory
     101                 :             :   // per connection.
     102                 :             :   size_t read_buffer_size = base::constants::DEFAULT_READ_BUFFER_SIZE;
     103                 :             :   // #437: 0 (unlimited) used to be the default, risking unbounded memory
     104                 :             :   // growth from a large number of slow/malicious clients. 0 still means
     105                 :             :   // unlimited for callers who explicitly opt into it.
     106                 :             :   int max_connections = static_cast<int>(base::constants::DEFAULT_MAX_CONNECTIONS);
     107                 :             :   int idle_timeout_ms = static_cast<int>(base::constants::DEFAULT_IDLE_TIMEOUT_MS);  // 0 = disabled
     108                 :             :   // #438: POSIX file permission bits (e.g. 0660) applied to the socket file
     109                 :             :   // after bind, restricting which local users/groups can connect. -1 (the
     110                 :             :   // default) leaves the socket at whatever the process umask produces,
     111                 :             :   // matching prior behavior. Ignored on Windows.
     112                 :             :   int socket_permissions = -1;
     113                 :             : 
     114                 :          44 :   bool is_valid() const {
     115                 :          87 :     return read_buffer_size >= base::constants::MIN_READ_BUFFER_SIZE &&
     116         [ +  + ]:          43 :            read_buffer_size <= base::constants::MAX_READ_BUFFER_SIZE &&
     117         [ +  + ]:          42 :            util::InputValidator::is_valid_uds_path(socket_path) &&
     118         [ +  + ]:          40 :            backpressure_threshold >= base::constants::MIN_BACKPRESSURE_THRESHOLD &&
     119   [ +  +  +  + ]:          39 :            backpressure_threshold <= base::constants::MAX_BACKPRESSURE_THRESHOLD && max_connections >= 0 &&
     120   [ +  +  +  + ]:          37 :            (idle_timeout_ms == 0 || (idle_timeout_ms >= static_cast<int>(base::constants::MIN_IDLE_TIMEOUT_MS) &&
     121   [ +  +  +  + ]:          89 :                                      idle_timeout_ms <= static_cast<int>(base::constants::MAX_IDLE_TIMEOUT_MS))) &&
     122   [ +  +  +  -  :          79 :            (socket_permissions == -1 || (socket_permissions >= 0 && socket_permissions <= 0777));
                   +  - ]
     123                 :             :   }
     124                 :             : 
     125                 :          40 :   void validate_and_clamp() {
     126         [ +  + ]:          40 :     if (read_buffer_size < base::constants::MIN_READ_BUFFER_SIZE) {
     127                 :           1 :       read_buffer_size = base::constants::MIN_READ_BUFFER_SIZE;
     128         [ +  + ]:          39 :     } else if (read_buffer_size > base::constants::MAX_READ_BUFFER_SIZE) {
     129                 :           1 :       read_buffer_size = base::constants::MAX_READ_BUFFER_SIZE;
     130                 :             :     }
     131         [ +  + ]:          40 :     if (backpressure_threshold < base::constants::MIN_BACKPRESSURE_THRESHOLD) {
     132                 :           1 :       backpressure_threshold = base::constants::MIN_BACKPRESSURE_THRESHOLD;
     133         [ +  + ]:          39 :     } else if (backpressure_threshold > base::constants::MAX_BACKPRESSURE_THRESHOLD) {
     134                 :           1 :       backpressure_threshold = base::constants::MAX_BACKPRESSURE_THRESHOLD;
     135                 :             :     }
     136                 :             : 
     137         [ +  + ]:          40 :     if (max_connections < 0) {
     138                 :           1 :       max_connections = 0;
     139         [ +  + ]:          39 :     } else if (max_connections > static_cast<int>(base::constants::MAX_MAX_CONNECTIONS)) {
     140                 :           1 :       max_connections = static_cast<int>(base::constants::MAX_MAX_CONNECTIONS);
     141                 :             :     }
     142                 :             : 
     143         [ +  + ]:          40 :     if (idle_timeout_ms < 0) {
     144                 :           1 :       idle_timeout_ms = 0;
     145         [ +  + ]:          39 :     } else if (idle_timeout_ms != 0) {
     146         [ -  + ]:           3 :       if (idle_timeout_ms < static_cast<int>(base::constants::MIN_IDLE_TIMEOUT_MS)) {
     147                 :           0 :         idle_timeout_ms = static_cast<int>(base::constants::MIN_IDLE_TIMEOUT_MS);
     148         [ +  + ]:           3 :       } else if (idle_timeout_ms > static_cast<int>(base::constants::MAX_IDLE_TIMEOUT_MS)) {
     149                 :           1 :         idle_timeout_ms = static_cast<int>(base::constants::MAX_IDLE_TIMEOUT_MS);
     150                 :             :       }
     151                 :             :     }
     152                 :             : 
     153   [ +  +  +  -  :          40 :     if (socket_permissions != -1 && (socket_permissions < 0 || socket_permissions > 0777)) {
                   -  + ]
     154                 :           0 :       socket_permissions = -1;
     155                 :             :     }
     156                 :          40 :   }
     157                 :             : };
     158                 :             : 
     159                 :             : }  // namespace config
     160                 :             : }  // namespace wirestead
        

Generated by: LCOV version 2.0-1