LCOV - code coverage report
Current view: top level - wirestead/config - tcp_client_config.hpp (source / functions) Coverage Total Hit
Test: Wirestead Coverage Report Lines: 88.5 % 52 46
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: 73.2 % 82 60

             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                 :             : struct TcpClientConfig {
      29                 :             :   std::string host = "127.0.0.1";
      30                 :             :   uint16_t port = 9000;
      31                 :             :   unsigned retry_interval_ms = base::constants::DEFAULT_RETRY_INTERVAL_MS;
      32                 :             :   unsigned connection_timeout_ms = base::constants::DEFAULT_CONNECTION_TIMEOUT_MS;
      33                 :             :   unsigned idle_timeout_ms = base::constants::DEFAULT_IDLE_TIMEOUT_MS;  // 0 = disabled
      34                 :             :   IdleTimeoutAction idle_timeout_action = IdleTimeoutAction::Reconnect;
      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                 :             :   bool tcp_no_delay = base::constants::DEFAULT_TCP_NO_DELAY;
      40                 :             :   bool keep_alive = base::constants::DEFAULT_KEEP_ALIVE;
      41                 :             :   size_t send_buffer_size = 0;
      42                 :             :   size_t receive_buffer_size = 0;
      43                 :             :   // Size of the per-connection userspace read buffer that each
      44                 :             :   // async_read_some() fills. Distinct from receive_buffer_size, which is the
      45                 :             :   // kernel's SO_RCVBUF. Raising this reduces read completions and callback
      46                 :             :   // dispatches on bulk transfers, at the cost of that much memory per
      47                 :             :   // connection.
      48                 :             :   size_t read_buffer_size = base::constants::DEFAULT_READ_BUFFER_SIZE;
      49                 :             : 
      50                 :             :   // TLS. Off unless tls_enabled is set, which is the default.
      51                 :             :   //
      52                 :             :   // The server side of TLS proves who it is; the client side is what checks.
      53                 :             :   // Verification is therefore on and not optional: an unverified TLS connection
      54                 :             :   // encrypts traffic to whoever answered, which is exactly what an attacker in
      55                 :             :   // the middle wants. Leave tls_ca_file empty to use the system trust store,
      56                 :             :   // or point it at a PEM to trust a private CA or a self-signed certificate.
      57                 :             :   bool tls_enabled = false;
      58                 :             :   std::string tls_ca_file;
      59                 :             : 
      60                 :         756 :   TcpClientConfig() = default;
      61                 :         229 :   TcpClientConfig(const TcpClientConfig&) = default;
      62                 :          99 :   TcpClientConfig& operator=(const TcpClientConfig&) = default;
      63                 :             :   TcpClientConfig(TcpClientConfig&&) noexcept = default;
      64                 :             :   TcpClientConfig& operator=(TcpClientConfig&&) noexcept = default;
      65                 :             : 
      66                 :             :   // Validation methods
      67                 :          21 :   bool is_valid() const {
      68                 :          41 :     return read_buffer_size >= base::constants::MIN_READ_BUFFER_SIZE &&
      69   [ +  +  +  + ]:          20 :            read_buffer_size <= base::constants::MAX_READ_BUFFER_SIZE && util::InputValidator::is_valid_host(host) &&
      70   [ +  -  +  - ]:          16 :            port > 0 && retry_interval_ms >= base::constants::MIN_RETRY_INTERVAL_MS &&
      71         [ +  - ]:          16 :            retry_interval_ms <= base::constants::MAX_RETRY_INTERVAL_MS &&
      72         [ +  + ]:          16 :            connection_timeout_ms >= base::constants::MIN_CONNECTION_TIMEOUT_MS &&
      73         [ +  + ]:          15 :            connection_timeout_ms <= base::constants::MAX_CONNECTION_TIMEOUT_MS &&
      74   [ +  +  +  - ]:          14 :            (idle_timeout_ms == 0 || (idle_timeout_ms >= base::constants::MIN_IDLE_TIMEOUT_MS &&
      75         [ -  + ]:           1 :                                      idle_timeout_ms <= base::constants::MAX_IDLE_TIMEOUT_MS)) &&
      76         [ +  - ]:          13 :            backpressure_threshold >= base::constants::MIN_BACKPRESSURE_THRESHOLD &&
      77         [ +  - ]:          13 :            backpressure_threshold <= base::constants::MAX_BACKPRESSURE_THRESHOLD &&
      78   [ +  +  +  + ]:          13 :            (send_buffer_size == 0 || (send_buffer_size >= base::constants::MIN_SOCKET_BUFFER_SIZE &&
      79         [ +  - ]:           1 :                                       send_buffer_size <= base::constants::MAX_SOCKET_BUFFER_SIZE)) &&
      80   [ +  +  +  - ]:          12 :            (receive_buffer_size == 0 || (receive_buffer_size >= base::constants::MIN_SOCKET_BUFFER_SIZE &&
      81   [ +  +  +  - ]:          42 :                                          receive_buffer_size <= base::constants::MAX_SOCKET_BUFFER_SIZE)) &&
      82   [ -  +  -  -  :          33 :            (max_retries == -1 || (max_retries >= 0 && max_retries <= base::constants::MAX_RETRIES_LIMIT));
                   -  - ]
      83                 :             :   }
      84                 :             : 
      85                 :             :   // Apply validation and clamp values to valid ranges
      86                 :         153 :   void validate_and_clamp() {
      87         [ +  + ]:         153 :     if (read_buffer_size < base::constants::MIN_READ_BUFFER_SIZE) {
      88                 :           1 :       read_buffer_size = base::constants::MIN_READ_BUFFER_SIZE;
      89         [ +  + ]:         152 :     } else if (read_buffer_size > base::constants::MAX_READ_BUFFER_SIZE) {
      90                 :           1 :       read_buffer_size = base::constants::MAX_READ_BUFFER_SIZE;
      91                 :             :     }
      92         [ +  + ]:         153 :     if (retry_interval_ms < base::constants::MIN_RETRY_INTERVAL_MS) {
      93                 :          14 :       retry_interval_ms = base::constants::MIN_RETRY_INTERVAL_MS;
      94         [ -  + ]:         139 :     } else if (retry_interval_ms > base::constants::MAX_RETRY_INTERVAL_MS) {
      95                 :           0 :       retry_interval_ms = base::constants::MAX_RETRY_INTERVAL_MS;
      96                 :             :     }
      97                 :             : 
      98         [ +  + ]:         153 :     if (connection_timeout_ms < base::constants::MIN_CONNECTION_TIMEOUT_MS) {
      99                 :           8 :       connection_timeout_ms = base::constants::MIN_CONNECTION_TIMEOUT_MS;
     100         [ +  + ]:         145 :     } else if (connection_timeout_ms > base::constants::MAX_CONNECTION_TIMEOUT_MS) {
     101                 :           1 :       connection_timeout_ms = base::constants::MAX_CONNECTION_TIMEOUT_MS;
     102                 :             :     }
     103                 :             : 
     104         [ +  + ]:         153 :     if (idle_timeout_ms != 0) {
     105         [ -  + ]:           5 :       if (idle_timeout_ms < base::constants::MIN_IDLE_TIMEOUT_MS) {
     106                 :           0 :         idle_timeout_ms = base::constants::MIN_IDLE_TIMEOUT_MS;
     107         [ +  + ]:           5 :       } else if (idle_timeout_ms > base::constants::MAX_IDLE_TIMEOUT_MS) {
     108                 :           1 :         idle_timeout_ms = base::constants::MAX_IDLE_TIMEOUT_MS;
     109                 :             :       }
     110                 :             :     }
     111                 :             : 
     112         [ +  + ]:         153 :     if (backpressure_threshold < base::constants::MIN_BACKPRESSURE_THRESHOLD) {
     113                 :           1 :       backpressure_threshold = base::constants::MIN_BACKPRESSURE_THRESHOLD;
     114         [ -  + ]:         152 :     } else if (backpressure_threshold > base::constants::MAX_BACKPRESSURE_THRESHOLD) {
     115                 :           0 :       backpressure_threshold = base::constants::MAX_BACKPRESSURE_THRESHOLD;
     116                 :             :     }
     117                 :             : 
     118   [ +  +  -  + ]:         153 :     if (max_retries != -1 && max_retries > base::constants::MAX_RETRIES_LIMIT) {
     119                 :           0 :       max_retries = base::constants::MAX_RETRIES_LIMIT;
     120                 :             :     }
     121                 :             : 
     122   [ +  +  +  - ]:         153 :     if (send_buffer_size != 0 && send_buffer_size < base::constants::MIN_SOCKET_BUFFER_SIZE) {
     123                 :           1 :       send_buffer_size = base::constants::MIN_SOCKET_BUFFER_SIZE;
     124         [ -  + ]:         152 :     } else if (send_buffer_size > base::constants::MAX_SOCKET_BUFFER_SIZE) {
     125                 :           0 :       send_buffer_size = base::constants::MAX_SOCKET_BUFFER_SIZE;
     126                 :             :     }
     127                 :             : 
     128   [ +  +  -  + ]:         153 :     if (receive_buffer_size != 0 && receive_buffer_size < base::constants::MIN_SOCKET_BUFFER_SIZE) {
     129                 :           0 :       receive_buffer_size = base::constants::MIN_SOCKET_BUFFER_SIZE;
     130         [ +  + ]:         153 :     } else if (receive_buffer_size > base::constants::MAX_SOCKET_BUFFER_SIZE) {
     131                 :           1 :       receive_buffer_size = base::constants::MAX_SOCKET_BUFFER_SIZE;
     132                 :             :     }
     133                 :         153 :   }
     134                 :             : };
     135                 :             : 
     136                 :             : }  // namespace config
     137                 :             : }  // namespace wirestead
        

Generated by: LCOV version 2.0-1