<commit_before># General Design decisions
- Queries are answered as soon as any queried information is available, i.e. a server does not wait
  until it can completely answer a query but already responds with partial information.
- A server should keep all public keys necessary to validate the signatures on all its cached
  sections. This allows the server to answer all delegation queries about sections it has sent out.
- A server should respond to a delegation query with all matching public keys it believes the
  querier is missing to check a signature. A server does not keep state which delegations it has
  already sent to another server.
- After a configurable maximum number of delegation queries (e.g. 2) sent to the server from which
  this server received the message and not leading to all needed public keys, the server sends a
  delegation query to a predefined 'backup' server. If no 'backup' server is defined, the section
  will be dropped. Otherwise this server tries until the entry expires.
- A server should log all incoming messages and their content such that an external service can
  blacklist zones or IP addresses based on it and additional information.
- Pointers to delegation assertions are stored in the assertion cache to answer received delegation
  queries as well as in the zone key cache which is internally used to lookup public keys.
- It must be possible to update peer and zone blacklists at runtime such that an external service or
  coprocess analyzing rainsd's logging in real time can defend misbehavior and attacks (e.g. DoS)
- It must be possible to configure a server such that it does only iterative lookups for a specified
  list of addresses.
- It must be possible to configure a server to which other server address(es) it sends recursive
  queries. If there are several specified it chooses one according to a policy (random, round-robin,
  etc.)
- If no server address(es) is configured for iterative or recursive lookup, then the server just
  forwards redirect assertions back to the querier. In case the query was issued by the server
  itself it directly drops the redirect assertion (and in case of a delegation query, the section(s)
  waiting for the public key)

# Coalescing and/or splitting of incoming messages
- An answer to a query can arrive as a whole or in a fragmented way. Possible scenarios are:
  1. one message, one section
  2. one message, multiple section
  3. several messages, each with one section
  4. several messages with several section
  The server must be able to handle all these cases in a meaningful way. It should be possible to
  configure the server to react in different ways to them.

## Proposals
1. The server processes all incoming information directly and solely on a per section basis, i.e. if
   a message contains several sections it splits them up and handles each of them separately and in
   parallel. The number of simultaneously active goroutines is upper bounded. Assertions in response
   to a delegation queries can be configured to be handled with priority.
- Pending query cache designs:
  1. As soon as the server processes the first section which is an answer to a query it forwards the
     section and removes the entry from the pending query cache. (Disadvantages: If a server/client
     is interested in several information it should issue for each of them a separate query
     otherwise it might get always the same answer. Delegation must be handled as a special case)
  2. When an answer to a pending query arrives (either by token or by name, ctx and type) it is
     stored to the entry in the pending query cache and a configurable wait-time is set/reset after
     which all so far gathered sections are sent back together as the response and the entry is
     removed from the pending query cache. (Disadvantage: complicated pending query cache)
  3. The entry in the pending query cache is only removed when expired. All answers arriving before
     the expiration are cached and then sent back to the sender. (Disadvantages: high delay and if
     the server decides to not cache a section then it can also not be used as an answer except if
     we would store each answering section to the pending query cache)
- Pending key cache:
  - A server can only resend a delegation query when the previous one has expired. This assures that
    a server does not get flooded with delegation queries after it rolled over a key.
  - All arriving delegation assertions are checked if they answers any of the sections in the
    pending key cache (hashmap lookup by zone, context, algorithm type and phase ID).
  - If the token on a message matches one in the pending key cache then the sections of this message
    are handled with priority (if not disabled in configuration).
  - There is a hashmap in the cache which is keyed by the token and the value is an object
    containing an expiration time and a pointer to an object containing all sections waiting for a
    public key. An entry is only removed from this hashmap if it has expired (a reap function takes
    care of this). This ensures that all messages in response to a delegation query are handled with
    priority.
  - Active Token cache is now part of the pending key cache because it is necessary to have a
    pointer from the token to the pending sections to remove them without raising an alarm in case
    the other server has sent a notification in response to the delegation query.
  - The server must log every section that gets dropped together with the destination which failed
    to send a delegation assertion in time.<commit_msg>pending cache design for proposal one more detail<commit_after># General Design decisions
- Queries are answered as soon as any queried information is available, i.e. a server does not wait
  until it can completely answer a query but already responds with partial information.
- A server should keep all public keys necessary to validate the signatures on all its cached
  sections. This allows the server to answer all delegation queries about sections it has sent out.
