lib/tsocket: add tsocket_writev_send/recv()
[ira/wip.git] / lib / tsocket / tsocket_guide.txt
1
2 Basic design of the tsocket abstraction
3 =======================================
4
5 The tsocket layer is designed to match more or less
6 the bsd socket layer, but it hides the filedescriptor
7 within a opaque 'tsocket_context' structure to make virtual
8 sockets possible. The virtual sockets can be encrypted tunnels
9 (like TLS, SASL or GSSAPI) or named pipes over smb.
10
11 The tsocket layer is a bit like an abstract class, which defines
12 common methods to work with sockets in a non blocking fashion.
13
14 The whole library is based on the talloc(3) and 'tevent' libraries.
15
16 The 'tsocket_address' structure is the 2nd abstracted class
17 which represends the address of a socket endpoint.
18
19 Each different type of socket has its own constructor.
20
21 Typically the constructor for a tsocket_context is attached to
22 the tsocket_address of the source endpoint. That means
23 the tsocket_address_create_socket() function takes the
24 tsocket_address of the local endpoint and creates a tsocket_context
25 for the communication.
26
27 For some usecases it's possible to wrap an existing socket into a
28 tsocket_context, e.g. to wrap an existing pipe(2) into
29 tsocket_context, so that you can use the same functions to
30 communicate over the pipe.
31
32 The tsocket_address abstraction
33 ===============================
34
35 The tsocket_address represents an socket endpoint genericly.
36 As it's like an abstract class it has no specific constructor.
37 The specific constructors are descripted later sections.
38
39 There's a function get the string representation of the
40 endpoint for debugging. Callers should not try to parse
41 the string! The should use additional methods of the specific
42 tsocket_address implemention to get more details.
43
44    char *tsocket_address_string(const struct tsocket_address *addr,
45                                 TALLOC_CTX *mem_ctx);
46
47 There's a function to create a copy of the tsocket_address.
48 This is useful when before doing modifications to a socket
49 via additional methods of the specific tsocket_address implementation.
50
51    struct tsocket_address *tsocket_address_copy(const struct tsocket_address *addr,
52                                                 TALLOC_CTX *mem_ctx);
53
54 There's a function to create a tsocket_context based on the given local
55 socket endpoint. The return value is 0 on success and -1 on failure
56 with errno holding the specific error. Specific details are descripted in later
57 sections. Note not all specific implementation have to implement all socket
58 types.
59
60    enum tsocket_type {
61         TSOCKET_TYPE_STREAM = 1,
62         TSOCKET_TYPE_DGRAM,
63         TSOCKET_TYPE_MESSAGE
64    };
65
66    int tsocket_address_create_socket(const struct tsocket_address *addr,
67                                      enum tsocket_type type,
68                                      TALLOC_CTX *mem_ctx,
69                                      struct tsocket_context **sock);
70
71 The tsocket_context abstraction
72 ===============================
73
74 The tsocket_context is like an abstract class and represents
75 a socket similar to bsd style sockets. The methods are more
76 or less equal to the bsd socket api, while the filedescriptor
77 is replaced by tsocket_context and sockaddr, socklen_t pairs
78 are replaced by tsocket_address. The 'bind' operation happens
79 in the specific constructor as the constructor is typically based
80 on tsocket_address of local socket endpoint.
81
82 All operations are by design non blocking and can return error
83 values like EAGAIN, EINPROGRESS, EWOULDBLOCK or EINTR which
84 indicate that the caller should retry the operation later.
85 Also read the "The glue to tevent" section.
86
87 The socket can of types:
88  - TSOCKET_TYPE_STREAM is the equivalent to SOCK_STREAM in the bsd socket api.
89  - TSOCKET_TYPE_DGRAM is the equivalent to SOCK_DGRAM in the bsd socket api.
90  - TSOCKET_TYPE_MESSAGE operates on a connected socket and is therefore
91    like TSOCKET_TYPE_STREAM, but the consumer needs to first read all
92    data of a message, which was generated by one message 'write' on the sender,
93    before the consumer gets data of the next message. This matches a bit
94    like message mode pipes on windows. The concept is to transfer ordered
95    messages between to endpoints.
96
97 There's a function to connect to a remote endpoint. The behavior
98 and error codes match the connect(2) function of the bsd socket api.
99 Maybe the specific tsocket_context implementation speficied some
100 further details.
101
102    int tsocket_connect(struct tsocket_context *sock,
103                        const struct tsocket_address *remote_addr);
104
105 There's a function to listen for incoming connections. The behavior
106 and error codes match the listen(2) function of the bsd socket api.
107 Maybe the specific tsocket_context implementation speficied some
108 further details.
109
110    int tsocket_listen(struct tsocket_context *sock,
111                       int queue_size);
112
113 There's a function to accept incoming connections. The behavior
114 and error codes match the accept(2) function of the bsd socket api.
115 Maybe the specific tsocket_context implementation speficied some
116 further details.
117
118    int tsocket_accept(struct tsocket_context *sock,
119                       TALLOC_CTX *mem_ctx,
120                       struct tsocket_context **new_sock);
121
122 There's a function to ask how many bytes are in input buffer
123 of the connection. For sockets of type TSOCKET_TYPE_DGRAM or
124 TSOCKET_TYPE_MESSAGE the size of the next available dgram/message
125 is returned. A return value of -1 indicates a socket error
126 and errno will hold the specific error code. If no data
127 is available 0 is returned, but retry error codes like
128 EINTR can also be returned.
129
130    ssize_t tsocket_pending(struct tsocket_context *sock);
131
132 There's a function to read data from the socket. The behavior
133 and error codes match the readv(3) function, also take a look
134 at the recv(2) function of the bsd socket api.
135 Maybe the specific tsocket_context implementation speficied some
136 further details.
137
138    int tsocket_readv(struct tsocket_context *sock,
139                      const struct iovec *vector, size_t count);
140
141 There's a function to write data from the socket. The behavior
142 and error codes match the writev(3) function, also take a look
143 at the send(2) function of the bsd socket api.
144 Maybe the specific tsocket_context implementation speficied some
145 further details.
146
147    int tsocket_writev(struct tsocket_context *sock,
148                       const struct iovec *vector, size_t count);
149
150 There's a function to read a datagram from a remote endpoint.
151 The behavior and error codes match the recvfrom(2) function of
152 the bsd socket api. As TSOCKET_TYPE_DGRAM sockets can also be
153 used in connected mode src_addr can be NULL, if the caller don't
154 want to get the source address. Maybe the specific tsocket_context
155 implementation speficied some further details.
156
157    ssize_t tsocket_recvfrom(struct tsocket_context *sock,
158                             uint8_t *data, size_t len,
159                             TALLOC_CTX *addr_ctx,
160                             struct tsocket_address **src_addr);
161
162 There's a function to send a datagram to a remote endpoint the socket.
163 The behavior and error codes match the recvfrom(2) function of the
164 bsd socket api. As TSOCKET_TYPE_DGRAM sockets can also be used in
165 connected mode dest_addr must be NULL in connected mode and a valid
166 tsocket_address otherwise. Maybe the specific tsocket_context
167 implementation speficied some further details.
168
169    ssize_t tsocket_sendto(struct tsocket_context *sock,
170                           const uint8_t *data, size_t len,
171                           const struct tsocket_address *dest_addr);
172
173 There's a function to get the current status of the socket.
174 The behavior and error codes match the getsockopt(2) function
175 of the bsd socket api, with SOL_SOCKET and SO_ERROR as arguments.
176 Maybe the specific tsocket_context implementation speficied some
177 further details.
178
179    int tsocket_get_status(const struct tsocket_context *sock);
180
181 There's a function to get tsocket_address of the local endpoint.
182 The behavior and error codes match the getsockname(2) function
183 of the bsd socket api. Maybe the specific tsocket_context
184 implementation speficied some further details.
185
186    int tsocket_get_local_address(const struct tsocket_context *sock,
187                                  TALLOC_CTX *mem_ctx,
188                                  struct tsocket_address **local_addr);
189
190 There's a function to get tsocket_address of the remote endpoint
191 of a connected socket. The behavior and error codes match the
192 getpeername(2) function of the bsd socket api. Maybe the specific
193 tsocket_context implementation speficied some further details.
194
195    int tsocket_get_remote_address(const struct tsocket_context *sock,
196                                   TALLOC_CTX *mem_ctx,
197                                   struct tsocket_address **remote_addr,
198                                   const char *location);
199
200 There's a function to ask for specific options of the socket.
201 The behavior and error codes match the getsockopt(2) function
202 of the bsd socket api. The option and value are represented as string
203 values, where the 'value' parameter can be NULL is the caller don't want to
204 get the value. The supported options and values are up to the specific
205 tsocket_context implementation.
206
207    int tsocket_get_option(const struct tsocket_context *sock,
208                           const char *option,
209                           TALLOC_CTX *mem_ctx,
210                           char **value);
211
212 There's a function to set specific options of the socket.
213 The behavior and error codes match the setsockopt(2) function
214 of the bsd socket api. The option and value are represented as string
215 values, where the 'value' parameter can be NULL. The supported options
216 and values are up to the specific tsocket_context implementation.
217 The 'force' parameter specifies whether an error should be returned
218 for unsupported options.
219
220    int tsocket_set_option(const struct tsocket_context *sock,
221                           const char *option,
222                           bool force,
223                           const char *value);
224
225 There's a function to disconnect the socket. The behavior
226 and error codes match the close(2) function of the bsd socket api.
227 Maybe the specific tsocket_context implementation speficied some
228 further details.
229
230    void tsocket_disconnect(struct tsocket_context *sock);
231
232 The glue to tevent
233 ==================
234
235 As the tsocket library is based on the tevent library,
236 there need to be functions to let the caller register
237 callback functions, which are triggered when the socket
238 is writeable or readable. Typically one would use
239 tevent fd events, but in order to hide the filedescriptor
240 the tsocket_context abstraction has their own functions.
241
242 There's a function to set the currently active tevent_context
243 for the socket. It's important there's only one tevent_context
244 actively used with the socket. A second call will cancel
245 all low level events made on the old tevent_context, it will
246 also resets the send and recv handlers to NULL. If the caller
247 sets attaches a new event context to the socket, the callback
248 function also need to be registered again. It's important
249 that the caller keeps the given tevent_context in memory
250 and actively calls tsocket_set_event_context(sock, NULL)
251 before calling talloc_free(event_context).
252 The function returns 0 on success and -1 together with an errno
253 on failure.
254
255    int tsocket_set_event_context(struct tsocket_context *sock,
256                                  struct tevent_context *ev);
257
258 There's a function to register a callback function which is called
259 when the socket is readable. If the caller don't want to get notified
260 anymore the function should be called with NULL as handler.
261 The function returns 0 on success and -1 together with an errno
262 on failure.
263
264    typedef void (*tsocket_event_handler_t)(struct tsocket_context *, void *);
265    int tsocket_set_readable_handler(struct tsocket_context *sock,
266                                     tsocket_event_handler_t handler,
267                                     void *private_data);
268
269 There's a function to register a callback function which is called
270 when the socket is writeable. If the caller don't want to get notified
271 anymore the function should be called with NULL as handler.
272 The function returns 0 on success and -1 together with an errno
273 on failure.
274
275    typedef void (*tsocket_event_handler_t)(struct tsocket_context *, void *);
276    int tsocket_set_writeable_handler(struct tsocket_context *sock,
277                                      tsocket_event_handler_t handler,
278                                      void *private_data);
279
280 Note: if the socket is readable and writeable, only the writeable
281       handler is called, this avoids deadlocks at the application level.
282