Merge pull request #305 from mrd0ll4r/doc-frontend
docs: add frontend documentation
This commit is contained in:
commit
22c42f9ec3
1 changed files with 108 additions and 0 deletions
108
docs/frontend.md
Normal file
108
docs/frontend.md
Normal file
|
@ -0,0 +1,108 @@
|
|||
# Frontends
|
||||
|
||||
A _Frontend_ is a component of Chihaya that serves a BitTorrent tracker on one protocol.
|
||||
The frontend accepts, parses and sanitizes requests, passes them to the _Logic_ and writes responses to _Clients_.
|
||||
|
||||
This documentation first gives a high-level overview of Frontends and later goes into implementation specifics.
|
||||
Users of Chihaya are expected to just read the first part - developers should read both.
|
||||
|
||||
## Functionality
|
||||
|
||||
A Frontend serves one protocol, for example HTTP ([BEP 3]) or UDP ([BEP 15]).
|
||||
It listens for requests and usually answers each of them with one response, a basic overview of the control flow is:
|
||||
|
||||
1. Read the request.
|
||||
2. Parse the request.
|
||||
3. Have the Logic handle the request. This calls a series of `PreHooks`.
|
||||
4. Send a response to the Client.
|
||||
5. Process the request and response through `PostHooks`.
|
||||
|
||||
## Available Frontends
|
||||
|
||||
Chihaya ships with frontends for HTTP(S) and UDP.
|
||||
The HTTP frontend uses Go's `http` package.
|
||||
The UDP frontend implements [opentracker-style] IPv6, contrary to the specification in [BEP 15].
|
||||
|
||||
## Implementing a Frontend
|
||||
|
||||
This part is intended for developers.
|
||||
|
||||
### Implementation Specifics
|
||||
|
||||
A frontend should serve only one protocol.
|
||||
It may serve that protocol on multiple transports or networks, if applicable.
|
||||
An example of that is the `http` Frontend, operating both on HTTP and HTTPS.
|
||||
|
||||
The typical control flow of handling announces, in more detail, is:
|
||||
|
||||
1. Read the request.
|
||||
2. Parse the request, if invalid go to 9.
|
||||
3. Validate/sanitize the request, if invalid go to 9.
|
||||
4. If the request is protocol-specific, handle, respond, and go to 8.
|
||||
5. Pass the request to the `TrackerLogic`'s `HandleAnnounce` or `HandleScrape` method, if an error is returned go to 9.
|
||||
6. Send the response to the Client.
|
||||
7. Pass the request and response to the `TrackerLogic`'s `AfterAnnounce` or `AfterScrape` method.
|
||||
8. Finish, accept next request.
|
||||
9. For invalid requests or errors during processing: Send an error response to the client.
|
||||
This step may be skipped for suspected denial-of-service attacks.
|
||||
The error response may contain information about the cause of the error.
|
||||
Only errors where the Client is at fault should be explained, internal server errors should be returned without explanation.
|
||||
Then finish, and accept the next request.
|
||||
|
||||
#### Configuration
|
||||
|
||||
The frontend must be configurable using a single, exported struct.
|
||||
The struct must have YAML annotations.
|
||||
The struct must implement `log.Fielder` to be logged on startup.
|
||||
|
||||
#### Metrics
|
||||
|
||||
Frontends may provide runtime metrics, such as the number of requests or their duration.
|
||||
Metrics must be reported using [Prometheus].
|
||||
|
||||
A frontend should provide at least the following metrics:
|
||||
- The number of valid and invalid requests handled
|
||||
- The average time it takes to handle a single request.
|
||||
This request timing should be made optional using a config entry.
|
||||
|
||||
Requests should be separated by type, i.e. Scrapes, Announces, and other protocol-specific requests.
|
||||
If the frontend serves multiple transports or networks, metrics for them should be separable.
|
||||
|
||||
It is recommended to publish one Prometheus `HistogramVec` with:
|
||||
- A name like `chihaya_PROTOCOL_response_duration_milliseconds`
|
||||
- A value holding the duration in milliseconds of the reported request
|
||||
- Labels for:
|
||||
- `action` (= `announce`, `scrape`, ...)
|
||||
- `address_family` (= `Unknown`, `IPv4`, `IPv6`, ...), if applicable
|
||||
- `error` (= A textual representation of the error encountered during processing.)
|
||||
Because `error` is expected to hold the textual representation of any error that occurred during the request, great care must be taken to ensure all error messages are static.
|
||||
`error` must not contain any information directly taken from the request, e.g. the value of an invalid parameter.
|
||||
This would cause this dimension of prometheus to explode, which slows down prometheus clients and reporters.
|
||||
|
||||
#### Error Handling
|
||||
|
||||
Frontends should return `bittorrent.ClientError`s to the Client.
|
||||
Frontends must not return errors that are not a `bittorrent.ClientError` to the Client.
|
||||
A message like `internal server error` should be used instead.
|
||||
|
||||
#### Request Sanitization
|
||||
|
||||
The `TrackerLogic` expects sanitized requests in order to function properly.
|
||||
|
||||
The `bittorrent` package provides the `SanitizeAnnounce` and `SanitizeScrape` functions to sanitize Announces and Scrapes, respectively.
|
||||
This is the minimal required sanitization, every `AnnounceRequest` and `ScrapeRequest` must be sanitized this way.
|
||||
|
||||
Note that the `AnnounceRequest` struct contains booleans of the form `XProvided`, where `X` denotes an optional parameter of the BitTorrent protocol.
|
||||
These should be set according to the values received by the Client.
|
||||
|
||||
#### Contexts
|
||||
|
||||
All methods of the `TrackerLogic` interface expect a `context.Context` as a parameter.
|
||||
After a request is handled by `HandleAnnounce` without errors, the populated context returned must be used to call `AfterAnnounce`.
|
||||
The same applies to Scrapes.
|
||||
This way, a PreHook can communicate with a PostHook by setting a context value.
|
||||
|
||||
[BEP 3]: http://bittorrent.org/beps/bep_0003.html
|
||||
[BEP 15]: http://bittorrent.org/beps/bep_0015.html
|
||||
[Prometheus]: https://prometheus.io/
|
||||
[opentracker-style]: http://opentracker.blog.h3q.com/2007/12/28/the-ipv6-situation/
|
Loading…
Reference in a new issue