Name |
Date |
Size |
#Lines |
LOC |
||
---|---|---|---|---|---|---|
.. | - | - | ||||
protocols/smtp/ | 12-May-2024 | - | 729 | 423 | ||
transports/ | 12-May-2024 | - | 950 | 606 | ||
README.md | D | 12-May-2024 | 6.1 KiB | 171 | 128 | |
abstract.c | D | 12-May-2024 | 8.4 KiB | 356 | 211 | |
private-lib-abstract.h | D | 12-May-2024 | 1.9 KiB | 56 | 21 | |
test-sequencer.c | D | 12-May-2024 | 7.2 KiB | 275 | 156 |
README.md
1# Abstract protocols and transports 2 3## Overview 4 5Until now protocol implementations in lws have been done directly 6to the network-related apis inside lws. 7 8In an effort to separate out completely network implementation 9details from protocol specification, lws now supports 10"abstract protocols" and "abstract transports". 11 12 13 14The concept is that the implementation is split into two separate 15chunks of code hidden behind "ops" structs... the "abstract protocol" 16implementation is responsible for the logical protocol operation 17and reads and writes only memory buffers. 18 19The "abstract transport" implementation is responsible for sending 20and receiving buffers on some kind of transport, and again is hidden 21behind a standardized ops struct. 22 23In the system, both the abstract protocols and transports are 24found by their name. 25 26An actual "connection" is created by calling a generic api 27`lws_abs_bind_and_create_instance()` to instantiate the 28combination of a protocol and a transport. 29 30This makes it possible to confidently offer the same protocol on 31completely different transports, eg, like serial, or to wire 32up the protocol implementation to a test jig sending canned 33test vectors and confirming the response at buffer level, without 34any network. The abstract protocol itself has no relationship 35to the transport at all and is completely unchanged by changes 36to the transport. 37 38In addition, generic tokens to control settings in both the 39protocol and the transport are passed in at instantiation-time, 40eg, controlling the IP address targeted by the transport. 41 42lws SMTP client support has been rewritten to use the new scheme, 43and lws provides a raw socket transport built-in. 44 45## Public API 46 47The public api for defining abstract protocols and transports is 48found at 49 50 - [abstract.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/abstract/abstract.h) 51 - [protocols.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/abstract/protocols.h) 52 - [transports.h](https://libwebsockets.org/git/libwebsockets/tree/include/libwebsockets/abstract/transports.h) 53 54### `lws_abs_t` 55 56The main structure that defines the abstraction is `lws_abs_t`, 57this is a name and then pointers to the protocol and transport, 58optional tokens to control both the protocol and transport, 59and pointers to private allocations for both the 60protocol and transport when instantiated. 61 62The transport is selected using 63 64``` 65LWS_VISIBLE LWS_EXTERN const lws_abs_transport_t * 66lws_abs_transport_get_by_name(const char *name); 67``` 68 69and similarly the protocol by 70 71``` 72LWS_VISIBLE LWS_EXTERN const lws_abs_protocol_t * 73lws_abs_protocol_get_by_name(const char *name); 74``` 75 76At the moment only "`raw-skt`" is defined as an lws built-in, athough 77you can also create your own mock transport the same way for creating 78test jigs. 79 80|transport op|meaning| 81|---|---| 82|`tx()`|transmit a buffer| 83|`client_conn()`|start a connection to a peer| 84|`close()`|request to close the connection to a peer| 85|`ask_for_writeable()`|request a `writeable()` callback when tx can be used| 86|`set_timeout()`|set a timeout that will close the connection if reached| 87|`state()`|check if the connection is established and can carry traffic| 88 89These are called by the protocol to get things done and make queries 90through the abstract transport. 91 92|protocol op|meaning| 93|---|---| 94|`accept()`|The peer has accepted the transport connection| 95|`rx()`|The peer has sent us some payload| 96|`writeable()`|The connection to the peer can take more tx| 97|`closed()`|The connection to the peer has closed| 98|`heartbeat()`|Called periodically even when no network events| 99 100These are called by the transport to inform the protocol of events 101and traffic. 102 103### Instantiation 104 105The user fills an lws_abs_t and passes a pointer to it to 106`lws_abs_bind_and_create_instance()` to create an instantiation 107of the protocol + transport. 108 109### `lws_token_map_t` 110 111The abstract protocol has no idea about a network or network addresses 112or ports or whatever... it may not even be hooked up to one. 113 114If the transport it is bound to wants things like that, they are passed 115in using an array of `lws_token_map_t` at instantiation time. 116 117For example this is passed to the raw socket protocol in the smtp client 118minimal example to control where it would connect to: 119 120``` 121static const lws_token_map_t smtp_abs_tokens[] = { 122{ 123 .u = { .value = "127.0.0.1" }, 124 .name_index = LTMI_PEER_DNS_ADDRESS, 125}, { 126 .u = { .lvalue = 25l }, 127 .name_index = LTMI_PEER_PORT, 128}}; 129``` 130 131## Steps for adding new abstract protocols 132 133 - add the public header in `./include/libwebsockets/abstract/protocols/` 134 - add a directory under `./lib/abstract/protocols/` 135 - add your protocol sources in the new directory 136 - in CMakeLists.txt: 137 - add an `LWS_WITH_xxx` for your protocol 138 - search for "using any abstract protocol" and add your `LWS_WITH_xxx` to 139 the if so it also sets `LWS_WITH_ABSTRACT` if any set 140 - add a clause to append your source to SOURCES if `LWS_WITH_xxx` enabled 141 - add your `lws_abs_protocol` to the list `available_abs_protocols` in 142 `./lib/abstract/abstract.c` 143 144## Steps for adding new abstract transports 145 146 - add the public header in `./include/libwebsockets/abstract/transports/` 147 - add your transport sources under `./lib/abstract/transports/` 148 - in CMakeLists.txt append your transport sources to SOURCES if `LWS_WITH_ABSTRACT` 149 and any other cmake conditionals 150 - add an extern for your transport `lws_protocols` in `./lib/core-net/private.h` 151 - add your transport `lws_protocols` to `available_abstract_protocols` in 152 `./lib/core-net/vhost.c` 153 - add your `lws_abs_transport` to the list `available_abs_transports` in 154 `./lib/abstract/abstract.c` 155 156# Protocol testing 157 158## unit tests 159 160lws features an abstract transport designed to facilitate unit testing. This 161contains an lws_sequencer that performs the steps of tests involving sending the 162protocol test vector buffers and confirming the response of the protocol matches 163the test vectors. 164 165## test-sequencer 166 167test-sequencer is a helper that sequences running an array of unit tests and 168collects the statistics and gives a PASS / FAIL result. 169 170See the SMTP client api test for an example of how to use. 171