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