Kevin Day [Tue, 20 Feb 2024 04:39:13 +0000 (22:39 -0600)]
Update: Get clang working by separating out gcc specific settings, such as -fstrict-flex-arrays=3, and related changes.
The "-fstrict-flex-arrays=3" flag is not supported by clang.
Create a new mode call "gcc", make that the default, and move the "-fstrict-flex-arrays=3" into the gcc-specific setting.
Update the unit tests and mocks with these changes.
Make the unit tests and mocks more consistent by having these same settings.
Add a missing period at the end of the clang specific mode documentation comment.
The example bootstrap script handling of threads is improved.
Kevin Day [Sat, 17 Feb 2024 22:10:28 +0000 (16:10 -0600)]
Update: Finish refactoring firewall from 0.6.x to 0.7.x/0.8.x.
I have tested this out and compared the show results between the 0.6.x version and the 0.7.x version to confirm consistent results.
From this point forward problems are to be up for consideration as possible regressions.
Separate out more of the functions into separate files.
I reviewed the header includes and removed the headers that do not have apparent direct use.
Kevin Day [Fri, 16 Feb 2024 05:56:20 +0000 (23:56 -0600)]
Progress: Continue refactoring firewall from 0.6.x to 0.7.x/0.8.x.
This gets the programming compiling.
There still remains some code to change.
The runtime needs to be tested.
I expect that there are things wrong given how much I jumped around while migrating this.
Kevin Day [Thu, 15 Feb 2024 04:28:10 +0000 (22:28 -0600)]
Cleanup: Switch from _ui_ format string to _un_ format string to match the print format arguments.
The _un_ format string is provided to directly match '%un' which is intended to directly match f_number_unsigned_t.
This is intended to make things easier (and safer) to hack.
That is, changing the data size of f_number_unsigned_t.
The _ul_ format string is specifically intended to be an unsigned long, period.
Kevin Day [Thu, 15 Feb 2024 04:25:53 +0000 (22:25 -0600)]
Progress: Continue refactoring firewall from 0.6.x to 0.7.x/0.8.x.
This is very close to be ready for review and testing.
I converted most of the buffers into the new structure but I need to check for isolation.
I am pretty sure that there are currently some isolation problems with the FSS Object and Content ranges.
I also noticed some typos and such that will need to be fixed (this therefore probably does not compile just yet).
Kevin Day [Sun, 11 Feb 2024 04:14:23 +0000 (22:14 -0600)]
Progress: Refactoring firewall from 0.6.x to 0.7.x/0.8.x and other FLL project wide changes.
Add the f_console_parameter_state_type_total_d and update all programs.
Add (and use) additional f_string_format strings.
Add fll_program_print_help_operations().
Add fll_program_print_help_special_options().
Begin using more helper flags for common behavior, such as "main_flag_version_copyright_help" type of flags.
Add missing documentation comments for some functions.
Remove duplicate "#ifdef __cplusplus" blocks in several programs.
Begin to refactoring firewall to follow the 0.7.x and eventually 0.8.x project design.
The firewall program is far from ready and will not yet compile.
Kevin Day [Fri, 9 Feb 2024 05:10:34 +0000 (23:10 -0600)]
Update: Use typedef on a structure tag to avoid the need for void pointer on the callback for f_state_t.
Using a typedef on the structure tag allows for having the structure reference itself.
In this case, the callback that is part of the structure accepts its own structure as one of the callback parameters.
I previously did not know that I could do this and opted to use a void pointer to provide this.
With this approach I get more safety, integrity, and less memory usage (for not having to add a variable that is a cast of the void pointer to the f_state_t).
Kevin Day [Fri, 9 Feb 2024 04:34:55 +0000 (22:34 -0600)]
Feature: Add _f_memory_USE_reallocarray_ and _f_memory_NO_zeroing_on_larger_ macros.
The _f_memory_USE_reallocarray_ designates to use reallocarray() rather than realloc() in the f_memory project.
The _f_memory_NO_zeroing_on_larger_ designates to not perform the memset() to 0 for malloc() or realloc() calls where the new size is larger than the old size.
The programs provided by this project might expect the memory to be zeroed.
Please use _f_memory_NO_zeroing_on_larger_ carefully.
Kevin Day [Fri, 9 Feb 2024 03:55:08 +0000 (21:55 -0600)]
Update: Add restrict optimization to f_memory functions.
The design of the memory operations require that array, used, and size do not point to the same memory address.
Help prevent potential aliasing by adding restrict keyword.
The functions with only a single pointer in its parameters still has the restrict keyword added.
I opted to avoid adding the restrict keyword to some of the append and append all functions.
Those would require more attention before I am certain whether or not they should be allowed to have overlapping addresses.
I think they should not, but just in case, I put doing that on hold.
The callback could also use restrict but I have decided not to do that as well due to the number of files that I will need to change.
I will do this later.
Kevin Day [Fri, 9 Feb 2024 03:24:54 +0000 (21:24 -0600)]
Progress: Begin adding unit tests for fl_fss_payload_header_map().
I added the single digit unit tests for signed and unsigned.
I started to add uint8_t with the test files but then I realized that I actually should implement uint8s_t.
I am leaving those test files currently but I will change them at a later date.
This adds a helper file for the payload header map private functions to simplify some of the code.
Kevin Day [Sun, 4 Feb 2024 23:34:53 +0000 (17:34 -0600)]
Progress: Wrap up initial pass of fl_fss_payload_header_map().
Everything for the fl_fss_payload_header_map() function is written.
I can guarantee that there is some logic error or mistake somewhere due to the codestorming practice that I did with this (in addition to doing it across multiple weeks).
I experimented with different approaches in the different private functions.
I will eventually follow up this with a clean up pass that add functions to reduce the redundant code and also standardize the logic implementations where reasonable.
My next task in regards to this function will be to write unit tests.
This will find the problems and I will use the unit tests to kick off the rewrite of the private functions.
Kevin Day [Sat, 3 Feb 2024 23:45:31 +0000 (17:45 -0600)]
Refactor: The f_string_quantity_t into f_quantity_t.
This makes the f_string_quantity_t consistent similar to how f_string_range_t was refactored into f_range_t.
This is done because there is no actual string value in f_string_quantity_t.
There are only numeric values.
Kevin Day [Sat, 3 Feb 2024 23:43:53 +0000 (17:43 -0600)]
Bugfix: Runtime tests have incorrect space for "not a comment" line tests.
I overlooked a bug when I generated these files.
Now that the bug has recently been fixed, the unit tests are failing as they should.
Fix the incorrect tests so that they pass and fail correctly by fixing the "expect" relevant files.
Kevin Day [Fri, 2 Feb 2024 04:26:16 +0000 (22:26 -0600)]
Progress: Continue working on fl_fss_payload_header_map().
Mostly focus on private_fl_payload_header_map_maps().
There is a lot of similar code design with subtle but key differences.
This is going to be really easy to make an mistake with.
Writing unit tests is going to be the ideal way to ensure the logic here is correct.
I did a lot of back and forth jumping around while trying to remember where I was last and what I need to do.
Make the build settings files more consistent in regards to threads and coverage modes.
Kevin Day [Thu, 1 Feb 2024 05:29:57 +0000 (23:29 -0600)]
Update: Add hopefully more secure compiler flags by default.
Use the "-Wl" for specifying the linker flags.
- Make sure "now", "relro", and "nodlopen" are set.
Add FORTIFY_SOURCE set to 3.
Add stack-clash-protection and strict-flex-arrays set to 3.
This project is designed around NULL checks.
- Make sure the no-delete-null-pointer-checks flag is set to prevent the compiler from removing these security/integrity checks.
Use stack-protector-strong rather than stack-protector for test flags.
- Future versions may enable stack-protector-strong by default for regular compiling.
Kevin Day [Wed, 31 Jan 2024 05:39:26 +0000 (23:39 -0600)]
Bugfix: FSS Basic List and FSS Extended List print comment at the start of the Content.
When the Content exists at the start of the Content, the comment character ('#') is printed when it should not be printed.
This is a bug where the code initializes the newline_last at the range.start.
The code logic then always expects the newline_last to represent an actual new line.
This is not necessarily the case for when newline_last is pointing to the initial range.start position.
Add a check when processing a comment to ensure that the newline_last is in fact a new line.
Restructure the not used checks to a single location to make reading the code easier.
Make sure to only increment the line on empty Content when the empty Content flag is set.
Kevin Day [Sun, 28 Jan 2024 06:32:13 +0000 (00:32 -0600)]
Progress: Improve FSS program processing and fix related bugs.
Clean up the logic in the fll_fss functions, removing redundant code.
Improve handling of F_fss_found_object_content_not cases in a more consistent manner.
Improve logic of the fll_fss payload functions.
Remove dead code that does nothing.
Have the payload processing properly determine and communicate when the "payload" section is missing.
Update the documentation comments.
Improve the FSS read programs relating to the above changes.
Fix problems in the FSS read programs where sometimes the EOL string is directly printed rather than calling the appropriate object/content end callbacks.
The callbacks handle the uses cases for when the pipe is used but the direct EOL string printing does not.
Rename the FSS read progams print functions to have the "data", "message", "error", and such practice be more consistently followed.
This fixes several of the problems in the FSS Read programs where the "-e/--empty" parameter is not being properly respected in many cases.
I am not sure I got all of the situations and the logic from all of the changes that I made needs some review.
For the FSS payload read program, add a new special parameter called "--payload".
This allows giving the user more control over how to handle the cases where the payload section does not exist.
Specifically, there is a payload "create" mode that allows for ensuring that the "payload" section always exists.
This should ideally help make scripting simpler and therefore easier.
The parameters must be re-processed once the '-A" is passed for the fss_read combined program.
I added a print_content_empty callback and then commented it out in this commit.
This seems like it would be practical to have but I am not certain any FSS specification would need this at this time.
Further investigation is needed in this regard.
Add some more TODO and FIXME comments so that when I come back to this code and can better resume where I left off.
The following Content should now be returned:
[0] = "
[1] = b
[2] = c
[3] = d.
This adds a new FSS state flag 'f_fss_state_quote_not_e' to give the caller the ability to manually designate that the quotes are being disabled.
Currently only the FSS Extended utilizes this flag.
Refactor the private function private_fl_fss_basic_read() into private_fl_fss_basic_or_extended_read() to make it more explicitly clear that it provides functionality fo both FSS Basic and FSS Extended.
This changes to the code such that when an unterminated quote is detected then the calling function will set the disable quote flag and then call the function again.
Writing these unit tests exposed some bugs, such as:
- The one solve in commit ba257a8b8385ec8dedfc9bc9bb596e420ca552f8.
- The FSS extended read is not handling unterminated single quote correctly.
An unterminated single quote in an extended requires that the quotes be treated as normal text, as per the standard.
This means that the quote should be broken up into unquoted content.
This is not the case and is considered a bug.
For example, consider the following line:
a " b c d.
That line is currently being interpreted by extended read as a single content called:
[0] = " b c d.
Instead, this should end up being 4 contents:
[0] = "
[1] = b
[2] = c
[3] = d.
The unit tests files that I created here should expect this and therefore the extended read tests currently fail.
I am also adding the basic list tests but I did not get to implementing the basic list content read tests yet.
The test data files exist but I need to review them and write the appropriate code.
The extended list and the embedded list tests are not yet written.
Kevin Day [Wed, 24 Jan 2024 05:54:07 +0000 (23:54 -0600)]
Bugfix: Incorrect stop position is calculated when FSS content ends at the start position on FSS read operations.
When the start position is say, 0, and the determined stop position ends up being 0, then an incorrect stop range is calculated.
This happens because the stop position is subtracting one from the current position.
Add checks to ensure that the stop position is never subtracted beyond the initial start position.
The initial start position is saved at the beginning of each affected FSS read function.
This now potentially returns a start range before the stop range.
The FSS read programs should also need to be updated following this commit to handle these cases.
Kevin Day [Tue, 23 Jan 2024 03:42:07 +0000 (21:42 -0600)]
Progress: Add "works" unit test for basic object read and basic content read.
My goal is to get to writing the payload tests but getting these other unit tests figured out first will make that process easier.
These "works" unit tests are intended to be very simple at this time.
There are no checks for comments.
The NULL data is not checked, partially due to the use of getline() and string comparison.
This also adds the beginnings of unit tests for the fl_fss project, specifically for the fl_fss_payload_header_map() function.
The tests for fl_fss_payload_header_map() will be rather complex and so I will likely break the tests for fl_fss_payload_header_map() into multiple files.
Kevin Day [Fri, 19 Jan 2024 03:08:51 +0000 (21:08 -0600)]
Cleanup: Invalid environment define "CMOCKA_TEST_ABORT" in testfiles.
This invalid configuration doesn't break anything unless someone uncomments it.
Then, the expected functionality does not happen.
The fix is easy, just add "define " at the start of that line to the right of the comment character.
Kevin Day [Thu, 18 Jan 2024 02:49:00 +0000 (20:49 -0600)]
Bugfix: Function private_fl_fss_basic_write() is missing "const".
The function implementations for private_fl_fss_basic_write() is missing the "const" type attribute in some parameters.
The declaration of these has the "const" type attribute as expected.
I did a lot of cleaning up and reorganization.
This adds a several flags that I intended to use but the current state of these is highly subject to change.
There are still a lot of incomplete changes, especially regarding existing code and the newly added flags.
Kevin Day [Tue, 16 Jan 2024 14:22:03 +0000 (08:22 -0600)]
Feature: Add f_string_dynamic_strip_null() and f_string_dynamic_strip_null_range().
The ability to strip out NULLs from a given string as a common function is needed.
Provide two similar but different functions.
The f_string_dynamic_strip_null() moves the NULLs to the end of the string and the shrinks the string used length as appropriate.
The f_string_dynamic_strip_null_range() shifts all of the NULLs found to the end of the given range without modifying the array used length.
Unit tests are added.
Only basic logic is applied and so there is no especially focused optimization in the parsing logic.
Kevin Day [Mon, 15 Jan 2024 18:34:10 +0000 (12:34 -0600)]
Refactor: The backtick into the grave.
Both the Unicode standard uses the word "grave" rather than the word "backtick" to commonly refer to the U+0060 character.
Change the use of the word from backtick to the word grave throughout the project.
This is a breaking change for the relevant programs, such as fss_write and iki_write.
Documentation, such as the website documentation and specifications, will need to be updated following this change.
Kevin Day [Mon, 15 Jan 2024 03:18:46 +0000 (21:18 -0600)]
Progress: Make control program at least compile.
I just did some quick tests and getting the control program to compile is just this simple change.
I believe there are still several programs, like the control program, that still need to be migrated from the 0.6 style to the 0.7 style.
Kevin Day [Mon, 15 Jan 2024 03:13:47 +0000 (21:13 -0600)]
Update: Switch to using the common format string structure where possible.
There may be other cases, but these are the ones I was able to quickly find.
After glancing over this I would also note that the common parameter argument printing could also be made common strings.
These would be common strings that are specific to something like fll_program.
Kevin Day [Sun, 31 Dec 2023 02:33:20 +0000 (20:33 -0600)]
Update: Explicitly cast UTF conversion to/from and simple packet bit operations to a uint32_t.
If the type is changed or the defines are used with different types, then the shift operators may become problematic.
Prevent this potential problem from happening through explicit casts to uint32_t.
Kevin Day [Sat, 16 Dec 2023 01:37:50 +0000 (19:37 -0600)]
Bugfix: Fix incorrect wording regarding negative times and add some clarification regarding defaults.
The time specification is mistakenly using the word "after" when it should be the word "before" for the example "2022:-5".
I decided that I needed to better clarify what I meant by default and not make it sound so strict.
Add additional language to better communicate that when the year is not specified, it is not specified.
There is no required interpretation and a default is simply a recommendation.
I am going to start trying to establish a habit of using UTC for my timestamps.
My local time zone, the date of the specification is still the 15 of December, 2023.
However, to stick with UTC for records purpose I need to the start doing this now.
There may be occasional inconsistencies for a while until I establish the habit of using UTC.
Kevin Day [Thu, 14 Dec 2023 02:27:54 +0000 (20:27 -0600)]
Refactor: The fss extract functions to be fss decode functions.
The commit 4713c80244fe1bc00da097eb27987e77c98601f0 introduced f_fss_simple_packet_encode().
Rename the f_fss_simple_packet_extract() and similar functions to f_fss_simple_packet_decode().
This makes the language more consistent between the two different functions.
Kevin Day [Tue, 12 Dec 2023 02:18:03 +0000 (20:18 -0600)]
Update: Strip NULLs from the payload number converters.
Add logic to strip the NULLs from the numbers.
The FSS functions use NULLs to reduce reallocations but the payload sends everything.
Don't introduce unexpected NULLs when writing the numbers.
I need to review the logic for any mistakes which I find is often best after sleeping on it.
Even better, I should write some unit tests to expose any potential logic flaws more easily.
Kevin Day [Mon, 11 Dec 2023 06:26:27 +0000 (00:26 -0600)]
Update: Socket size_read/size_write checks, result == -1, and explicit passing .generic.
Make sure size_read and size_write are not 0.
If either is 0, then return F_data_not.
Make sure the result checks are "== -1" rather than "< 0".
Explicitly pass .generic for the address union.
This probably isn't necessary but being explicit seems safer.
The memory address of the address union, regardless of the union type being used, is cast to 'struct sockaddr' in most cases.
This makes the use of ".generic" very practical.
Add documentation comment about F_pipe being returned.
Problems with the address unions ".sin_family" must be set or unclear F_pipe errors are returned.
I may in a future commit perform this assignment during setup because the "form" parameter makes this practical and reasonable to do.
Kevin Day [Fri, 8 Dec 2023 04:46:53 +0000 (22:46 -0600)]
Update: Re-design f_socket to better support handling of different struct sockaddr types.
The networking types are already in use, such as address family (AF_*) and protocol family (PF_*).
The known and supported socket address structures (struct sockaddr) do not directly relate to either.
Create a new enumeration that directly maps to these socket address structures (struct sockaddr), called an address form.
A 16-bit integer is hopefully more than is ever needed for this.
Rewrite f_socket_bind() and f_socket_connect() to use the socket.form enumeration.
The custom *_inet4(), *_inet6(), and *_local() functions are removed.
Add a generic, or fallback aka failsafe, type for handling the most basic socket address tructure (struct sockaddr).
Kevin Day [Fri, 8 Dec 2023 02:28:02 +0000 (20:28 -0600)]
Update: The fss-000e (Payload) specification should allow for the "payload" Section to be optional.
In cases where packets that are being sent only need to send the "header", then it makes sense to not have a "payload" Section.
This should help reduce network traffic by avoiding the extra "payload:\n" characters when the payload Section is to be ignored.
Add additional tests.
Fix bad test data, such as where the string lengths are incorrect.
Perform tests when "where" parameter both is NULL or is a valid pointer.
The tests now handle validating the "where" parameter, when specified.
Add additional comments to better communicate the logic in f_network_is_ip_address().
Properly handle the "where" parameter assignment.
Kevin Day [Mon, 4 Dec 2023 04:13:06 +0000 (22:13 -0600)]
Update: Unit tests for f_network().
The commit 309f2625e983ef164c52543b492365fe92eed6d5 did not update the unit tests.
The tests currently do not pass due to a regression that will be addressed in a follow up commit.
The referenced commit was rushed so that I could get to the f_string_range_t and related migration.
I didn't bother to review the code or run the unit tests.
I will now have to follow up with a more extensive review and fix any problems.
The unit tests need to also be updated to handle all of the new behavior of the changed function.
Kevin Day [Mon, 4 Dec 2023 01:50:55 +0000 (19:50 -0600)]
Update: The f_network_is_ip_address() to use f_string_range_double_t (soon to be f_range_double_t).
This allows for getting both the address and port range positions.
The POSIX/libc functions do not support the bracket notation in an IPV6 address.
The string detected by this must then have the brackets filtered out.
This new structure allows for saving the range.
I did a quick run-through write-up of the logic for these changes but I have not spent any time reviewing or testing the logic.
Hopefully there are not logic bugs or mistakes.
Kevin Day [Mon, 4 Dec 2023 01:43:11 +0000 (19:43 -0600)]
Feature: Add f_string_range_double_t, updating build settings and unit tests appropriately.
I need a string range structure that has two ranges for some given string for the network related code.
The unit tests are updated or added as appropriate.
Any bugs discovered in the related unit tests are fixed.
The build data is rebuilt.
I originally wrote f_string_range_t to be specific to strings.
I now think that this needs to be conceptually more generalized.
The purpose of such a generalization is to simplify the code logic and design.
Renaming f_string_range_t to f_range_t and now renaming f_string_range_double_t into f_range_double_t is the intended change.
This would then be moved out of the f_string project and into the f_type project.
This is too much to do in the scope of this commit.
Instead, the f_string_range_double_t is being added under f_string_range_double_t.
I will then follow up this commit with a refactor of the f_string_range_t and f_string_range_double_t.
Kevin Day [Thu, 30 Nov 2023 03:01:02 +0000 (21:01 -0600)]
Bugfix: f_network_from_ip_string() and f_network_to_ip_string() design problems.
Change the inet_pton() and inet_ntop() function calls to use the explicit .v4 and .v6 union members.
Being explicit is much safer.
The inet_pton() function also returns zero without the errno set when the address is invalid.
Handle this case, returning F_address_not (with error bit) when zero is returned by inet_pton().
The unit tests for these functions are incorrect and are not all called (which is why their incorrectness was not previously discovered).
Make sure to use h_errno where appropriate.
Make sure the mock function for inet_pton() allows for returning zero or non-zero.
Make sure the family type is set so that the expected return codes are returned.
Make sure the ip string is set so that the expected return codes are returned.
Handle the newly added F_address_not case.
Add the missing unit test function calls:
- test__f_network_from_ip_address__fails
- test__f_network_from_ip_name__fails
- test__f_network_from_ip_string__fails
- test__f_network_to_ip_string__fails
This could use more review and testing.
Such extra review will be performed while I continue to write TacocaT.
Kevin Day [Thu, 30 Nov 2023 02:57:43 +0000 (20:57 -0600)]
Bugfix: f_socket_connect() should require non-negative socket.id.
I seem to have this one backwards.
The socket.id must be something other than -1.
If the socket.id is -1, then just return F_file_descriptor without error bit to designate that no descriptor is available to connect with.
Kevin Day [Tue, 14 Nov 2023 23:56:43 +0000 (17:56 -0600)]
Update: Specifications for Payload and Simple Packet.
Add "type" as a recommended Object in the header section for the Payload.
Change the size units being used in Simple Packet.
The numbers used in some areas are completely wrong 2^4 is not 32-bits.
Instead use the word "bytes" or "bits" and update the units.
The Payload Block Structure uses "bytes" rather than bits as that is the general focus of that section.
All others use "bits".
Kevin Day [Wed, 1 Nov 2023 02:58:58 +0000 (21:58 -0500)]
Progress: Resume working on custom payload functions.
I'm getting more back into things and this is a small step towards pickup up where I left off.
There are several todos that I will consider and either implement or not.
This performs the work that I mentioned in the previous commit in regards to redesigning the approach in fl_fss_payload_header_write() (now called fl_fss_payload_header_map()).
I started doing some re-designing to improve the approach and prepare for signatures/checksums.
I realized somewhere during that process that I wanted to eventually control or even randomize the header order for integrity, organization, or security reasons.
The current approach makes that impractical.
I decided to save the current state so that I can then pivot to a better approach that will accommodate the above needs.
Appropriate todo notes are added to this end.
A lot of the existing payload code will be re-designed, again, as a result of this.
I decided to use two caches.
One for the main cache.
The other for a smaller, multi-purpose cache.
The second cache should be smaller and so re-allocations should be cheaper.
Use re-allocations on this as much as possible.
There are some code changes that I was indecisive around and jumped around on implementation.
I think I cleaned that all up but I may have missed something.
Kevin Day [Thu, 5 Oct 2023 04:19:44 +0000 (23:19 -0500)]
Progress: Begin adding FSS Payload processing code.
This will use the f_abstruse project.
This is very incomplete and is mostly drafted out.
Update the Featureless Make stand alone build with the latest changes.
Apply the related cleanups from 4ced1b0ba41334ce94d0a9b511b363a6031da136 (Cleanup: Have enumeration types support "none" and have the "// enum" comment at the end.).
Kevin Day [Thu, 5 Oct 2023 03:11:38 +0000 (22:11 -0500)]
Update: Simplify the f_abstruse types a little.
Being a union, the single valued integer types provide very little gain and introduce a cost in complexity.
Remove the integer types that overlap and just stick with the f_number_signed_t and f_number_unsigned_t for single value number types.
Multiple valued number types remain because there is potential for design differences due to the memory allocation and size differences.
The f_char_t type is removed.
Just stick with f_string_t.
Provide an optional "signature" Object and associated Content rules to the specification.
This better separates defining how the "header" and "payload" can be signed or have checksums applied.
The actual rules are left rather vague and flexible for implementation specific decisions.
A suggested strategy for using the "signature" is provided within the example.