VCL-LDPRELOAD: add sendfile/sendfile64 implementation.
[vpp.git] / src / vcl / vcom_socket.h
1 /*
2  * Copyright (c) 2017 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #ifndef included_vcom_socket_h
17 #define included_vcom_socket_h
18
19 #include <string.h>
20
21 #include <vcl/vcom_glibc_socket.h>
22 #include <vppinfra/types.h>
23 #include <sys/socket.h>
24
25 #define INVALID_SESSION_ID (~0)
26 #define INVALID_FD (~0)
27
28 #define INVALID_VEP_IDX INVALID_SESSION_ID
29 #define INVALID_EPFD INVALID_FD
30
31 typedef enum
32 {
33   SOCKET_TYPE_UNBOUND = 0,
34   SOCKET_TYPE_KERNEL_BOUND,
35   SOCKET_TYPE_VPPCOM_BOUND
36 } vcom_socket_type_t;
37
38 typedef enum
39 {
40   EPOLL_TYPE_UNBOUND = 0,
41   EPOLL_TYPE_KERNEL_BOUND,
42   EPOLL_TYPE_VPPCOM_BOUND
43 } vcom_epoll_type_t;
44
45 typedef enum
46 {
47   FD_TYPE_INVALID = 0,
48   FD_TYPE_KERNEL,
49   FD_TYPE_EPOLL,
50   FD_TYPE_VCOM_SOCKET,
51   /* add new types here */
52   /* FD_TYPE_MAX should be the last entry */
53   FD_TYPE_MAX
54 } vcom_fd_type_t;
55
56 typedef struct
57 {
58   /* file descriptor -
59    * fd 0, 1, 2 have special meaning and are reserved,
60    * -1 denote invalid fd */
61   i32 fd;
62
63   /* session id - -1 denote invalid sid */
64   i32 sid;
65
66   /* socket type */
67   vcom_socket_type_t type;
68
69   /* vcom socket attributes here */
70
71 } vcom_socket_t;
72
73 typedef struct
74 {
75   /* epoll file descriptor -
76    * epfd 0, 1, 2 have special meaning and are reserved,
77    * -1 denote invalid epfd */
78   i32 epfd;
79
80   /* vep idx - -1 denote invalid vep_idx */
81   i32 vep_idx;
82
83   /* epoll type */
84   vcom_epoll_type_t type;
85
86   /* flags - 0 or EPOLL_CLOEXEC */
87   i32 flags;
88
89   /* vcom epoll attributes here */
90
91   /*
92    * 00. count of file descriptors currently registered
93    *     on this epoll instance.
94    * 01. number of file descriptors in the epoll set.
95    * 02. EPOLL_CTL_ADD, EPOLL_CTL_MOD, EPOLL_CTL_DEL
96    *     update the count.
97    * 03. cached for frequent access.
98    * */
99   i32 count;
100   i32 vcl_cnt;
101   i32 libc_cnt;
102
103   /* close( ) called on this epoll instance */
104   /* 0 - close ( ) not called, 1 - close( ) called. */
105   u32 close;
106
107 } vcom_epoll_t;
108
109 typedef struct
110 {
111   /* "container" of this item */
112   i32 epfd;
113
114   /* fd - file descriptor information this item refers to */
115   i32 fd;
116   /* next and prev fd in the "epoll set" of epfd */
117   i32 next_fd;
118   i32 prev_fd;
119
120   /* vcom fd type */
121   vcom_fd_type_t type;
122
123   /* interested events and the source fd */
124   struct epoll_event event;
125
126   /* ready events and the source fd */
127   struct epoll_event revent;
128
129   /* epitem attributes here */
130
131 } vcom_epitem_t;
132
133 typedef union vcom_epitem_key
134 {
135   struct
136   {
137     i32 fd;
138     i32 epfd;
139   };
140   i64 key;
141 } __EPOLL_PACKED vcom_epitem_key_t;
142
143 static inline char *
144 vcom_socket_type_str (vcom_socket_type_t t)
145 {
146   switch (t)
147     {
148     case SOCKET_TYPE_UNBOUND:
149       return "SOCKET_TYPE_UNBOUND";
150
151     case SOCKET_TYPE_KERNEL_BOUND:
152       return "SOCKET_TYPE_KERNEL_BOUND";
153
154     case SOCKET_TYPE_VPPCOM_BOUND:
155       return "SOCKET_TYPE_VPPCOM_BOUND";
156
157     default:
158       return "SOCKET_TYPE_UNKNOWN";
159     }
160 }
161
162 static inline char *
163 vcom_socket_epoll_type_str (vcom_epoll_type_t t)
164 {
165   switch (t)
166     {
167     case EPOLL_TYPE_UNBOUND:
168       return "EPOLL_TYPE_UNBOUND";
169
170     case EPOLL_TYPE_KERNEL_BOUND:
171       return "EPOLL_TYPE_KERNEL_BOUND";
172
173     case EPOLL_TYPE_VPPCOM_BOUND:
174       return "EPOLL_TYPE_VPPCOM_BOUND";
175
176     default:
177       return "EPOLL_TYPE_UNKNOWN";
178     }
179 }
180
181 static inline char *
182 vcom_socket_vcom_fd_type_str (vcom_fd_type_t t)
183 {
184   switch (t)
185     {
186     case FD_TYPE_KERNEL:
187       return "FD_TYPE_KERNEL";
188
189     case FD_TYPE_EPOLL:
190       return "FD_TYPE_EPOLL";
191
192     case FD_TYPE_VCOM_SOCKET:
193       return "FD_TYPE_VCOM_SOCKET";
194
195     default:
196       return "FD_TYPE_UNKNOWN";
197     }
198 }
199
200 static inline int
201 vcom_socket_type_is_vppcom_bound (vcom_socket_type_t t)
202 {
203   return t == SOCKET_TYPE_VPPCOM_BOUND;
204 }
205
206 static inline int
207 vcom_socket_epoll_type_is_vppcom_bound (vcom_epoll_type_t t)
208 {
209   return t == EPOLL_TYPE_VPPCOM_BOUND;
210 }
211
212 static inline void
213 vsocket_init (vcom_socket_t * vsock)
214 {
215   memset (vsock, 0, sizeof (*vsock));
216
217   vsock->fd = INVALID_FD;
218   vsock->sid = INVALID_SESSION_ID;
219   vsock->type = SOCKET_TYPE_UNBOUND;
220   /* vcom socket attributes init here */
221 }
222
223 static inline void
224 vepoll_init (vcom_epoll_t * vepoll)
225 {
226   memset (vepoll, 0, sizeof (*vepoll));
227
228   vepoll->epfd = INVALID_EPFD;
229   vepoll->vep_idx = INVALID_VEP_IDX;
230   vepoll->type = EPOLL_TYPE_UNBOUND;
231   vepoll->flags = 0;
232
233   vepoll->count = 0;
234   vepoll->close = 0;
235   /* vcom epoll attributes init here */
236 }
237
238 static inline void
239 vepitem_init (vcom_epitem_t * vepitem)
240 {
241   struct epoll_event event = {.events = 0,.data.fd = INVALID_FD };
242
243   memset (vepitem, 0, sizeof (*vepitem));
244
245   vepitem->epfd = INVALID_EPFD;
246
247   vepitem->fd = INVALID_FD;
248   vepitem->next_fd = INVALID_FD;
249   vepitem->prev_fd = INVALID_FD;
250
251   vepitem->type = FD_TYPE_INVALID;
252
253   vepitem->event = event;
254   vepitem->revent = event;
255   /* vepoll attributes init here */
256 }
257
258 static inline void
259 vepitemkey_init (vcom_epitem_key_t * epfdfd)
260 {
261   memset (epfdfd, 0, sizeof (*epfdfd));
262
263   epfdfd->epfd = INVALID_EPFD;
264   epfdfd->fd = INVALID_FD;
265 }
266
267 static inline void
268 vsocket_set (vcom_socket_t * vsock, i32 fd, i32 sid, vcom_socket_type_t type)
269 {
270   vsock->fd = fd;
271   vsock->sid = sid;
272   vsock->type = type;
273   /* vcom socket attributes set here */
274 }
275
276 static inline void
277 vepoll_set (vcom_epoll_t * vepoll,
278             i32 epfd, i32 vep_idx,
279             vcom_epoll_type_t type, i32 flags, i32 count, u32 close)
280 {
281   vepoll->epfd = epfd;
282   vepoll->vep_idx = vep_idx;
283   vepoll->type = type;
284   vepoll->flags = flags;
285
286   vepoll->count = count;
287   vepoll->close = close;
288   /* vcom epoll attributes set here */
289 }
290
291 static inline void
292 vepitem_set (vcom_epitem_t * vepitem,
293              i32 epfd,
294              i32 fd, i32 next_fd, i32 prev_fd,
295              vcom_fd_type_t type,
296              struct epoll_event event, struct epoll_event revent)
297 {
298   vepitem->epfd = epfd;
299
300   vepitem->fd = fd;
301   vepitem->next_fd = next_fd;
302   vepitem->prev_fd = prev_fd;
303
304   vepitem->type = type;
305
306   vepitem->event = event;
307   vepitem->revent = revent;
308   /* vcom epitem attributes set here */
309 }
310
311 static inline void
312 vepitemkey_set (vcom_epitem_key_t * epfdfd, i32 epfd, i32 fd)
313 {
314   epfdfd->epfd = epfd;
315   epfdfd->fd = fd;
316 }
317
318 static inline int
319 vsocket_is_vppcom_bound (vcom_socket_t * vsock)
320 {
321   return vcom_socket_type_is_vppcom_bound (vsock->type);
322 }
323
324 static inline int
325 vepoll_is_vppcom_bound (vcom_epoll_t * vepoll)
326 {
327   return vcom_socket_epoll_type_is_vppcom_bound (vepoll->type);
328 }
329
330 int vcom_socket_main_init (void);
331
332 void vcom_socket_main_destroy (void);
333
334 void vcom_socket_main_show (void);
335
336 int vcom_socket_is_vcom_fd (int fd);
337
338 int vcom_socket_is_vcom_epfd (int epfd);
339
340 int vcom_socket_close (int __fd);
341
342 ssize_t vcom_socket_read (int __fd, void *__buf, size_t __nbytes);
343
344 ssize_t vcom_socket_readv (int __fd, const struct iovec *__iov, int __iovcnt);
345
346 ssize_t vcom_socket_write (int __fd, const void *__buf, size_t __n);
347
348 ssize_t vcom_socket_writev (int __fd, const struct iovec *__iov,
349                             int __iovcnt);
350
351 int vcom_socket_fcntl_va (int __fd, int __cmd, va_list __ap);
352
353 int vcom_socket_ioctl_va (int __fd, unsigned long int __cmd, va_list __ap);
354
355 int
356 vcom_socket_select (int vcom_nfds, fd_set * __restrict vcom_readfds,
357                     fd_set * __restrict vcom_writefds,
358                     fd_set * __restrict vcom_exceptfds,
359                     struct timeval *__restrict timeout);
360
361
362 int vcom_socket_socket (int __domain, int __type, int __protocol);
363
364 int
365 vcom_socket_socketpair (int __domain, int __type, int __protocol,
366                         int __fds[2]);
367
368 int vcom_socket_bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len);
369
370 int
371 vcom_socket_getsockname (int __fd, __SOCKADDR_ARG __addr,
372                          socklen_t * __restrict __len);
373
374 int
375 vcom_socket_connect (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len);
376
377 int
378 vcom_socket_getpeername (int __fd, __SOCKADDR_ARG __addr,
379                          socklen_t * __restrict __len);
380
381 ssize_t
382 vcom_socket_send (int __fd, const void *__buf, size_t __n, int __flags);
383
384 ssize_t vcom_socket_recv (int __fd, void *__buf, size_t __n, int __flags);
385
386 ssize_t
387 vcom_socket_sendfile (int __out_fd, int __in_fd, off_t * __offset,
388                       size_t __len);
389
390 /*
391  * RETURN   1 if __fd is (SOCK_STREAM, SOCK_SEQPACKET),
392  * 0 otherwise
393  * */
394 int vcom_socket_is_connection_mode_socket (int __fd);
395
396 ssize_t
397 vcom_socket_sendto (int __fd, const void *__buf, size_t __n,
398                     int __flags, __CONST_SOCKADDR_ARG __addr,
399                     socklen_t __addr_len);
400
401 ssize_t
402 vcom_socket_recvfrom (int __fd, void *__restrict __buf, size_t __n,
403                       int __flags, __SOCKADDR_ARG __addr,
404                       socklen_t * __restrict __addr_len);
405
406 ssize_t
407 vcom_socket_sendmsg (int __fd, const struct msghdr *__message, int __flags);
408
409 #ifdef __USE_GNU
410 int
411 vcom_socket_sendmmsg (int __fd, struct mmsghdr *__vmessages,
412                       unsigned int __vlen, int __flags);
413 #endif
414
415 ssize_t vcom_socket_recvmsg (int __fd, struct msghdr *__message, int __flags);
416
417 #ifdef __USE_GNU
418 int
419 vcom_socket_recvmmsg (int __fd, struct mmsghdr *__vmessages,
420                       unsigned int __vlen, int __flags,
421                       struct timespec *__tmo);
422 #endif
423
424 int
425 vcom_socket_getsockopt (int __fd, int __level, int __optname,
426                         void *__restrict __optval,
427                         socklen_t * __restrict __optlen);
428
429 int
430 vcom_socket_setsockopt (int __fd, int __level, int __optname,
431                         const void *__optval, socklen_t __optlen);
432
433 int vcom_socket_listen (int __fd, int __n);
434
435 int
436 vcom_socket_accept (int __fd, __SOCKADDR_ARG __addr,
437                     socklen_t * __restrict __addr_len);
438
439 int
440 vcom_socket_accept4 (int __fd, __SOCKADDR_ARG __addr,
441                      socklen_t * __restrict __addr_len, int __flags);
442
443 int vcom_socket_shutdown (int __fd, int __how);
444
445 int vcom_socket_epoll_create1 (int __flags);
446
447 int
448 vcom_socket_epoll_ctl (int __epfd, int __op, int __fd,
449                        struct epoll_event *__event);
450
451 int
452 vcom_socket_epoll_pwait (int __epfd, struct epoll_event *__events,
453                          int __maxevents, int __timeout,
454                          const __sigset_t * __ss);
455
456 /*
457  * handle only vcom fds
458  */
459 int vcom_socket_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout);
460
461 #ifdef __USE_GNU
462 int
463 vcom_socket_ppoll (struct pollfd *__fds, nfds_t __nfds,
464                    const struct timespec *__timeout, const __sigset_t * __ss);
465 #endif
466
467 #endif /* included_vcom_socket_h */
468
469 /*
470  * fd.io coding-style-patch-verification: ON
471  *
472  * Local Variables:
473  * eval: (c-set-style "gnu")
474  * End:
475  */