- A server should respond to a delegation query with all matching public keys it believes the
  querier is missing to check a signature. A server does not keep state which delegations it has
  already sent to another server.
- After a configurable maximum number of delegation queries (e.g. 2) sent to the server from which
  this server received the message and not leading to all needed public keys, the server sends a
  delegation query to a predefined 'backup' server. If no 'backup' server is defined, the section
  will be dropped. Otherwise this server tries until the entry expires.
- A server should log all incoming messages and their content such that an external service can
  blacklist zones or IP addresses based on it and additional information.
- Pointers to delegation assertions are stored in the assertion cache to answer received delegation
  queries as well as in the zone key cache which is internally used to lookup public keys.
- It must be possible to update peer and zone blacklists at runtime such that an external service or
  coprocess analyzing rainsd's logging in real time can defend misbehavior and attacks (e.g. DoS)
- It must be possible to configure a server such that it does only iterative lookups for a specified
  list of addresses.
- It must be possible to configure a server to which other server address(es) it sends recursive
  queries. If there are several specified it chooses one according to a policy (random, round-robin,
  etc.)
- If no server address(es) is configured for iterative or recursive lookup, then the server just
  forwards redirect assertions back to the querier. In case the query was issued by the server
  itself it directly drops the redirect assertion (and in case of a delegation query, the section(s)
  waiting for the public key)

# Coalescing and/or splitting of incoming messages
- An answer to a query can arrive as a whole or in a fragmented way. Possible scenarios are:
  1. one message, one section
  2. one message, multiple section
  3. several messages, each with one section
  4. several messages with several section
  The server must be able to handle all these cases in a meaningful way. It should be possible to
  configure the server to react in different ways to them.

## Proposals
1. The server processes all incoming information directly and solely on a per section basis, i.e. if
   a message contains several sections it splits them up and handles each of them separately and in
   parallel. The number of simultaneously active goroutines is upper bounded. Assertions in response
   to a delegation queries can be configured to be handled with priority.
- Pending query cache designs:
  1. As soon as the server processes the first section which is an answer to a query it forwards the
     section and removes the entry from the pending query cache. (Disadvantages: If a server/client
     is interested in several information it should issue for each of them a separate query
     otherwise it might get always the same answer. Delegation must be handled as a special case)
  2. When an answer to a pending query arrives (either by token or by name, ctx and type) it is
     stored to the entry in the pending query cache and a configurable wait-time is set/reset after
     which all so far gathered sections are sent back together as the response and the entry is
     removed from the pending query cache. (Disadvantage: complicated pending query cache)
  3. The entry in the pending query cache is only removed when expired. All answers arriving before
     the expiration are cached and then sent back to the sender. (Disadvantages: high delay and if
     the server decides to not cache a section then it can also not be used as an answer except if
     we would store each answering section to the pending query cache)
- Pending key cache:
  - A server can only resend a delegation query when the previous one has expired. This assures that
    a server does not get flooded with delegation queries after it rolled over a key.
  - The server checks if the token of an arriving section is stored in the cache and updates the
    cache accordingly. (In case the response is a redirect, iterative, recursive or no lookup. In
    case of negative proof remove sections and log it)
  - All arriving delegation assertions without a matching token are checked if they answers any of
    the sections in the pending key cache (hashmap lookup by zone, context, algorithm type and phase
    ID). All answered sections are added to the processing queue.
  - If the token on a message matches one in the pending key cache then the sections of this message
    are handled with priority (if not disabled in configuration).
  - There is a hashmap in the cache which is keyed by the token and the value is an object
    containing an expiration time and a pointer to an object containing all sections waiting for a
    public key. An entry is only removed from this hashmap if it has expired (a reap function takes
    care of this). This ensures that all messages in response to a delegation query are handled with
    priority.
  - Active Token cache is now part of the pending key cache because it is necessary to have a
    pointer from the token to the pending sections to remove them without raising an alarm in case
    the other server has sent a notification in response to the delegation query.
  - The server must log every section that gets dropped together with the destination which failed
    to send a delegation assertion in time.
{'fraction_non_alphanumeric': 0.023711340206185566, 'fraction_numerical': 0.0015463917525773195, 'mean_word_length': 3.786595394736842, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2680417', 'n_tokens_mistral': 2650, 'n_tokens_neox': 2561, 'n_words': 1907}