/* * Copyright (c) 2017 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef included_vcom_socket_h #define included_vcom_socket_h #include <string.h> #include <vcl/vcom_glibc_socket.h> #include <vppinfra/types.h> #include <sys/socket.h> #define INVALID_SESSION_ID (~0) #define INVALID_FD (~0) #define INVALID_VEP_IDX INVALID_SESSION_ID #define INVALID_EPFD INVALID_FD typedef enum { SOCKET_TYPE_UNBOUND = 0, SOCKET_TYPE_KERNEL_BOUND, SOCKET_TYPE_VPPCOM_BOUND } vcom_socket_type_t; typedef enum { EPOLL_TYPE_UNBOUND = 0, EPOLL_TYPE_KERNEL_BOUND, EPOLL_TYPE_VPPCOM_BOUND } vcom_epoll_type_t; typedef enum { FD_TYPE_INVALID = 0, FD_TYPE_KERNEL, FD_TYPE_EPOLL, FD_TYPE_VCOM_SOCKET, /* add new types here */ /* FD_TYPE_MAX should be the last entry */ FD_TYPE_MAX } vcom_fd_type_t; typedef struct { /* file descriptor - * fd 0, 1, 2 have special meaning and are reserved, * -1 denote invalid fd */ i32 fd; /* session id - -1 denote invalid sid */ i32 sid; /* socket type */ vcom_socket_type_t type; /* vcom socket attributes here */ } vcom_socket_t; typedef struct { /* epoll file descriptor - * epfd 0, 1, 2 have special meaning and are reserved, * -1 denote invalid epfd */ i32 epfd; /* vep idx - -1 denote invalid vep_idx */ i32 vep_idx; /* epoll type */ vcom_epoll_type_t type; /* flags - 0 or EPOLL_CLOEXEC */ i32 flags; /* vcom epoll attributes here */ /* * 00. count of file descriptors currently registered * on this epoll instance. * 01. number of file descriptors in the epoll set. * 02. EPOLL_CTL_ADD, EPOLL_CTL_MOD, EPOLL_CTL_DEL * update the count. * 03. cached for frequent access. * */ i32 count; i32 vcl_cnt; i32 libc_cnt; /* close( ) called on this epoll instance */ /* 0 - close ( ) not called, 1 - close( ) called. */ u32 close; } vcom_epoll_t; typedef struct { /* "container" of this item */ i32 epfd; /* fd - file descriptor information this item refers to */ i32 fd; /* next and prev fd in the "epoll set" of epfd */ i32 next_fd; i32 prev_fd; /* vcom fd type */ vcom_fd_type_t type; /* interested events and the source fd */ struct epoll_event event; /* ready events and the source fd */ struct epoll_event revent; /* epitem attributes here */ } vcom_epitem_t; typedef union vcom_epitem_key { struct { i32 fd; i32 epfd; }; i64 key; } __EPOLL_PACKED vcom_epitem_key_t; static inline char * vcom_socket_type_str (vcom_socket_type_t t) { switch (t) { case SOCKET_TYPE_UNBOUND: return "SOCKET_TYPE_UNBOUND"; case SOCKET_TYPE_KERNEL_BOUND: return "SOCKET_TYPE_KERNEL_BOUND"; case SOCKET_TYPE_VPPCOM_BOUND: return "SOCKET_TYPE_VPPCOM_BOUND"; default: return "SOCKET_TYPE_UNKNOWN"; } } static inline char * vcom_socket_epoll_type_str (vcom_epoll_type_t t) { switch (t) { case EPOLL_TYPE_UNBOUND: return "EPOLL_TYPE_UNBOUND"; case EPOLL_TYPE_KERNEL_BOUND: return "EPOLL_TYPE_KERNEL_BOUND"; case EPOLL_TYPE_VPPCOM_BOUND: return "EPOLL_TYPE_VPPCOM_BOUND"; default: return "EPOLL_TYPE_UNKNOWN"; } } static inline char * vcom_socket_vcom_fd_type_str (vcom_fd_type_t t) { switch (t) { case FD_TYPE_KERNEL: return "FD_TYPE_KERNEL"; case FD_TYPE_EPOLL: return "FD_TYPE_EPOLL"; case FD_TYPE_VCOM_SOCKET: return "FD_TYPE_VCOM_SOCKET"; default: return "FD_TYPE_UNKNOWN"; } } static inline int vcom_socket_type_is_vppcom_bound (vcom_socket_type_t t) { return t == SOCKET_TYPE_VPPCOM_BOUND; } static inline int vcom_socket_epoll_type_is_vppcom_bound (vcom_epoll_type_t t) { return t == EPOLL_TYPE_VPPCOM_BOUND; } static inline void vsocket_init (vcom_socket_t * vsock) { memset (vsock, 0, sizeof (*vsock)); vsock->fd = INVALID_FD; vsock->sid = INVALID_SESSION_ID; vsock->type = SOCKET_TYPE_UNBOUND; /* vcom socket attributes init here */ } static inline void vepoll_init (vcom_epoll_t * vepoll) { memset (vepoll, 0, sizeof (*vepoll)); vepoll->epfd = INVALID_EPFD; vepoll->vep_idx = INVALID_VEP_IDX; vepoll->type = EPOLL_TYPE_UNBOUND; vepoll->flags = 0; vepoll->count = 0; vepoll->close = 0; /* vcom epoll attributes init here */ } static inline void vepitem_init (vcom_epitem_t * vepitem) { struct epoll_event event = {.events = 0,.data.fd = INVALID_FD }; memset (vepitem, 0, sizeof (*vepitem)); vepitem->epfd = INVALID_EPFD; vepitem->fd = INVALID_FD; vepitem->next_fd = INVALID_FD; vepitem->prev_fd = INVALID_FD; vepitem->type = FD_TYPE_INVALID; vepitem->event = event; vepitem->revent = event; /* vepoll attributes init here */ } static inline void vepitemkey_init (vcom_epitem_key_t * epfdfd) { memset (epfdfd, 0, sizeof (*epfdfd)); epfdfd->epfd = INVALID_EPFD; epfdfd->fd = INVALID_FD; } static inline void vsocket_set (vcom_socket_t * vsock, i32 fd, i32 sid, vcom_socket_type_t type) { vsock->fd = fd; vsock->sid = sid; vsock->type = type; /* vcom socket attributes set here */ } static inline void vepoll_set (vcom_epoll_t * vepoll, i32 epfd, i32 vep_idx, vcom_epoll_type_t type, i32 flags, i32 count, u32 close) { vepoll->epfd = epfd; vepoll->vep_idx = vep_idx; vepoll->type = type; vepoll->flags = flags; vepoll->count = count; vepoll->close = close; /* vcom epoll attributes set here */ } static inline void vepitem_set (vcom_epitem_t * vepitem, i32 epfd, i32 fd, i32 next_fd, i32 prev_fd, vcom_fd_type_t type, struct epoll_event event, struct epoll_event revent) { vepitem->epfd = epfd; vepitem->fd = fd; vepitem->next_fd = next_fd; vepitem->prev_fd = prev_fd; vepitem->type = type; vepitem->event = event; vepitem->revent = revent; /* vcom epitem attributes set here */ } static inline void vepitemkey_set (vcom_epitem_key_t * epfdfd, i32 epfd, i32 fd) { epfdfd->epfd = epfd; epfdfd->fd = fd; } static inline int vsocket_is_vppcom_bound (vcom_socket_t * vsock) { return vcom_socket_type_is_vppcom_bound (vsock->type); } static inline int vepoll_is_vppcom_bound (vcom_epoll_t * vepoll) { return vcom_socket_epoll_type_is_vppcom_bound (vepoll->type); } int vcom_socket_main_init (void); void vcom_socket_main_destroy (void); void vcom_socket_main_show (void); int vcom_socket_is_vcom_fd (int fd); int vcom_socket_is_vcom_epfd (int epfd); int vcom_socket_close (int __fd); ssize_t vcom_socket_read (int __fd, void *__buf, size_t __nbytes); ssize_t vcom_socket_readv (int __fd, const struct iovec *__iov, int __iovcnt); ssize_t vcom_socket_write (int __fd, const void *__buf, size_t __n); ssize_t vcom_socket_writev (int __fd, const struct iovec *__iov, int __iovcnt); int vcom_socket_fcntl_va (int __fd, int __cmd, va_list __ap); int vcom_socket_ioctl_va (int __fd, unsigned long int __cmd, va_list __ap); int vcom_socket_select (int vcom_nfds, fd_set * __restrict vcom_readfds, fd_set * __restrict vcom_writefds, fd_set * __restrict vcom_exceptfds, struct timeval *__restrict timeout); int vcom_socket_socket (int __domain, int __type, int __protocol); int vcom_socket_socketpair (int __domain, int __type, int __protocol, int __fds[2]); int vcom_socket_bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len); int vcom_socket_getsockname (int __fd, __SOCKADDR_ARG __addr, socklen_t * __restrict __len); int vcom_socket_connect (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len); int vcom_socket_getpeername (int __fd, __SOCKADDR_ARG __addr, socklen_t * __restrict __len); ssize_t vcom_socket_send (int __fd, const void *__buf, size_t __n, int __flags); ssize_t vcom_socket_recv (int __fd, void *__buf, size_t __n, int __flags); ssize_t vcom_socket_sendfile (int __out_fd, int __in_fd, off_t * __offset, size_t __len); /* * RETURN 1 if __fd is (SOCK_STREAM, SOCK_SEQPACKET), * 0 otherwise * */ int vcom_socket_is_connection_mode_socket (int __fd); ssize_t vcom_socket_sendto (int __fd, const void *__buf, size_t __n, int __flags, __CONST_SOCKADDR_ARG __addr, socklen_t __addr_len); ssize_t vcom_socket_recvfrom (int __fd, void *__restrict __buf, size_t __n, int __flags, __SOCKADDR_ARG __addr, socklen_t * __restrict __addr_len); ssize_t vcom_socket_sendmsg (int __fd, const struct msghdr *__message, int __flags); #ifdef __USE_GNU int vcom_socket_sendmmsg (int __fd, struct mmsghdr *__vmessages, unsigned int __vlen, int __flags); #endif ssize_t vcom_socket_recvmsg (int __fd, struct msghdr *__message, int __flags); #ifdef __USE_GNU int vcom_socket_recvmmsg (int __fd, struct mmsghdr *__vmessages, unsigned int __vlen, int __flags, struct timespec *__tmo); #endif int vcom_socket_getsockopt (int __fd, int __level, int __optname, void *__restrict __optval, socklen_t * __restrict __optlen); int vcom_socket_setsockopt (int __fd, int __level, int __optname, const void *__optval, socklen_t __optlen); int vcom_socket_listen (int __fd, int __n); int vcom_socket_accept (int __fd, __SOCKADDR_ARG __addr, socklen_t * __restrict __addr_len); int vcom_socket_accept4 (int __fd, __SOCKADDR_ARG __addr, socklen_t * __restrict __addr_len, int __flags); int vcom_socket_shutdown (int __fd, int __how); int vcom_socket_epoll_create1 (int __flags); int vcom_socket_epoll_ctl (int __epfd, int __op, int __fd, struct epoll_event *__event); int vcom_socket_epoll_pwait (int __epfd, struct epoll_event *__events, int __maxevents, int __timeout, const __sigset_t * __ss); /* * handle only vcom fds */ int vcom_socket_poll (struct pollfd *__fds, nfds_t __nfds, int __timeout); #ifdef __USE_GNU int vcom_socket_ppoll (struct pollfd *__fds, nfds_t __nfds, const struct timespec *__timeout, const __sigset_t * __ss); #endif #endif /* included_vcom_socket_h */ /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */