]> Kevux Git Server - kevux-tools/commitdiff
Progress: Further work in TacocaT.
authorKevin Day <thekevinday@gmail.com>
Thu, 31 Aug 2023 04:12:54 +0000 (23:12 -0500)
committerKevin Day <thekevinday@gmail.com>
Thu, 31 Aug 2023 04:12:54 +0000 (23:12 -0500)
Add the beginnings of some basic sanity checks.
The max buffer size is provided to prevent DOS and similar attacks by sending an infinitely large packet.

The TacocaT program is not designed for nor is it intended to be used for handling infinite streams.

15 files changed:
documents/readme.tacocat.txt
sources/c/tacocat/main/common.c
sources/c/tacocat/main/common/define.h
sources/c/tacocat/main/common/enumeration.h
sources/c/tacocat/main/common/string.c
sources/c/tacocat/main/common/string.h
sources/c/tacocat/main/common/type.h
sources/c/tacocat/main/print/error.c
sources/c/tacocat/main/print/error.h
sources/c/tacocat/main/print/message.c
sources/c/tacocat/main/print/warning.c
sources/c/tacocat/main/print/warning.h
sources/c/tacocat/main/process.c
sources/c/tacocat/main/receive.c
sources/c/tacocat/main/receive.h

index 34ca94ff8cf2428d923659a602399b190970eef9..2bf8f0e3588b83838d818d509b8049de4604d45d 100644 (file)
@@ -18,6 +18,8 @@ TacocaT Readme Documentation:
 
   The bold:"tacocat" program has the following arguments\:
 
+  The code:"--interval" (code:"-I") parameter designates a custom poll interval (in milliseconds) to use.
+  The code:"--max_buffer" (code:"-M") parameter designates a maximum buffer size to allow (in bytes) when receiving packets.
   The code:"--receive" (code:"-r") parameter is an address or socket file to listen to.
   The code:"--resolve" (code:"-R") parameter designates a DNS:"Domain Name Resolver" mode, such as code:"classic" or code:"kevux".
   The code:"--send" (code:"-s") parameter is an address or socket file to transmit to.
index f38a232c987484b33d14dd96b5dbbc34d1ef0aa4..50d743403d48d6431355b23372171af51718b568 100644 (file)
@@ -173,6 +173,54 @@ extern "C" {
       return;
     }
 
