> +        retval = recvmsg(sock, &msg, 0);
> +    } while (retval < 0 && errno == EINTR);
> +    if (retval <= 0) {
> +        return retval < 0 ? -errno : 0;
> +    }
> +
> +    for (p = CMSG_FIRSTHDR(&msg); p; p = CMSG_NXTHDR(&msg, p)) {
> +        if (p->cmsg_level != SOL_SOCKET || p->cmsg_type != SCM_RIGHTS) {
> +            VLOG_ERR("unexpected control message %d:%d",
> +                     (int) p->cmsg_level, (int) p->cmsg_type);

Are the casts necessary here?  At least in the sparse version of the
header the type is int.

> +            goto error;
> +        } else if (*n_fdsp) {
> +            VLOG_ERR("multiple SCM_RIGHTS received");
> +            goto error;
> +        } else {
> +            size_t n_fds = (p->cmsg_len - CMSG_LEN(0)) / sizeof *fds;
> +            const int *fds_data = (const int *) CMSG_DATA(p);
> +
> +            assert(n_fds > 0);
> +            if (n_fds > SOUTIL_MAX_FDS) {
> +                VLOG_ERR("%zu fds received but only %d supported",
> +                         n_fds, SOUTIL_MAX_FDS);
> +                for (i = 0; i < n_fds; i++) {
> +                    close(fds_data[i]);
> +                }
> +                goto error;
> +            }
> +
> +            *n_fdsp = n_fds;
> +            memcpy(fds, fds_data, n_fds * sizeof *fds);
> +        }
> +    }
> +
> +    return retval;
> +
> +error:

> +    for (i = 0; i < *n_fdsp; i++) {
> +        close(fds[i]);
> +    }

This doesn't seem right to me.  fds is only written to when there's no
error.  Really this should be closing the file descriptors in
fds_data, but that's done already.  If it turns out this is
unnecessary we can probably remove the goto altogether and just use
return EPROTO.

Ethan

> +    *n_fdsp = 0;
> +    return EPROTO;
> +}
> diff --git a/lib/socket-util.h b/lib/socket-util.h
> index e2e0d9a..a0e7970 100644
> --- a/lib/socket-util.h
> +++ b/lib/socket-util.h
> @@ -71,4 +71,28 @@ char *describe_fd(int fd);
>  * in <netinet/ip.h> is used. */
>  #define DSCP_DEFAULT (IPTOS_PREC_INTERNETCONTROL >> 2)
>
> +/* Maximum number of fds that we support sending or receiving at one time
> + * across a Unix domain socket. */
> +#define SOUTIL_MAX_FDS 8
> +
> +/* Iovecs. */
> +size_t iovec_len(const struct iovec *iovs, size_t n_iovs);
> +bool iovec_is_empty(const struct iovec *iovs, size_t n_iovs);
> +
> +/* Functions particularly useful for Unix domain sockets. */
> +void xsocketpair(int domain, int type, int protocol, int fds[2]);
> +int send_iovec_and_fds(int sock,
> +                       const struct iovec *iovs, size_t n_iovs,
> +                       const int fds[], size_t n_fds);
> +int send_iovec_and_fds_fully(int sock,
> +                             const struct iovec *iovs, size_t n_iovs,
> +                             const int fds[], size_t n_fds,
> +                             size_t skip_bytes, size_t *bytes_sent);
> +int send_iovec_and_fds_fully_block(int sock,
> +                                   const struct iovec *iovs, size_t n_iovs,
> +                                   const int fds[], size_t n_fds);
> +int recv_data_and_fds(int sock,
> +                      void *data, size_t size,
> +                      int fds[SOUTIL_MAX_FDS], size_t *n_fdsp);
> +
>  #endif /* socket-util.h */
> --
> 1.7.2.5
>
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev
_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to