]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | /*- |
2 | * BSD LICENSE | |
3 | * | |
f67539c2 TL |
4 | * Copyright (c) Intel Corporation. All rights reserved. |
5 | * Copyright (c) 2020 Mellanox Technologies LTD. All rights reserved. | |
11fdf7f2 TL |
6 | * |
7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | |
10 | * | |
11 | * * Redistributions of source code must retain the above copyright | |
12 | * notice, this list of conditions and the following disclaimer. | |
13 | * * Redistributions in binary form must reproduce the above copyright | |
14 | * notice, this list of conditions and the following disclaimer in | |
15 | * the documentation and/or other materials provided with the | |
16 | * distribution. | |
17 | * * Neither the name of Intel Corporation nor the names of its | |
18 | * contributors may be used to endorse or promote products derived | |
19 | * from this software without specific prior written permission. | |
20 | * | |
21 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
22 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
23 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
24 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
25 | * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
26 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
27 | * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
31 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
32 | */ | |
33 | ||
34 | /** \file | |
35 | * TCP socket abstraction layer | |
36 | */ | |
37 | ||
38 | #ifndef SPDK_SOCK_H | |
39 | #define SPDK_SOCK_H | |
40 | ||
41 | #include "spdk/stdinc.h" | |
42 | ||
f67539c2 TL |
43 | #include "spdk/queue.h" |
44 | #include "spdk/json.h" | |
45 | ||
11fdf7f2 TL |
46 | #ifdef __cplusplus |
47 | extern "C" { | |
48 | #endif | |
49 | ||
50 | struct spdk_sock; | |
51 | struct spdk_sock_group; | |
52 | ||
f67539c2 TL |
53 | /** |
54 | * Anywhere this struct is used, an iovec array is assumed to | |
55 | * immediately follow the last member in memory, without any | |
56 | * padding. | |
57 | * | |
58 | * A simpler implementation would be to place a 0-length array | |
59 | * of struct iovec at the end of this request. However, embedding | |
60 | * a structure that ends with a variable length array inside of | |
61 | * another structure is a GNU C extension and not standard. | |
62 | */ | |
63 | struct spdk_sock_request { | |
64 | /* When the request is completed, this callback will be called. | |
65 | * err will be 0 on success or a negated errno value on failure. */ | |
66 | void (*cb_fn)(void *cb_arg, int err); | |
67 | void *cb_arg; | |
68 | ||
69 | /** | |
70 | * These fields are used by the socket layer and should not be modified | |
71 | */ | |
72 | struct __sock_request_internal { | |
73 | TAILQ_ENTRY(spdk_sock_request) link; | |
74 | uint32_t offset; | |
75 | } internal; | |
76 | ||
77 | int iovcnt; | |
78 | /* struct iovec iov[]; */ | |
79 | }; | |
80 | ||
81 | #define SPDK_SOCK_REQUEST_IOV(req, i) ((struct iovec *)(((uint8_t *)req + sizeof(struct spdk_sock_request)) + (sizeof(struct iovec) * i))) | |
82 | ||
83 | /** | |
84 | * SPDK socket implementation options. | |
85 | * | |
86 | * A pointer to this structure is used by spdk_sock_impl_get_opts() and spdk_sock_impl_set_opts() | |
87 | * to allow the user to request options for the socket module implementation. | |
88 | * Each socket module defines which options from this structure are applicable to the module. | |
89 | */ | |
90 | struct spdk_sock_impl_opts { | |
91 | /** | |
92 | * Size of sock receive buffer. Used by posix socket module. | |
93 | */ | |
94 | uint32_t recv_buf_size; | |
95 | ||
96 | /** | |
97 | * Size of sock send buffer. Used by posix socket module. | |
98 | */ | |
99 | uint32_t send_buf_size; | |
100 | ||
101 | /** | |
102 | * Enable or disable receive pipe. Used by posix socket module. | |
103 | */ | |
104 | bool enable_recv_pipe; | |
105 | ||
106 | /** | |
107 | * Enable or disable use of zero copy flow on send. Used by posix socket module. | |
108 | */ | |
109 | bool enable_zerocopy_send; | |
110 | }; | |
111 | ||
112 | /** | |
113 | * Spdk socket initialization options. | |
114 | * | |
115 | * A pointer to this structure will be used by spdk_sock_listen_ext() or spdk_sock_connect_ext() to | |
116 | * allow the user to request non-default options on the socket. | |
117 | */ | |
118 | struct spdk_sock_opts { | |
119 | /** | |
120 | * The size of spdk_sock_opts according to the caller of this library is used for ABI | |
121 | * compatibility. The library uses this field to know how many fields in this | |
122 | * structure are valid. And the library will populate any remaining fields with default values. | |
123 | */ | |
124 | size_t opts_size; | |
125 | ||
126 | /** | |
127 | * The priority on the socket and default value is zero. | |
128 | */ | |
129 | int priority; | |
130 | }; | |
131 | ||
132 | /** | |
133 | * Initialize the default value of opts. | |
134 | * | |
135 | * \param opts Data structure where SPDK will initialize the default sock options. | |
136 | * Users must set opts_size to sizeof(struct spdk_sock_opts). This will ensure that the | |
137 | * libraryonly tries to fill as many fields as allocated by the caller. This allows ABI | |
138 | * compatibility with future versions of this library that may extend the spdk_sock_opts | |
139 | * structure. | |
140 | */ | |
141 | void spdk_sock_get_default_opts(struct spdk_sock_opts *opts); | |
142 | ||
11fdf7f2 TL |
143 | /** |
144 | * Get client and server addresses of the given socket. | |
145 | * | |
146 | * \param sock Socket to get address. | |
147 | * \param saddr A pointer to the buffer to hold the address of server. | |
148 | * \param slen Length of the buffer 'saddr'. | |
149 | * \param sport A pointer(May be NULL) to the buffer to hold the port info of server. | |
150 | * \param caddr A pointer to the buffer to hold the address of client. | |
151 | * \param clen Length of the buffer 'caddr'. | |
152 | * \param cport A pointer(May be NULL) to the buffer to hold the port info of server. | |
153 | * | |
154 | * \return 0 on success, -1 on failure. | |
155 | */ | |
156 | int spdk_sock_getaddr(struct spdk_sock *sock, char *saddr, int slen, uint16_t *sport, | |
157 | char *caddr, int clen, uint16_t *cport); | |
158 | ||
159 | /** | |
f67539c2 TL |
160 | * Create a socket using the specific sock implementation, connect the socket |
161 | * to the specified address and port (of the server), and then return the socket. | |
162 | * This function is used by client. | |
163 | * | |
164 | * \param ip IP address of the server. | |
165 | * \param port Port number of the server. | |
166 | * \param impl_name The sock_implementation to use, such as "posix". If impl_name is | |
167 | * specified, it will *only* try to connect on that impl. If it is NULL, it will try | |
168 | * all the sock implementations in order and uses the first sock implementation which | |
169 | * can connect. For example, it may try vpp first, then fall back to posix. | |
170 | * | |
171 | * \return a pointer to the connected socket on success, or NULL on failure. | |
172 | */ | |
173 | struct spdk_sock *spdk_sock_connect(const char *ip, int port, char *impl_name); | |
174 | ||
175 | /** | |
176 | * Create a socket using the specific sock implementation, connect the socket | |
177 | * to the specified address and port (of the server), and then return the socket. | |
178 | * This function is used by client. | |
11fdf7f2 TL |
179 | * |
180 | * \param ip IP address of the server. | |
181 | * \param port Port number of the server. | |
f67539c2 TL |
182 | * \param impl_name The sock_implementation to use, such as "posix". If impl_name is |
183 | * specified, it will *only* try to connect on that impl. If it is NULL, it will try | |
184 | * all the sock implementations in order and uses the first sock implementation which | |
185 | * can connect. For example, it may try vpp first, then fall back to posix. | |
186 | * \param opts The sock option pointer provided by the user which should not be NULL pointer. | |
11fdf7f2 TL |
187 | * |
188 | * \return a pointer to the connected socket on success, or NULL on failure. | |
189 | */ | |
f67539c2 TL |
190 | struct spdk_sock *spdk_sock_connect_ext(const char *ip, int port, char *impl_name, |
191 | struct spdk_sock_opts *opts); | |
11fdf7f2 TL |
192 | |
193 | /** | |
f67539c2 TL |
194 | * Create a socket using the specific sock implementation, bind the socket to |
195 | * the specified address and port and listen on the socket, and then return the socket. | |
196 | * This function is used by server. | |
11fdf7f2 TL |
197 | * |
198 | * \param ip IP address to listen on. | |
199 | * \param port Port number. | |
f67539c2 TL |
200 | * \param impl_name The sock_implementation to use, such as "posix". If impl_name is |
201 | * specified, it will *only* try to listen on that impl. If it is NULL, it will try | |
202 | * all the sock implementations in order and uses the first sock implementation which | |
203 | * can listen. For example, it may try vpp first, then fall back to posix. | |
11fdf7f2 TL |
204 | * |
205 | * \return a pointer to the listened socket on success, or NULL on failure. | |
206 | */ | |
f67539c2 TL |
207 | struct spdk_sock *spdk_sock_listen(const char *ip, int port, char *impl_name); |
208 | ||
209 | /** | |
210 | * Create a socket using the specific sock implementation, bind the socket to | |
211 | * the specified address and port and listen on the socket, and then return the socket. | |
212 | * This function is used by server. | |
213 | * | |
214 | * \param ip IP address to listen on. | |
215 | * \param port Port number. | |
216 | * \param impl_name The sock_implementation to use, such as "posix". If impl_name is | |
217 | * specified, it will *only* try to listen on that impl. If it is NULL, it will try | |
218 | * all the sock implementations in order and uses the first sock implementation which | |
219 | * can listen. For example, it may try vpp first, then fall back to posix. | |
220 | * \param opts The sock option pointer provided by the user, which should not be NULL pointer. | |
221 | * | |
222 | * \return a pointer to the listened socket on success, or NULL on failure. | |
223 | */ | |
224 | struct spdk_sock *spdk_sock_listen_ext(const char *ip, int port, char *impl_name, | |
225 | struct spdk_sock_opts *opts); | |
11fdf7f2 TL |
226 | |
227 | /** | |
228 | * Accept a new connection from a client on the specified socket and return a | |
229 | * socket structure which holds the connection. | |
230 | * | |
231 | * \param sock Listening socket. | |
232 | * | |
233 | * \return a pointer to the accepted socket on success, or NULL on failure. | |
234 | */ | |
235 | struct spdk_sock *spdk_sock_accept(struct spdk_sock *sock); | |
236 | ||
237 | /** | |
238 | * Close a socket. | |
239 | * | |
240 | * \param sock Socket to close. | |
241 | * | |
242 | * \return 0 on success, -1 on failure. | |
243 | */ | |
244 | int spdk_sock_close(struct spdk_sock **sock); | |
245 | ||
f67539c2 TL |
246 | /** |
247 | * Flush a socket from data gathered in previous writev_async calls. | |
248 | * | |
249 | * \param sock Socket to flush. | |
250 | * | |
251 | * \return 0 on success, -1 on failure. | |
252 | */ | |
253 | int spdk_sock_flush(struct spdk_sock *sock); | |
254 | ||
11fdf7f2 TL |
255 | /** |
256 | * Receive a message from the given socket. | |
257 | * | |
258 | * \param sock Socket to receive message. | |
259 | * \param buf Pointer to a buffer to hold the data. | |
260 | * \param len Length of the buffer. | |
261 | * | |
262 | * \return the length of the received message on success, -1 on failure. | |
263 | */ | |
264 | ssize_t spdk_sock_recv(struct spdk_sock *sock, void *buf, size_t len); | |
265 | ||
266 | /** | |
267 | * Write message to the given socket from the I/O vector array. | |
268 | * | |
269 | * \param sock Socket to write to. | |
270 | * \param iov I/O vector. | |
271 | * \param iovcnt Number of I/O vectors in the array. | |
272 | * | |
273 | * \return the length of written message on success, -1 on failure. | |
274 | */ | |
275 | ssize_t spdk_sock_writev(struct spdk_sock *sock, struct iovec *iov, int iovcnt); | |
9f95a23c | 276 | |
f67539c2 TL |
277 | /** |
278 | * Write data to the given socket asynchronously, calling | |
279 | * the provided callback when the data has been written. | |
280 | * | |
281 | * \param sock Socket to write to. | |
282 | * \param req The write request to submit. | |
283 | */ | |
284 | void spdk_sock_writev_async(struct spdk_sock *sock, struct spdk_sock_request *req); | |
285 | ||
9f95a23c TL |
286 | /** |
287 | * Read message from the given socket to the I/O vector array. | |
288 | * | |
289 | * \param sock Socket to receive message. | |
290 | * \param iov I/O vector. | |
291 | * \param iovcnt Number of I/O vectors in the array. | |
292 | * | |
293 | * \return the length of the received message on success, -1 on failure. | |
294 | */ | |
295 | ssize_t spdk_sock_readv(struct spdk_sock *sock, struct iovec *iov, int iovcnt); | |
11fdf7f2 TL |
296 | |
297 | /** | |
298 | * Set the value used to specify the low water mark (in bytes) for this socket. | |
299 | * | |
300 | * \param sock Socket to set for. | |
301 | * \param nbytes Value for recvlowat. | |
302 | * | |
303 | * \return 0 on success, -1 on failure. | |
304 | */ | |
305 | int spdk_sock_set_recvlowat(struct spdk_sock *sock, int nbytes); | |
306 | ||
307 | /** | |
308 | * Set receive buffer size for the given socket. | |
309 | * | |
310 | * \param sock Socket to set buffer size for. | |
311 | * \param sz Buffer size in bytes. | |
312 | * | |
313 | * \return 0 on success, -1 on failure. | |
314 | */ | |
315 | int spdk_sock_set_recvbuf(struct spdk_sock *sock, int sz); | |
316 | ||
317 | /** | |
318 | * Set send buffer size for the given socket. | |
319 | * | |
320 | * \param sock Socket to set buffer size for. | |
321 | * \param sz Buffer size in bytes. | |
322 | * | |
323 | * \return 0 on success, -1 on failure. | |
324 | */ | |
325 | int spdk_sock_set_sendbuf(struct spdk_sock *sock, int sz); | |
326 | ||
327 | /** | |
328 | * Check whether the address of socket is ipv6. | |
329 | * | |
330 | * \param sock Socket to check. | |
331 | * | |
332 | * \return true if the address of socket is ipv6, or false otherwise. | |
333 | */ | |
334 | bool spdk_sock_is_ipv6(struct spdk_sock *sock); | |
335 | ||
336 | /** | |
337 | * Check whether the address of socket is ipv4. | |
338 | * | |
339 | * \param sock Socket to check. | |
340 | * | |
341 | * \return true if the address of socket is ipv4, or false otherwise. | |
342 | */ | |
343 | bool spdk_sock_is_ipv4(struct spdk_sock *sock); | |
344 | ||
f67539c2 TL |
345 | /** |
346 | * Check whether the socket is currently connected. | |
347 | * | |
348 | * \param sock Socket to check | |
349 | * | |
350 | * \return true if the socket is connected or false otherwise. | |
351 | */ | |
352 | bool spdk_sock_is_connected(struct spdk_sock *sock); | |
353 | ||
11fdf7f2 TL |
354 | /** |
355 | * Callback function for spdk_sock_group_add_sock(). | |
356 | * | |
357 | * \param arg Argument for the callback function. | |
358 | * \param group Socket group. | |
359 | * \param sock Socket. | |
360 | */ | |
361 | typedef void (*spdk_sock_cb)(void *arg, struct spdk_sock_group *group, struct spdk_sock *sock); | |
362 | ||
363 | /** | |
f67539c2 | 364 | * Create a new socket group with user provided pointer |
11fdf7f2 | 365 | * |
f67539c2 | 366 | * \param ctx the context provided by user. |
11fdf7f2 TL |
367 | * \return a pointer to the created group on success, or NULL on failure. |
368 | */ | |
f67539c2 TL |
369 | struct spdk_sock_group *spdk_sock_group_create(void *ctx); |
370 | ||
371 | /** | |
372 | * Get the ctx of the sock group | |
373 | * | |
374 | * \param sock_group Socket group. | |
375 | * \return a pointer which is ctx of the sock_group. | |
376 | */ | |
377 | void *spdk_sock_group_get_ctx(struct spdk_sock_group *sock_group); | |
378 | ||
11fdf7f2 TL |
379 | |
380 | /** | |
381 | * Add a socket to the group. | |
382 | * | |
383 | * \param group Socket group. | |
384 | * \param sock Socket to add. | |
385 | * \param cb_fn Called when the operation completes. | |
386 | * \param cb_arg Argument passed to the callback function. | |
387 | * | |
388 | * \return 0 on success, -1 on failure. | |
389 | */ | |
390 | int spdk_sock_group_add_sock(struct spdk_sock_group *group, struct spdk_sock *sock, | |
391 | spdk_sock_cb cb_fn, void *cb_arg); | |
392 | ||
393 | /** | |
394 | * Remove a socket from the group. | |
395 | * | |
396 | * \param group Socket group. | |
397 | * \param sock Socket to remove. | |
398 | * | |
399 | * \return 0 on success, -1 on failure. | |
400 | */ | |
401 | int spdk_sock_group_remove_sock(struct spdk_sock_group *group, struct spdk_sock *sock); | |
402 | ||
403 | /** | |
404 | * Poll incoming events for each registered socket. | |
405 | * | |
406 | * \param group Group to poll. | |
407 | * | |
f67539c2 | 408 | * \return the number of events on success, -1 on failure. |
11fdf7f2 TL |
409 | */ |
410 | int spdk_sock_group_poll(struct spdk_sock_group *group); | |
411 | ||
412 | /** | |
413 | * Poll incoming events up to max_events for each registered socket. | |
414 | * | |
415 | * \param group Group to poll. | |
416 | * \param max_events Number of maximum events to poll for each socket. | |
417 | * | |
418 | * \return the number of events on success, -1 on failure. | |
419 | */ | |
420 | int spdk_sock_group_poll_count(struct spdk_sock_group *group, int max_events); | |
421 | ||
422 | /** | |
423 | * Close all registered sockets of the group and then remove the group. | |
424 | * | |
425 | * \param group Group to close. | |
426 | * | |
427 | * \return 0 on success, -1 on failure. | |
428 | */ | |
429 | int spdk_sock_group_close(struct spdk_sock_group **group); | |
430 | ||
f67539c2 TL |
431 | /** |
432 | * Get the optimal sock group for this sock. | |
433 | * | |
434 | * \param sock The socket | |
435 | * \param group Returns the optimal sock group. If there is no optimal sock group, returns NULL. | |
436 | * | |
437 | * \return 0 on success. Negated errno on failure. | |
438 | */ | |
439 | int spdk_sock_get_optimal_sock_group(struct spdk_sock *sock, struct spdk_sock_group **group); | |
440 | ||
441 | /** | |
442 | * Get current socket implementation options. | |
443 | * | |
444 | * \param impl_name The socket implementation to use, such as "posix". | |
445 | * \param opts Pointer to allocated spdk_sock_impl_opts structure that will be filled with actual values. | |
446 | * \param len On input specifies size of passed opts structure. On return it is set to actual size that was filled with values. | |
447 | * | |
448 | * \return 0 on success, -1 on failure. errno is set to indicate the reason of failure. | |
449 | */ | |
450 | int spdk_sock_impl_get_opts(const char *impl_name, struct spdk_sock_impl_opts *opts, size_t *len); | |
451 | ||
452 | /** | |
453 | * Set socket implementation options. | |
454 | * | |
455 | * \param impl_name The socket implementation to use, such as "posix". | |
456 | * \param opts Pointer to allocated spdk_sock_impl_opts structure with new options values. | |
457 | * \param len Size of passed opts structure. | |
458 | * | |
459 | * \return 0 on success, -1 on failure. errno is set to indicate the reason of failure. | |
460 | */ | |
461 | int spdk_sock_impl_set_opts(const char *impl_name, const struct spdk_sock_impl_opts *opts, | |
462 | size_t len); | |
463 | ||
464 | /** | |
465 | * Write socket subsystem configuration into provided JSON context. | |
466 | * | |
467 | * \param w JSON write context | |
468 | */ | |
469 | void spdk_sock_write_config_json(struct spdk_json_write_ctx *w); | |
470 | ||
11fdf7f2 TL |
471 | #ifdef __cplusplus |
472 | } | |
473 | #endif | |
474 | ||
475 | #endif /* SPDK_SOCK_H */ |