+    if (main->program.parameters.array[kt_tacocat_parameter_max_buffer_e].result & f_console_result_value_e) {
+      index = main->program.parameters.array[kt_tacocat_parameter_max_buffer_e].values.array[main->program.parameters.array[kt_tacocat_parameter_max_buffer_e].values.used - 1];
+
+      f_number_unsigned_t number = 0;
+
+      main->setting.state.status = fl_conversion_dynamic_to_unsigned_detect(fl_conversion_data_base_10_c, main->program.parameters.arguments.array[index], &number);
+
+      if (F_status_is_error(main->setting.state.status)) {
+        macro_setting_load_print_first();
+        kt_tacocat_print_error(&main->program.error, macro_kt_tacocat_f(fl_conversion_dynamic_to_unsigned_detect));
+
+        return;
+      }
+
+      if (number == 0) {
+        kt_tacocat_print_warning_parameter_integer_is(&main->program.warning, f_console_symbol_long_normal_s, kt_tacocat_long_max_buffer_s, f_string_ascii_0_s);
+
+        main->setting.max_buffer = 0;
+        main->setting.flag |= kt_tacocat_main_flag_max_buffer_e;
+      }
+      else if (main->setting.state.status == F_number_negative) {
+        if (number == 1) {
+          main->setting.max_buffer = 0;
+          main->setting.flag -= main->setting.flag & kt_tacocat_main_flag_max_buffer_e;
+        }
+        else {
+          main->setting.state.status = F_status_set_error(F_parameter);
+
+          fll_program_print_error_parameter_integer_less_than(&main->program.error, f_console_symbol_long_normal_s, kt_tacocat_long_max_buffer_s, main->program.parameters.arguments.array[index], kt_tacocat_digit_negative_one_s);
+
+          return;
+        }
+      }
+      else {
+        main->setting.max_buffer = number;
+        main->setting.flag |= kt_tacocat_main_flag_max_buffer_e;
+      }
+    }
+    else if (main->program.parameters.array[kt_tacocat_parameter_max_buffer_e].result & f_console_result_found_e) {
+      main->setting.state.status = F_status_set_error(F_parameter);
+
+      macro_setting_load_print_first();
+
+      fll_program_print_error_parameter_missing_value(&main->program.error, f_console_symbol_long_normal_s, kt_tacocat_long_max_buffer_s);
+
+      return;
+    }
+
     // Only process these when needed to avoid unnecessary operations.
     if (main->callback.setting_load_send_receive && !(main->setting.flag & (kt_tacocat_main_flag_copyright_e | kt_tacocat_main_flag_version_e |kt_tacocat_main_flag_help_e))) {
       main->callback.setting_load_send_receive(arguments, (void *) main);
@@ -472,8 +520,8 @@ extern "C" {
             f_file_close(&sets[i]->files.array[j]);
 
             sets[i]->files.array[j].flag = is_receive[i] ? F_file_flag_append_wo_d : F_file_flag_read_only_d;
-            sets[i]->files.array[j].size_read = sets[i]->block_size;
-            sets[i]->files.array[j].size_write = sets[i]->block_size;
+            sets[i]->files.array[j].size_read = sets[i]->size_block;
+            sets[i]->files.array[j].size_write = sets[i]->size_block;
 
             main->setting.state.status = f_file_open(main->program.parameters.arguments.array[index], F_file_mode_all_rw_d, &sets[i]->files.array[j]);
 
index c90d3a7bdbf8cf1ae80fca180ff2f32972aa2a88..2682fea6afd8991a7338fd6f022ddafa48188aa5 100644 (file)
@@ -24,9 +24,6 @@ extern "C" {
  *   - large:   An allocation step used for buffers that are anticipated to have large buffers.
  *   - small:   An allocation step used for buffers that are anticipated to have small buffers.
  *
- * kt_tacocat_backlog_*_d:
- *   - max: The max backlog size to use.
- *
  * kt_tacocat_block_*_d:
  *   - size:         The block size in bytes to use for either sending or receiving.
  *   - size_receive: The block size in bytes to use when sending packets.
@@ -35,6 +32,11 @@ extern "C" {
  * kt_tacocat_interval_*_d:
  *   - poll: The time in milliseconds to poll for before returning (this is the amount of time poll() blocks).
  *
+ * kt_tacocat_max_*_d:
+ *   - backlog:  The max backlog in bytes size to use.
+ *   - buffer:   The max buffer in bytes size to use when receiving packets.
+ *   - maintain: The max size in bytes to maintain a particular buffer.
+ *
  * kt_tacocat_packet_*_d:
  *   - peek: The size to peek into the packet to get the initial information.
  *   - read: The size to read at a time when processing the packet.
@@ -44,23 +46,25 @@ extern "C" {
  *   - check_failsafe: When using threads, how many consecutive failures to check signal before aborting (as a recursion failsafe).
  */
 #ifndef _di_kt_tacocat_d_
-  #define kt_tacocat_allocation_console_d 4
-  #define kt_tacocat_allocation_large_d   2048
-  #define kt_tacocat_allocation_small_d   128
+  #define kt_tacocat_allocation_console_d 0x4
+  #define kt_tacocat_allocation_large_d   0x800
+  #define kt_tacocat_allocation_small_d   0x80
 
-  #define kt_tacocat_backlog_max_d 1024
-
-  #define kt_tacocat_block_size_d         65535
+  #define kt_tacocat_block_size_d         0xffff
   #define kt_tacocat_block_size_receive_d kt_tacocat_block_size_d
   #define kt_tacocat_block_size_send_d    kt_tacocat_block_size_d
 
   #define kt_tacocat_interval_poll_d 1400 // 1.4 second.
 
+  #define kt_tacocat_max_backlog_d  0x400
+  #define kt_tacocat_max_buffer_d   0x10000000 // 0x10^0x5 * 0x100 (Which is 256 Megabytes (0x10^0x5 where the base unit is 16 rather than 10 or 2 (maybe call this xytes? Megaxytes?)).
+  #define kt_tacocat_max_maintain_d 0x100000   // 0x10^5 (Which is 1 Megabyte in base 16 (1 Megaxyte (MX)).
+
   #define kt_tacocat_packet_peek_d F_fss_simple_packet_block_header_size_d
-  #define kt_tacocat_packet_read_d 8192
+  #define kt_tacocat_packet_read_d 0x2000
 
-  #define kt_tacocat_signal_check_d          20000
-  #define kt_tacocat_signal_check_failsafe_d 20000
+  #define kt_tacocat_signal_check_d          0x4e20
+  #define kt_tacocat_signal_check_failsafe_d 0x4e20
 #endif // _di_kt_tacocat_d_
 
 /**
index 88e8858b3263309f27a49e2448898f4ae386caf1..a7b6537250eae6fce54eb4688b6d267a1d9f8571 100644 (file)
@@ -24,6 +24,7 @@ extern "C" {
  *   - copyright:       Print copyright.
  *   - print_first:     When set, print new line to message output on program begin after loading settings.
  *   - print_last:      When set, print new line to message output on program end.
+ *   - max_buffer:      When set, a maximum buffer on receive is enforced.
  *   - receive:         The address or socket to receive from is specified.
  *   - resolve_classic: Follow the classic Domain Name Resolution method.
  *   - resolve_kevux:   Follow the Kevux Domain Name Resolution method.
@@ -47,14 +48,15 @@ extern "C" {
     kt_tacocat_main_flag_none_e            = 0x0,
     kt_tacocat_main_flag_copyright_e       = 0x1,
     kt_tacocat_main_flag_help_e            = 0x2,
-    kt_tacocat_main_flag_print_first_e     = 0x4,
-    kt_tacocat_main_flag_print_last_e      = 0x8,
-    kt_tacocat_main_flag_receive_e         = 0x10,
-    kt_tacocat_main_flag_resolve_classic_e = 0x20,
-    kt_tacocat_main_flag_resolve_kevux_e   = 0x40,
-    kt_tacocat_main_flag_resolve_e         = 0x80,
-    kt_tacocat_main_flag_send_e            = 0x100,
-    kt_tacocat_main_flag_version_e         = 0x200,
+    kt_tacocat_main_flag_max_buffer_e      = 0x4,
+    kt_tacocat_main_flag_print_first_e     = 0x8,
+    kt_tacocat_main_flag_print_last_e      = 0x10,
+    kt_tacocat_main_flag_receive_e         = 0x20,
+    kt_tacocat_main_flag_resolve_classic_e = 0x40,
+    kt_tacocat_main_flag_resolve_kevux_e   = 0x80,
+    kt_tacocat_main_flag_resolve_e         = 0x100,
+    kt_tacocat_main_flag_send_e            = 0x200,
+    kt_tacocat_main_flag_version_e         = 0x400,
   }; // enum
 #endif // _di_kt_tacocat_main_flag_e_
 
@@ -78,6 +80,7 @@ extern "C" {
     kt_tacocat_parameter_line_last_no_e,
 
     kt_tacocat_parameter_interval_e,
+    kt_tacocat_parameter_max_buffer_e,
     kt_tacocat_parameter_receive_e,
     kt_tacocat_parameter_resolve_e,
     kt_tacocat_parameter_send_e,
@@ -88,12 +91,13 @@ extern "C" {
       macro_fll_program_console_parameter_standard_initialize, \
       \
       macro_f_console_parameter_t_initialize_3(kt_tacocat_short_interval_s, kt_tacocat_long_interval_s, 1, f_console_flag_normal_e), \
+      macro_f_console_parameter_t_initialize_3(kt_tacocat_short_max_buffer_s, kt_tacocat_long_max_buffer_s, 1, f_console_flag_normal_e), \
       macro_f_console_parameter_t_initialize_3(kt_tacocat_short_receive_s, kt_tacocat_long_receive_s, 2, f_console_flag_normal_e), \
       macro_f_console_parameter_t_initialize_3(kt_tacocat_short_resolve_s, kt_tacocat_long_resolve_s, 1, f_console_flag_normal_e), \
       macro_f_console_parameter_t_initialize_3(kt_tacocat_short_send_s, kt_tacocat_long_send_s, 2, f_console_flag_normal_e), \
     }
 
-  #define kt_tacocat_parameter_total_d 17
+  #define kt_tacocat_parameter_total_d 18
 #endif // _di_kt_tacocat_parameter_e_
 
 /**
index 1e049b888f71a9642fab98c20c21c90c8a1d21c1..0872b2f196ee198c4977892149c1fb85a1873acf 100644 (file)
@@ -19,6 +19,7 @@ extern "C" {
 
 #ifndef _di_kt_tacocat_s_
   const f_string_static_t kt_tacocat_classic_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_classic_s, 0, KT_TACOCAT_classic_s_length);
+  const f_string_static_t kt_tacocat_digit_negative_one_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_digit_negative_one_s, 0, KT_TACOCAT_digit_negative_one_s_length);
   const f_string_static_t kt_tacocat_kevux_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_kevux_s, 0, KT_TACOCAT_kevux_s_length);
   const f_string_static_t kt_tacocat_file_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_file_s, 0, KT_TACOCAT_file_s_length);
   const f_string_static_t kt_tacocat_network_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_network_s, 0, KT_TACOCAT_network_s_length);
@@ -32,11 +33,13 @@ extern "C" {
 
 #ifndef _di_kt_tacocat_parameter_s_
   const f_string_static_t kt_tacocat_short_interval_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_short_interval_s, 0, KT_TACOCAT_short_interval_s_length);
+  const f_string_static_t kt_tacocat_short_max_buffer_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_short_max_buffer_s, 0, KT_TACOCAT_short_max_buffer_s_length);
   const f_string_static_t kt_tacocat_short_receive_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_short_receive_s, 0, KT_TACOCAT_short_receive_s_length);
   const f_string_static_t kt_tacocat_short_resolve_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_short_resolve_s, 0, KT_TACOCAT_short_resolve_s_length);
   const f_string_static_t kt_tacocat_short_send_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_short_send_s, 0, KT_TACOCAT_short_send_s_length);
 
   const f_string_static_t kt_tacocat_long_interval_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_long_interval_s, 0, KT_TACOCAT_long_interval_s_length);
+  const f_string_static_t kt_tacocat_long_max_buffer_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_long_max_buffer_s, 0, KT_TACOCAT_long_max_buffer_s_length);
   const f_string_static_t kt_tacocat_long_receive_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_long_receive_s, 0, KT_TACOCAT_long_receive_s_length);
   const f_string_static_t kt_tacocat_long_resolve_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_long_resolve_s, 0, KT_TACOCAT_long_resolve_s_length);
   const f_string_static_t kt_tacocat_long_send_s = macro_f_string_static_t_initialize_1(KT_TACOCAT_long_send_s, 0, KT_TACOCAT_long_send_s_length);
index 6fc8ecf1103fb5c8e99a1f2da836de7d82506dcf..df04c1007c288411de9054dfad2bec53f9c1b31c 100644 (file)
@@ -72,29 +72,32 @@ extern "C" {
  * kt_tacocat_*_s: Arbitrary strings.
  */
 #ifndef _di_kt_tacocat_s_
-  #define KT_TACOCAT_classic_s           "classic"
-  #define KT_TACOCAT_kevux_s             "kevux"
-  #define KT_TACOCAT_file_s              "file"
-  #define KT_TACOCAT_network_s           "network"
-  #define KT_TACOCAT_network_or_socket_s "network / socket"
-  #define KT_TACOCAT_receive_s           "receive"
-  #define KT_TACOCAT_send_s              "send"
-  #define KT_TACOCAT_socket_s            "socket"
-  #define KT_TACOCAT_tacocat_s           "tacocat"
-  #define KT_TACOCAT_two_s               "two"
-
-  #define KT_TACOCAT_classic_s_length           7
-  #define KT_TACOCAT_kevux_s_length             5
-  #define KT_TACOCAT_file_s_length              4
-  #define KT_TACOCAT_network_s_length           7
-  #define KT_TACOCAT_network_or_socket_s_length 16
-  #define KT_TACOCAT_receive_s_length           7
-  #define KT_TACOCAT_send_s_length              4
-  #define KT_TACOCAT_socket_s_length            6
-  #define KT_TACOCAT_tacocat_s_length           7
-  #define KT_TACOCAT_two_s_length               3
+  #define KT_TACOCAT_classic_s            "classic"
+  #define KT_TACOCAT_digit_negative_one_s "-1"
+  #define KT_TACOCAT_kevux_s              "kevux"
+  #define KT_TACOCAT_file_s               "file"
+  #define KT_TACOCAT_network_s            "network"
+  #define KT_TACOCAT_network_or_socket_s  "network / socket"
+  #define KT_TACOCAT_receive_s            "receive"
+  #define KT_TACOCAT_send_s               "send"
+  #define KT_TACOCAT_socket_s             "socket"
+  #define KT_TACOCAT_tacocat_s            "tacocat"
+  #define KT_TACOCAT_two_s                "two"
+
+  #define KT_TACOCAT_classic_s_length            7
+  #define KT_TACOCAT_digit_negative_one_s_length 2
+  #define KT_TACOCAT_kevux_s_length              5
+  #define KT_TACOCAT_file_s_length               4
+  #define KT_TACOCAT_network_s_length            7
+  #define KT_TACOCAT_network_or_socket_s_length  16
+  #define KT_TACOCAT_receive_s_length            7
+  #define KT_TACOCAT_send_s_length               4
+  #define KT_TACOCAT_socket_s_length             6
+  #define KT_TACOCAT_tacocat_s_length            7
+  #define KT_TACOCAT_two_s_length                3
 
   extern const f_string_static_t kt_tacocat_classic_s;
+  extern const f_string_static_t kt_tacocat_digit_negative_one_s;
   extern const f_string_static_t kt_tacocat_kevux_s;
   extern const f_string_static_t kt_tacocat_file_s;
   extern const f_string_static_t kt_tacocat_network_s;
@@ -110,32 +113,38 @@ extern "C" {
  * The main program parameters.
  */
 #ifndef _di_kt_tacocat_parameter_s_
-  #define KT_TACOCAT_short_interval_s "I"
-  #define KT_TACOCAT_short_receive_s  "r"
-  #define KT_TACOCAT_short_resolve_s  "R"
-  #define KT_TACOCAT_short_send_s     "s"
-
-  #define KT_TACOCAT_long_interval_s "interval"
-  #define KT_TACOCAT_long_receive_s  "receive"
-  #define KT_TACOCAT_long_resolve_s  "resolve"
-  #define KT_TACOCAT_long_send_s     "send"
-
-  #define KT_TACOCAT_short_interval_s_length 1
-  #define KT_TACOCAT_short_receive_s_length  1
-  #define KT_TACOCAT_short_resolve_s_length  1
-  #define KT_TACOCAT_short_send_s_length     1
-
-  #define KT_TACOCAT_long_interval_s_length 8
-  #define KT_TACOCAT_long_receive_s_length  7
-  #define KT_TACOCAT_long_resolve_s_length  7
-  #define KT_TACOCAT_long_send_s_length     4
+  #define KT_TACOCAT_short_interval_s   "I"
+  #define KT_TACOCAT_short_max_buffer_s "M"
+  #define KT_TACOCAT_short_receive_s    "r"
+  #define KT_TACOCAT_short_resolve_s    "R"
+  #define KT_TACOCAT_short_send_s       "s"
+
+  #define KT_TACOCAT_long_interval_s   "interval"
+  #define KT_TACOCAT_long_max_buffer_s "max_buffer"
+  #define KT_TACOCAT_long_receive_s    "receive"
+  #define KT_TACOCAT_long_resolve_s    "resolve"
+  #define KT_TACOCAT_long_send_s       "send"
+
+  #define KT_TACOCAT_short_interval_s_length   1
+  #define KT_TACOCAT_short_max_buffer_s_length 1
+  #define KT_TACOCAT_short_receive_s_length    1
+  #define KT_TACOCAT_short_resolve_s_length    1
+  #define KT_TACOCAT_short_send_s_length       1
+
+  #define KT_TACOCAT_long_interval_s_length   8
+  #define KT_TACOCAT_long_max_buffer_s_length 10
+  #define KT_TACOCAT_long_receive_s_length    7
+  #define KT_TACOCAT_long_resolve_s_length    7
+  #define KT_TACOCAT_long_send_s_length       4
 
   extern const f_string_static_t kt_tacocat_short_interval_s;
+  extern const f_string_static_t kt_tacocat_short_max_buffer_s;
   extern const f_string_static_t kt_tacocat_short_receive_s;
   extern const f_string_static_t kt_tacocat_short_resolve_s;
   extern const f_string_static_t kt_tacocat_short_send_s;
 
   extern const f_string_static_t kt_tacocat_long_interval_s;
+  extern const f_string_static_t kt_tacocat_long_max_buffer_s;
   extern const f_string_static_t kt_tacocat_long_receive_s;
   extern const f_string_static_t kt_tacocat_long_resolve_s;
   extern const f_string_static_t kt_tacocat_long_send_s;
index 4b189123f85a7c0c21d8f8b51d179d303a3f8bd6..76fbdcbb238a4293e35dc834db3cfd93d0498001 100644 (file)
@@ -19,7 +19,8 @@ extern "C" {
 /**
  * A set containing all socket related data sets.
  *
- * block_size: The size in bytes to used to represent a block when sending or receiving packets.
+ * size_block:  The size in bytes to used to represent a block when sending or receiving packets.
+ * max_buffer:  The maximum size in bytes to used to represent a block when sending or receiving packets.
  *
  * flags:   An array of flags for each socket.
  * files:   An array of files for each socket.
@@ -33,7 +34,7 @@ extern "C" {
  */
 #ifndef _di_kt_tacocat_socket_set_t_
   typedef struct {
-    f_number_unsigned_t block_size;
+    f_number_unsigned_t size_block;
 
     f_uint16s_t flags;
     f_files_t files;
@@ -59,9 +60,9 @@ extern "C" {
       f_fss_simple_packet_ranges_t_initialize, \
     }
 
-  #define macro_kt_tacocat_setting_t_initialize_1(block_size) \
+  #define macro_kt_tacocat_setting_t_initialize_1(size_block) \
     { \
-      block_size, \
+      size_block, \
       f_uint16s_t_initialize, \
       f_files_t_initialize, \
       f_polls_t_initialize, \
@@ -79,8 +80,9 @@ extern "C" {
  * This is passed to the program-specific main entry point to designate program settings.
  * These program settings are often processed from the program arguments (often called the command line arguments).
  *
- * flag:     Flags passed to the main function.
- * interval: The poll interval to use.
+ * flag:       Flags passed to the main function.
+ * interval:   The poll interval to use.
+ * max_buffer: The maximum buffer size to use on receive.
  *
  * status_receive: A status used exclusively by the receive thread.
  * status_send:    A status used exclusively by the send thread.
@@ -97,6 +99,7 @@ extern "C" {
   typedef struct {
     uint64_t flag;
     uint64_t interval;
+    f_number_unsigned_t max_buffer;
 
     f_status_t status_receive;
     f_status_t status_send;
@@ -112,8 +115,9 @@ extern "C" {
 
   #define kt_tacocat_setting_t_initialize \
     { \
-      kt_tacocat_main_flag_none_e, \
+      kt_tacocat_main_flag_max_buffer_e, \
       kt_tacocat_interval_poll_d, \
+      kt_tacocat_max_buffer_d, \
       F_okay, \
       F_okay, \
       F_okay, \
index 6ccd7a5fc23521f9d908df0b91eaa7db28f85c03..6b7f8f1fb1e581236fbe98268251715dde8acd41 100644 (file)
@@ -50,6 +50,26 @@ extern "C" {
   }
 #endif // _di_kt_tacocat_print_error_
 
+#ifndef _di_kt_tacocat_print_error_on_buffer_too_large_
+  f_status_t kt_tacocat_print_error_on_buffer_too_large(fl_print_t * const print, f_string_static_t on, const f_string_static_t network) {
+
+    if (!print || !print->custom) return F_status_set_error(F_output_not);
+    if (print->verbosity < f_console_verbosity_error_e) return F_output_not;
+
+    f_file_stream_lock(print->to);
+
+    fl_print_format("%[%QNetwork packets too large for%] ", print->to, print->set->error, print->prefix, print->set->error);
+    fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, on, print->set->notable);
+    fl_print_format(" %[buffer for '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
+    fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, network, print->set->notable);
+    fl_print_format(" %['.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s);
+
+    f_file_stream_unlock(print->to);
+
+    return F_okay;
+  }
+#endif // _di_kt_tacocat_print_error_on_buffer_too_large_
+
 #ifndef _di_kt_tacocat_print_error_parameter_value_resolve_unknown_
   f_status_t kt_tacocat_print_error_parameter_value_resolve_unknown(fl_print_t * const print, const f_string_dynamic_t unknown) {
 
@@ -59,7 +79,7 @@ extern "C" {
     f_file_stream_lock(print->to);
 
     fl_print_format("%[%QThe parameter%] ", print->to, print->set->error, print->prefix, print->set->error);
-    fl_print_format("%[%Q%Q%]", print->to, print->set->notable, f_console_symbol_long_normal_s, kt_tacocat_long_resolve_s, print->set->notable);
+    fl_print_format(f_string_format_QQ_single_s.string, print->to, print->set->notable, f_console_symbol_long_normal_s, kt_tacocat_long_resolve_s, print->set->notable);
     fl_print_format(" %[may only be either '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
     fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, kt_tacocat_classic_s, print->set->notable);
     fl_print_format("%' or '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
@@ -111,7 +131,7 @@ extern "C" {
     f_file_stream_lock(print->to);
 
     fl_print_format("%[%QUnsupported protocol%] ", print->to, print->set->error, print->prefix, print->set->error);
-    fl_print_format("%[%lu%]", print->to, print->set->notable, protocol, print->set->notable);
+    fl_print_format("%[%ul%]", print->to, print->set->notable, protocol, print->set->notable);
     fl_print_format(" %[while processing '%]", print->to, print->set->error, print->set->error, f_string_eol_s);
     fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, name, print->set->notable);
     fl_print_format(" %['.%]%r", print->to, print->set->error, print->set->error, f_string_eol_s);
index 3d883a62624a0c4b76e9c71b90a46d59fb87c7ab..a2d8253eca94bf2d68c48adce9a3d92ea193799a 100644 (file)
@@ -95,6 +95,30 @@ extern "C" {
 #endif // _di_kt_tacocat_print_error_on_
 
 /**
+ * Print file related error or warning messages for when buffer is too large to accept additional packet blocks.
+ *
+ * @param print
+ *   The output structure to print to.
+ *
+ *   This does not alter print.custom.setting.state.status.
+ * @param on
+ *   The network connection direction, which should either be "receive" or "send".
+ * @param network
+ *   The name of the network in which the error is related.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_output_not on success, but no printing is performed.
+ *
+ *   F_output_not (with error bit) if setting is NULL.
+ *
+ * @see fll_error_file_print()
+ */
+#ifndef _di_kt_tacocat_print_error_on_buffer_too_large_
+  f_status_t kt_tacocat_print_error_on_buffer_too_large(fl_print_t * const print, f_string_static_t on, const f_string_static_t network);
+#endif // _di_kt_tacocat_print_error_on_buffer_too_large_
+
+/**
  * Print error message for when an unknown value for the resolve parameter is provided.
  *
  * @param print
index 8a92e70d2cb841a5fe94154c3cd33e2b4fa8bf0d..a5d2936f1063bb9e2da3e685161b4fad0bc9cc19 100644 (file)
@@ -19,15 +19,19 @@ extern "C" {
 
     f_print_dynamic_raw(f_string_eol_s, print->to);
 
-    fll_program_print_help_option(print, kt_tacocat_short_interval_s, kt_tacocat_long_interval_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "Specify a custom poll interval in milliseconds to use.");
-    fll_program_print_help_option(print, kt_tacocat_short_receive_s, kt_tacocat_long_receive_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, " Specify an address or socket file to listen to and a file to write to.");
-    fll_program_print_help_option(print, kt_tacocat_short_resolve_s, kt_tacocat_long_resolve_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, " Specify a custom DNS resolution methodology.");
-    fll_program_print_help_option(print, kt_tacocat_short_send_s, kt_tacocat_long_send_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "    Specify an address or socket file send transmit to and a file to read from.");
+    fll_program_print_help_option(print, kt_tacocat_short_interval_s, kt_tacocat_long_interval_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "  Specify a custom poll interval in milliseconds to use.");
+    fll_program_print_help_option(print, kt_tacocat_short_max_buffer_s, kt_tacocat_long_max_buffer_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "Specify a maximum buffer size to allow (in bytes) when receiving packets.");
+    fll_program_print_help_option(print, kt_tacocat_short_receive_s, kt_tacocat_long_receive_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "   Specify an address or socket file to listen to and a file to write to.");
+    fll_program_print_help_option(print, kt_tacocat_short_resolve_s, kt_tacocat_long_resolve_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "   Specify a custom DNS resolution methodology.");
+    fll_program_print_help_option(print, kt_tacocat_short_send_s, kt_tacocat_long_send_s, f_console_symbol_short_normal_s, f_console_symbol_long_normal_s, "      Specify an address or socket file send transmit to and a file to read from.");
 
     f_print_dynamic_raw(f_string_eol_s, print->to);
 
     fll_program_print_help_usage(print, kt_tacocat_program_name_s, f_string_empty_s);
 
+    fl_print_format("%r  The parameter '%[%r%r%]' may be set to ", print->to, f_string_eol_s, context.set.notable, f_console_symbol_long_normal_s, kt_tacocat_long_max_buffer_s, context.set.notable);
+    fl_print_format("%[-1%] to disable the maximum buffer size limit on receive.%r%r", print->to, context.set.notable, context.set.notable, f_string_eol_s, f_string_eol_s);
+
     fl_print_format("%r  The parameters '%[%r%r%]', ", print->to, f_string_eol_s, context.set.notable, f_console_symbol_long_normal_s, kt_tacocat_long_receive_s, context.set.notable);
     fl_print_format("'%[%r%r%]' ", print->to, context.set.notable, f_console_symbol_long_normal_s, kt_tacocat_long_send_s, context.set.notable);
     fl_print_format("may either represent a network address or a local socket file.%r%r", print->to, f_string_eol_s, f_string_eol_s);
index fb76bdfaf7bd214ed1e4379bf7c737014313fc5a..3e3b16e74028f66e2b45828f17a8d4cfc240978b 100644 (file)
@@ -4,7 +4,26 @@
 extern "C" {
 #endif
 
-#ifndef _di_fake_build_print_warning_setting_boolean_may_only_be_
+#ifndef _di_kt_tacocat_print_warning_parameter_integer_is_
+  f_status_t kt_tacocat_print_warning_parameter_integer_is(fl_print_t * const print, const f_string_static_t symbol, const f_string_static_t name, const f_string_static_t is) {
+
+    if (print->verbosity < f_console_verbosity_verbose_e) return F_output_not;
+
+    f_file_stream_lock(print->to);
+
+    fl_print_format("%[%QThe value for the parameter '%]", print->to, print->set->error, print->set->error);
+    fl_print_format(f_string_format_QQ_single_s.string, print->to, print->set->notable, symbol, name, print->set->notable);
+    fl_print_format("%[' is %]", print->to, print->set->error, print->set->error);
+    fl_print_format(f_string_format_Q_single_s.string, print->to, print->set->notable, is, print->set->notable);
+    fl_print_format(f_string_format_sentence_end_s.string, print->to, print->set->error, print->set->error, f_string_eol_s);
+
+    f_file_stream_unlock(print->to);
+
+    return F_okay;
+  }
+#endif // _di_kt_tacocat_print_warning_parameter_integer_is_
+
+#ifndef _di_kt_tacocat_print_warning_port_number_overflow_
   f_status_t kt_tacocat_print_warning_port_number_overflow(fl_print_t * const print, const f_string_static_t address, const f_number_unsigned_t port) {
 
     if (print->verbosity < f_console_verbosity_verbose_e) return F_output_not;
@@ -21,7 +40,7 @@ extern "C" {
 
     return F_okay;
   }
-#endif // _di_fake_build_print_warning_setting_boolean_may_only_be_
+#endif // _di_kt_tacocat_print_warning_port_number_overflow_
 
 #ifdef __cplusplus
 } // extern "C"
index 00d0b9432e713299857788aebb6cc24032419382..a4ed861d8c7113a56715ba1bb81ad1fca1030a36 100644 (file)
@@ -17,6 +17,38 @@ extern "C" {
 #endif
 
 /**
+ * Print warning message about given parameter being a specific integer value.
+ *
+ * @param print
+ *   The output structure to print to.
+ *
+ *   This requires print.custom to be fake_main_t.
+ *
+ *   This does not alter print.custom.setting.state.status.
+ * @param symbol
+ *   The symbol string prepended to both parameters.
+ *   This locks, uses, and unlocks the file stream.
+ *   This is usually f_console_symbol_long_normal_s.
+ * @param name
+ *   The parameter name.
+ * @param is
+ *   The string representing the number that is being warned about.
+ *
+ * @return
+ *   F_okay on success.
+ *   F_output_not on success, but no printing is performed.
+ *
+ *   F_output_not (with error bit) if setting is NULL.
+ *
+ * @see f_file_stream_lock()
+ * @see f_file_stream_unlock()
+ * @see fl_print_format()
+ */
+#ifndef _di_kt_tacocat_print_warning_parameter_integer_is_
+  extern f_status_t kt_tacocat_print_warning_parameter_integer_is(fl_print_t * const print, const f_string_static_t symbol, const f_string_static_t name, const f_string_static_t is);
+#endif // _di_kt_tacocat_print_warning_parameter_integer_is_
+
+/**
  * Print warning message about given port number being out of range for this system.
  *
  * @param print
index f51311732f807040c962d83a1b44400206c0bafa..2748b3a15a158b515301d646e9003d93f0096fa4 100644 (file)
@@ -181,7 +181,7 @@ extern "C" {
         continue;
       }
 
-      main->setting.receive.statuss.array[i] = f_socket_listen(&main->setting.receive.sockets.array[i], kt_tacocat_backlog_max_d);
+      main->setting.receive.statuss.array[i] = f_socket_listen(&main->setting.receive.sockets.array[i], kt_tacocat_max_backlog_d);
 
       if (F_status_is_error(main->setting.receive.statuss.array[i])) {
         main->setting.status_receive = main->setting.receive.statuss.array[i];
index 17a5ffc017a0dc0daefe509fc5b5b483001bf03e..fe3841af65245143d13b49a2b5e25d9e7ead27b3 100644 (file)
@@ -85,6 +85,30 @@ extern "C" {
       socket->size_read = kt_tacocat_packet_read_d;
     }
 
+    // @todo this check should also be performed after reading the FSS Packet Header against the FSS Payload length value.
+    if (main->setting.flag & kt_tacocat_main_flag_max_buffer_e) {
+      if ((buffer->used + socket->size_read) > main->setting.max_buffer) {
+        buffer->used = 0;
+
+        if (buffer->size > kt_tacocat_max_maintain_d) {
+          *status = f_memory_array_resize(kt_tacocat_max_maintain_d, sizeof(f_char_t), (void **) &buffer->string, &buffer->used, &buffer->size);
+
+          if (F_status_is_error(*status)) {
+            kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(f_memory_array_resize), kt_tacocat_receive_s, *name, *status);
+
+            return;
+          }
+        }
+
+        // @todo for all unrecoverable errors, make sure to drop/flush the packet to prevent processing and then reset the status code (otherwise an infinite error loop will occur, which is the current behavior).
+        *status = F_status_set_error(F_packet_too_large);
+
+        kt_tacocat_print_error_on_buffer_too_large(&main->program.error, kt_tacocat_receive_s, *name);
+
+        return;
+      }
+    }
+
     *status = f_memory_array_increase_by(socket->size_read, sizeof(f_char_t), (void **) &buffer->string, &buffer->used, &buffer->size);
 
     if (F_status_is_error(*status)) {
@@ -142,6 +166,17 @@ extern "C" {
 
     // For now just close the socket until the appropriate code gets written here.
     f_file_close_id(&socket->id_data);
+
+    // @todo perform this check only when fully finished processing all of the packet parts.
+    if (buffer->size > kt_tacocat_max_maintain_d) {
+      buffer->used = 0;
+
+      *status = f_memory_array_resize(kt_tacocat_max_maintain_d, sizeof(f_char_t), (void **) &buffer->string, &buffer->used, &buffer->size);
+
+      if (F_status_is_error(*status)) {
+        kt_tacocat_print_error_on(&main->program.error, macro_kt_tacocat_f(f_memory_array_resize), kt_tacocat_receive_s, *name, *status);
+      }
+    }
   }
 #endif // _di_kt_tacocat_receive_process_
 
index 1ab90d16df4acdccb619b865619bc3137dbbc62a..000e9840a554436a83508596a70e52c115064009 100644 (file)
@@ -39,6 +39,9 @@ extern "C" {
  *
  *   This alters main.setting.state.status:
  *     F_okay on success.
+ *
+ *     F_packet_too_large (with error bit) on total packet size is too large.
+ *     F_payload_too_large (with error bit) on total payload size is too large.
  * @param index
  *   The position within the receive arrays to process.
  *