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.
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.
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);
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]);
* - 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.
* 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.
* - 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_
/**
* - 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.
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_
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,
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_
/**
#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);
#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);
* 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;
* 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;
/**
* 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.
*/
#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;
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, \
* 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.
typedef struct {
uint64_t flag;
uint64_t interval;
+ f_number_unsigned_t max_buffer;
f_status_t status_receive;
f_status_t status_send;
#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, \
}
#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) {
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);
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);
#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
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);
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;
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"
#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
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];
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)) {
// 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_
*
* 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.
*