vcom_socket.h revision 1431306b
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
30typedef enum
31{
32  SOCKET_TYPE_UNBOUND = 0,
33  SOCKET_TYPE_KERNEL_BOUND,
34  SOCKET_TYPE_VPPCOM_BOUND
35} vcom_socket_type_t;
36
37typedef enum
38{
39  EPOLL_TYPE_UNBOUND = 0,
40  EPOLL_TYPE_KERNEL_BOUND,
41  EPOLL_TYPE_VPPCOM_BOUND
42} vcom_epoll_type_t;
43
44typedef 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
55typedef 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
72typedef 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
106typedef 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
130typedef union vcom_epitem_key
131{
132  struct {
133  i32 fd;
134  i32 epfd;
135  };
136  i64 key;
137} __EPOLL_PACKED vcom_epitem_key_t;
138
139static inline char *
140vcom_socket_type_str (vcom_socket_type_t t)
141{
142  switch (t)
143    {
144    case SOCKET_TYPE_UNBOUND:
145      return "SOCKET_TYPE_UNBOUND";
146
147    case SOCKET_TYPE_KERNEL_BOUND:
148      return "SOCKET_TYPE_KERNEL_BOUND";
149
150    case SOCKET_TYPE_VPPCOM_BOUND:
151      return "SOCKET_TYPE_VPPCOM_BOUND";
152
153    default:
154      return "SOCKET_TYPE_UNKNOWN";
155    }
156}
157
158static inline char *
159vcom_socket_epoll_type_str (vcom_epoll_type_t t)
160{
161  switch (t)
162    {
163    case EPOLL_TYPE_UNBOUND:
164      return "EPOLL_TYPE_UNBOUND";
165
166    case EPOLL_TYPE_KERNEL_BOUND:
167      return "EPOLL_TYPE_KERNEL_BOUND";
168
169    case EPOLL_TYPE_VPPCOM_BOUND:
170      return "EPOLL_TYPE_VPPCOM_BOUND";
171
172    default:
173      return "EPOLL_TYPE_UNKNOWN";
174    }
175}
176
177static inline char *
178vcom_socket_vcom_fd_type_str (vcom_fd_type_t t)
179{
180  switch (t)
181    {
182    case FD_TYPE_KERNEL:
183      return "FD_TYPE_KERNEL";
184
185    case FD_TYPE_EPOLL:
186      return "FD_TYPE_EPOLL";
187
188    case FD_TYPE_VCOM_SOCKET:
189      return "FD_TYPE_VCOM_SOCKET";
190
191    default:
192      return "FD_TYPE_UNKNOWN";
193    }
194}
195
196static inline int
197vcom_socket_type_is_vppcom_bound (vcom_socket_type_t t)
198{
199  return t == SOCKET_TYPE_VPPCOM_BOUND;
200}
201
202static inline int
203vcom_socket_epoll_type_is_vppcom_bound (vcom_epoll_type_t t)
204{
205  return t == EPOLL_TYPE_VPPCOM_BOUND;
206}
207
208static inline void
209vsocket_init (vcom_socket_t * vsock)
210{
211  memset (vsock, 0, sizeof (*vsock));
212
213  vsock->fd = INVALID_FD;
214  vsock->sid = INVALID_SESSION_ID;
215  vsock->type = SOCKET_TYPE_UNBOUND;
216  /* vcom socket attributes init here */
217}
218
219static inline void
220vepoll_init (vcom_epoll_t * vepoll)
221{
222  memset (vepoll, 0, sizeof (*vepoll));
223
224  vepoll->epfd = INVALID_EPFD;
225  vepoll->vep_idx = INVALID_VEP_IDX;
226  vepoll->type = EPOLL_TYPE_UNBOUND;
227  vepoll->flags = 0;
228
229  vepoll->count = 0;
230  vepoll->close = 0;
231  /* vcom epoll attributes init here */
232}
233
234static inline void
235vepitem_init (vcom_epitem_t * vepitem)
236{
237  struct epoll_event event = {.events = 0, .data.fd = INVALID_FD};
238
239  memset (vepitem, 0, sizeof (*vepitem));
240
241  vepitem->epfd = INVALID_EPFD;
242
243  vepitem->fd = INVALID_FD;
244  vepitem->next_fd = INVALID_FD;
245  vepitem->prev_fd = INVALID_FD;
246
247  vepitem->type = FD_TYPE_INVALID;
248
249  vepitem->event = event;
250  vepitem->revent = event;
251  /* vepoll attributes init here */
252}
253
254static inline void
255vepitemkey_init (vcom_epitem_key_t * epfdfd)
256{
257  memset (epfdfd, 0, sizeof (*epfdfd));
258
259  epfdfd->epfd = INVALID_EPFD;
260  epfdfd->fd = INVALID_FD;
261}
262
263static inline void
264vsocket_set (vcom_socket_t * vsock,
265             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
273static inline void
274vepoll_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
288static inline void
289vepitem_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
308static inline void
309vepitemkey_set (vcom_epitem_key_t * epfdfd,
310                i32 epfd, i32 fd)
311{
312  epfdfd->epfd = epfd;
313  epfdfd->fd = fd;
314}
315
316static inline int
317vsocket_is_vppcom_bound (vcom_socket_t * vsock)
318{
319  return vcom_socket_type_is_vppcom_bound (vsock->type);
320}
321
322static inline int
323vepoll_is_vppcom_bound (vcom_epoll_t * vepoll)
324{
325  return vcom_socket_epoll_type_is_vppcom_bound (vepoll->type);
326}
327
328int vcom_socket_main_init (void);
329
330void vcom_socket_main_destroy (void);
331
332void vcom_socket_main_show (void);
333
334int vcom_socket_is_vcom_fd (int fd);
335
336int
337vcom_socket_is_vcom_epfd (int epfd);
338
339int vcom_socket_close (int __fd);
340
341ssize_t vcom_socket_read (int __fd, void *__buf, size_t __nbytes);
342
343ssize_t vcom_socket_write (int __fd, const void *__buf, size_t __n);
344
345int vcom_socket_fcntl_va (int __fd, int __cmd, va_list __ap);
346
347int
348vcom_socket_select (int vcom_nfds, fd_set * __restrict vcom_readfds,
349                    fd_set * __restrict vcom_writefds,
350                    fd_set * __restrict vcom_exceptfds,
351                    struct timeval *__restrict timeout);
352
353
354int vcom_socket_socket (int __domain, int __type, int __protocol);
355
356int
357vcom_socket_socketpair (int __domain, int __type, int __protocol,
358                        int __fds[2]);
359
360int vcom_socket_bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len);
361
362int
363vcom_socket_getsockname (int __fd, __SOCKADDR_ARG __addr,
364                         socklen_t * __restrict __len);
365
366int
367vcom_socket_connect (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len);
368
369int
370vcom_socket_getpeername (int __fd, __SOCKADDR_ARG __addr,
371                         socklen_t * __restrict __len);
372
373ssize_t
374vcom_socket_send (int __fd, const void *__buf, size_t __n, int __flags);
375
376ssize_t vcom_socket_recv (int __fd, void *__buf, size_t __n, int __flags);
377
378/*
379 * RETURN   1 if __fd is (SOCK_STREAM, SOCK_SEQPACKET),
380 * 0 otherwise
381 * */
382int vcom_socket_is_connection_mode_socket (int __fd);
383
384ssize_t
385vcom_socket_sendto (int __fd, const void *__buf, size_t __n,
386                    int __flags, __CONST_SOCKADDR_ARG __addr,
387                    socklen_t __addr_len);
388
389ssize_t
390vcom_socket_recvfrom (int __fd, void *__restrict __buf, size_t __n,
391                      int __flags, __SOCKADDR_ARG __addr,
392                      socklen_t * __restrict __addr_len);
393
394ssize_t
395vcom_socket_sendmsg (int __fd, const struct msghdr *__message, int __flags);
396
397#ifdef __USE_GNU
398int
399vcom_socket_sendmmsg (int __fd, struct mmsghdr *__vmessages,
400                      unsigned int __vlen, int __flags);
401#endif
402
403ssize_t vcom_socket_recvmsg (int __fd, struct msghdr *__message, int __flags);
404
405#ifdef __USE_GNU
406int
407vcom_socket_recvmmsg (int __fd, struct mmsghdr *__vmessages,
408                      unsigned int __vlen, int __flags,
409                      struct timespec *__tmo);
410#endif
411
412int
413vcom_socket_getsockopt (int __fd, int __level, int __optname,
414                        void *__restrict __optval,
415                        socklen_t * __restrict __optlen);
416
417int
418vcom_socket_setsockopt (int __fd, int __level, int __optname,
419                        const void *__optval, socklen_t __optlen);
420
421int vcom_socket_listen (int __fd, int __n);
422
423int
424vcom_socket_accept (int __fd, __SOCKADDR_ARG __addr,
425                    socklen_t * __restrict __addr_len);
426
427#ifdef __USE_GNU
428int
429vcom_socket_accept4 (int __fd, __SOCKADDR_ARG __addr,
430                     socklen_t * __restrict __addr_len, int __flags);
431#endif
432
433int vcom_socket_shutdown (int __fd, int __how);
434
435int
436vcom_socket_epoll_create1 (int __flags);
437
438int
439vcom_socket_epoll_ctl (int __epfd, int __op, int __fd,
440                       struct epoll_event *__event);
441
442int
443vcom_socket_epoll_pwait (int __epfd, struct epoll_event *__events,
444                         int __maxevents, int __timeout,
445                         const __sigset_t *__ss);
446
447#endif /* included_vcom_socket_h */
448
449/*
450 * fd.io coding-style-patch-verification: ON
451 *
452 * Local Variables:
453 * eval: (c-set-style "gnu")
454 * End:
455 */
456