X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvcl%2Fvcom_socket.c;h=5918f6b73d132a24677765e28036c53dea9277d7;hb=faf9d7730828b80814a233eeecf7affc046193d3;hp=8806ebd011a3c781525b4b734e6f2123447892d6;hpb=5c7cf1cc5358d137160be1619981e7eea9a7402f;p=vpp.git diff --git a/src/vcl/vcom_socket.c b/src/vcl/vcom_socket.c index 8806ebd011a..5918f6b73d1 100644 --- a/src/vcl/vcom_socket.c +++ b/src/vcl/vcom_socket.c @@ -465,6 +465,7 @@ vcom_socket_read (int __fd, void *__buf, size_t __nbytes) { rv = vppcom_session_read (vsock->sid, __buf, __nbytes); } + /* coverity[CONSTANT_EXPRESSION_RESULT] */ while (rv == -EAGAIN || rv == -EWOULDBLOCK); return rv; } @@ -535,6 +536,7 @@ vcom_socket_readv (int __fd, const struct iovec * __iov, int __iovcnt) } } } + /* coverity[CONSTANT_EXPRESSION_RESULT] */ while ((rv == -EAGAIN || rv == -EWOULDBLOCK) && total == 0); return total; } @@ -1510,11 +1512,38 @@ vcom_session_sendto (int __sid, void *__buf, size_t __n, int __flags, __CONST_SOCKADDR_ARG __addr, socklen_t __addr_len) { - int rv = -1; - /* TBD add new vpp api */ - /* TBD add flags parameter */ - rv = vppcom_session_write (__sid, (void *) __buf, (int) __n); - return rv; + vppcom_endpt_t *ep = 0; + + if (__addr) + { + vppcom_endpt_t _ep; + + ep = &_ep; + ep->vrf = VPPCOM_VRF_DEFAULT; + switch (__addr->sa_family) + { + case AF_INET: + ep->is_ip4 = VPPCOM_IS_IP4; + ep->ip = + (uint8_t *) & ((const struct sockaddr_in *) __addr)->sin_addr; + ep->port = + (uint16_t) ((const struct sockaddr_in *) __addr)->sin_port; + break; + + case AF_INET6: + ep->is_ip4 = VPPCOM_IS_IP6; + ep->ip = + (uint8_t *) & ((const struct sockaddr_in6 *) __addr)->sin6_addr; + ep->port = + (uint16_t) ((const struct sockaddr_in6 *) __addr)->sin6_port; + break; + + default: + return -EAFNOSUPPORT; + } + } + + return vppcom_session_sendto (__sid, __buf, __n, __flags, ep);; } ssize_t @@ -1522,7 +1551,6 @@ vcom_socket_sendto (int __fd, const void *__buf, size_t __n, int __flags, __CONST_SOCKADDR_ARG __addr, socklen_t __addr_len) { - int rv = -1; vcom_socket_main_t *vsm = &vcom_socket_main; uword *p; vcom_socket_t *vsock; @@ -1561,15 +1589,15 @@ vcom_socket_sendto (int __fd, const void *__buf, size_t __n, return -EDESTADDRREQ; } /* not a vppcom supported address family */ - if ((__addr->sa_family != AF_INET) || (__addr->sa_family != AF_INET6)) + if (!((__addr->sa_family == AF_INET) || + (__addr->sa_family == AF_INET6))) { return -EINVAL; } } - rv = vcom_session_sendto (vsock->sid, (void *) __buf, (int) __n, - __flags, __addr, __addr_len); - return rv; + return vcom_session_sendto (vsock->sid, (void *) __buf, (int) __n, + __flags, __addr, __addr_len); } static inline ssize_t @@ -1577,10 +1605,51 @@ vcom_session_recvfrom (int __sid, void *__restrict __buf, size_t __n, int __flags, __SOCKADDR_ARG __addr, socklen_t * __restrict __addr_len) { - int rv = -1; + int rv; + vppcom_endpt_t ep; + u8 src_addr[sizeof (struct sockaddr_in6)]; + + if (__addr) + { + ep.ip = src_addr; + rv = vppcom_session_recvfrom (__sid, __buf, __n, __flags, &ep); + + if (rv > 0) + { + if (ep.vrf == VPPCOM_VRF_DEFAULT) + { + __addr->sa_family = + ep.is_ip4 == VPPCOM_IS_IP4 ? AF_INET : AF_INET6; + switch (__addr->sa_family) + { + case AF_INET: + ((struct sockaddr_in *) __addr)->sin_port = ep.port; + memcpy (&((struct sockaddr_in *) __addr)->sin_addr, + src_addr, sizeof (struct in_addr)); + + *__addr_len = sizeof (struct sockaddr_in); + break; + + case AF_INET6: + ((struct sockaddr_in6 *) __addr)->sin6_port = ep.port; + memcpy (((struct sockaddr_in6 *) __addr)->sin6_addr. + __in6_u.__u6_addr8, src_addr, + sizeof (struct in6_addr)); + *__addr_len = sizeof (struct sockaddr_in6); + break; + + default: + rv = -EAFNOSUPPORT; + break; + } + } + else + rv = -1; + } + } + else + rv = vppcom_session_recvfrom (__sid, __buf, __n, __flags, NULL); - /* TBD add flags parameter */ - rv = vppcom_session_read (__sid, __buf, __n); return rv; } @@ -1594,10 +1663,8 @@ vcom_socket_recvfrom (int __fd, void *__restrict __buf, size_t __n, uword *p; vcom_socket_t *vsock; - if (!__buf || !__addr || !__addr_len) - { - return -EINVAL; - } + if (__addr && !__addr_len) + return -EINVAL; p = hash_get (vsm->sockidx_by_fd, __fd); if (!p) @@ -1734,9 +1801,26 @@ vcom_session_get_sockopt (int __sid, int __level, int __optname, void *__restrict __optval, socklen_t * __restrict __optlen) { + int rv = 0; + /* 1. for socket level options that are NOT socket attributes * and that has corresponding vpp options get from vppcom */ - return 0; + switch (__level) + { + case SOL_SOCKET: + switch (__optname) + { + case SO_ERROR: + *(int *) __optval = 0; + break; + default: + break; + } + default: + break; + } + /* 2. unhandled options */ + return rv; } int @@ -1749,6 +1833,9 @@ vcom_socket_getsockopt (int __fd, int __level, int __optname, uword *p; vcom_socket_t *vsock; + if (!__optval || !__optlen) + return -EINVAL; + p = hash_get (vsm->sockidx_by_fd, __fd); if (!p) return -EBADF; @@ -1760,12 +1847,8 @@ vcom_socket_getsockopt (int __fd, int __level, int __optname, if (vsock->type != SOCKET_TYPE_VPPCOM_BOUND) return -EINVAL; - if (!__optval && !__optlen) - return -EFAULT; - switch (__level) { - /* handle options at socket level */ case SOL_SOCKET: switch (__optname) { @@ -1788,7 +1871,6 @@ vcom_socket_getsockopt (int __fd, int __level, int __optname, case SO_TYPE: case SO_PROTOCOL: case SO_DOMAIN: - case SO_ERROR: case SO_OOBINLINE: case SO_NO_CHECK: case SO_PRIORITY: @@ -1832,6 +1914,11 @@ vcom_socket_getsockopt (int __fd, int __level, int __optname, } break; + case SO_ERROR: + rv = vcom_session_get_sockopt (vsock->sid, __level, __optname, + __optval, __optlen); + break; + default: /* We implement the SO_SNDLOWAT etc to not be settable * (1003.1g 7). @@ -3151,13 +3238,9 @@ vcom_socket_poll_vppcom_impl (struct pollfd *__fds, nfds_t __nfds, { time_to_wait = (double) 0; } - else if (__timeout < 0) - { - time_to_wait = ~0; - } else { - return -EBADF; + time_to_wait = ~0; } return vppcom_poll (__fds, __nfds, time_to_wait); @@ -3332,9 +3415,10 @@ vcom_socket_main_destroy (void) /* *INDENT-OFF* */ pool_flush (vepitem, vsm->vepitems, ({ - if (vepitem->type == FD_TYPE_EPOLL || FD_TYPE_VCOM_SOCKET) + if ((vepitem->type == FD_TYPE_EPOLL) || + (vepitem->type == FD_TYPE_VCOM_SOCKET)) { - vcom_socket_epoll_ctl1 (vepitem->epfd, EPOLL_CTL_DEL, + vcom_socket_epoll_ctl1 (vepitem->epfd, EPOLL_CTL_DEL, vepitem->fd, NULL); vepitem_init (vepitem); }