]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
more documentation
authorAlan T. DeKok <aland@freeradius.org>
Tue, 5 Mar 2024 14:43:09 +0000 (09:43 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 5 Mar 2024 14:43:09 +0000 (09:43 -0500)
src/lib/bio/retry.md [new file with mode: 0644]

diff --git a/src/lib/bio/retry.md b/src/lib/bio/retry.md
new file mode 100644 (file)
index 0000000..ade6016
--- /dev/null
@@ -0,0 +1,78 @@
+# The retry bio
+
+The retry bio manages timed retries of requests and responses, using the `fr_retry_t` timers.
+
+As with most bio blocks, the bulk of the work is done via callbacks
+
+## Callbacks
+
+### Sent Callback
+
+On `write()`, the `fr_bio_retry_sent_t` callback is run after the bio
+has sent the packet.  The packet is tracked in an internal data
+structure called `fr_bio_retry_entry_t`.  The `sent` callback passes
+that pointer back to the application, which should cache it in a data
+structure associated with the request.  (Usually the `packet_ctx`).
+
+This pointer can be used to cancel an outgoing packet, or can be
+returned by the `response` callback.
+
+The request is normally tracked in an RB tree or hash table, keyed by
+various fields in the packet header.
+
+### Response callback
+
+On `read()`, the `fr_bio_retry_response_t` callback is run after the bio has
+read a full packet (the next bio should usually be a `mem` bio, with a
+packet verify callback).
+
+The application should use the response packet data to find the
+request usually by looking it up in an RB tree based on packet header.
+Once the request packet has been found, the application should return
+the pointer from the `fr_bio_retry_sent_t` callback.
+
+This process lets the retry bio find not only the request, but the
+internal data needed to do the retries.
+
+Note that the callback should _always_ update the `retry_ctx` pointer,
+even if the packet is a duplicate (the application still has to track
+that itself).  Returning it lets the retry bio track dups.
+
+i.e. if the retry bio sends 4 packets, we likely don't want to clean
+up the `retry_ctx` until we've seen all 4 responses, OR until the
+`maximum_retry_duration` timer has been hit.
+
+### Rewrite Callback
+
+The rewrite callback is run when a timer fires.  When no rewrite
+callback is given, the bio just re-sends the request packet as-is.
+
+If a rewrite callback is given, it is called.  The application can
+then change the packet if necessary (e.g. update Acct-Delay-Time),
+re-encode the packet, etc.  The application should *not* call the
+`fr_bio_write()` routine to send the updated data.  Instead, the
+application should call `fr_bio_retry_rewrite()`, and return that
+value as its return value.
+
+The difference is that a call to the main `fr_bio_write()` routine
+runs through all of the bios, and sets up a _new_ packet to send, with
+_new_ timers.  The `fr_bio_retry_rewrite()` function instead gets
+passed the `retry_ctx`, which lets the retry bio update the timers,
+but without allocating a new retry context for it.
+
+Note that the bio can block during this write.  And also it could
+write a partial packet.  Any partial writes are saved, and cannot be cancelled.
+
+### Release callback
+
+The `release` callback is run when the retry bio has decided to
+release the `retry_ctx` associated with the request.  The application
+should clean up any tracking table associated with the request / response.
+
+## Cancel Function
+
+An outgoing request can be cancelled at any time by calling the cancel
+function, with the `retry_ctx` from the `sent` callback.
+
+The `release` callback will be called when a request packet is cancelled.
+