From 6364a07adde1072d595044a19359e61fc27940dd Mon Sep 17 00:00:00 2001 From: David Goulet Date: Thu, 14 Jun 2012 14:48:49 -0400 Subject: [PATCH] Add network transport layer to sessiond-comm Only import the library files in sessiond-comm/ directory for network communication supporting both TCP and UDP protocols with IPv4 and IPv6. First layer needed for network streaming and communication with the upcoming lttng-relayd daemon. Signed-off-by: David Goulet --- src/common/sessiond-comm/Makefile.am | 2 +- src/common/sessiond-comm/inet.c | 291 +++++++++++++++++++++++ src/common/sessiond-comm/inet.h | 44 ++++ src/common/sessiond-comm/inet6.c | 291 +++++++++++++++++++++++ src/common/sessiond-comm/inet6.h | 45 ++++ src/common/sessiond-comm/sessiond-comm.c | 150 ++++++++++++ src/common/sessiond-comm/sessiond-comm.h | 62 +++++ tests/kernel/Makefile.am | 4 +- tests/ust/Makefile.am | 4 +- 9 files changed, 890 insertions(+), 3 deletions(-) create mode 100644 src/common/sessiond-comm/inet.c create mode 100644 src/common/sessiond-comm/inet.h create mode 100644 src/common/sessiond-comm/inet6.c create mode 100644 src/common/sessiond-comm/inet6.h diff --git a/src/common/sessiond-comm/Makefile.am b/src/common/sessiond-comm/Makefile.am index c0beee01e..1c73dcb9e 100644 --- a/src/common/sessiond-comm/Makefile.am +++ b/src/common/sessiond-comm/Makefile.am @@ -2,5 +2,5 @@ noinst_LTLIBRARIES = libsessiond-comm.la libsessiond_comm_la_SOURCES = sessiond-comm.c sessiond-comm.h \ - unix.c unix.h + unix.c unix.h inet.c inet.h inet6.c inet6.h diff --git a/src/common/sessiond-comm/inet.c b/src/common/sessiond-comm/inet.c new file mode 100644 index 000000000..51ac670f2 --- /dev/null +++ b/src/common/sessiond-comm/inet.c @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2012 - David Goulet + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License, version 2 only, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "inet.h" + +/* + * INET protocol operations. + */ +static const struct lttcomm_proto_ops inet_ops = { + .bind = lttcomm_bind_inet_sock, + .close = lttcomm_close_inet_sock, + .connect = lttcomm_connect_inet_sock, + .accept = lttcomm_accept_inet_sock, + .listen = lttcomm_listen_inet_sock, + .recvmsg = lttcomm_recvmsg_inet_sock, + .sendmsg = lttcomm_sendmsg_inet_sock, +}; + +/* + * Creates an PF_INET socket. + */ +int lttcomm_create_inet_sock(struct lttcomm_sock *sock, int type, int proto) +{ + int val, ret; + + /* Create server socket */ + if ((sock->fd = socket(PF_INET, type, proto)) < 0) { + PERROR("socket inet"); + goto error; + } + + sock->ops = &inet_ops; + + /* + * Set socket option to reuse the address. + */ + ret = setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(int)); + if (ret < 0) { + PERROR("setsockopt inet"); + goto error; + } + + return 0; + +error: + return -1; +} + +/* + * Bind socket and return. + */ +int lttcomm_bind_inet_sock(struct lttcomm_sock *sock) +{ + int ret; + + ret = bind(sock->fd, &sock->sockaddr.addr.sin, + sizeof(sock->sockaddr.addr.sin)); + if (ret < 0) { + PERROR("bind inet"); + } + + return ret; +} + +/* + * Connect PF_INET socket. + */ +int lttcomm_connect_inet_sock(struct lttcomm_sock *sock) +{ + int ret, closeret; + + ret = connect(sock->fd, (struct sockaddr *) &sock->sockaddr.addr.sin, + sizeof(sock->sockaddr.addr.sin)); + if (ret < 0) { + /* + * Don't print message on connect error, because connect is used in + * normal execution to detect if sessiond is alive. + */ + goto error_connect; + } + + return ret; + +error_connect: + closeret = close(sock->fd); + if (closeret) { + PERROR("close inet"); + } + + return ret; +} + +/* + * Do an accept(2) on the sock and return the new lttcomm socket. The socket + * MUST be bind(2) before. + */ +struct lttcomm_sock *lttcomm_accept_inet_sock(struct lttcomm_sock *sock) +{ + int new_fd; + socklen_t len = 0; + struct lttcomm_sock *new_sock; + + if (sock->proto == LTTCOMM_SOCK_UDP) { + /* + * accept(2) does not exist for UDP so simply return the passed socket. + */ + new_sock = sock; + goto end; + } + + new_sock = lttcomm_alloc_sock(LTTCOMM_INET, sock->proto); + if (new_sock == NULL) { + goto error; + } + + /* Blocking call */ + new_fd = accept(sock->fd, (struct sockaddr *) &new_sock->sockaddr.addr.sin, + &len); + if (new_fd < 0) { + PERROR("accept inet"); + goto error; + } + + new_sock->fd = new_fd; + +end: + return new_sock; + +error: + free(new_sock); + return NULL; +} + +/* + * Make the socket listen using LTTNG_SESSIOND_COMM_MAX_LISTEN. + */ +int lttcomm_listen_inet_sock(struct lttcomm_sock *sock, int backlog) +{ + int ret; + + if (sock->proto == LTTCOMM_SOCK_UDP) { + /* listen(2) does not exist for UDP so simply return success. */ + ret = 0; + goto end; + } + + /* Default listen backlog */ + if (backlog <= 0) { + backlog = LTTNG_SESSIOND_COMM_MAX_LISTEN; + } + + ret = listen(sock->fd, backlog); + if (ret < 0) { + PERROR("listen inet"); + } + +end: + return ret; +} + +/* + * Receive data of size len in put that data into the buf param. Using recvmsg + * API. + * + * Return the size of received data. + */ +ssize_t lttcomm_recvmsg_inet_sock(struct lttcomm_sock *sock, void *buf, + size_t len, int flags) +{ + struct msghdr msg; + struct iovec iov[1]; + ssize_t ret = -1; + + memset(&msg, 0, sizeof(msg)); + + iov[0].iov_base = buf; + iov[0].iov_len = len; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + + msg.msg_name = (struct sockaddr *) &sock->sockaddr.addr.sin; + msg.msg_namelen = sizeof(sock->sockaddr.addr.sin); + + if (flags == 0) { + flags = MSG_WAITALL; + } + + do { + ret = recvmsg(sock->fd, &msg, flags); + } while (ret < 0 && errno == EINTR); + if (ret < 0) { + PERROR("recvmsg inet"); + } + + return ret; +} + +/* + * Send buf data of size len. Using sendmsg API. + * + * Return the size of sent data. + */ +ssize_t lttcomm_sendmsg_inet_sock(struct lttcomm_sock *sock, void *buf, + size_t len, int flags) +{ + struct msghdr msg; + struct iovec iov[1]; + ssize_t ret = -1; + + memset(&msg, 0, sizeof(msg)); + + iov[0].iov_base = buf; + iov[0].iov_len = len; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + + switch (sock->proto) { + case LTTCOMM_SOCK_UDP: + msg.msg_name = (struct sockaddr *) &sock->sockaddr.addr.sin; + msg.msg_namelen = sizeof(sock->sockaddr.addr.sin); + break; + default: + break; + } + + do { + ret = sendmsg(sock->fd, &msg, flags); + } while (ret < 0 && errno == EINTR); + if (ret < 0) { + /* + * Only warn about EPIPE when quiet mode is deactivated. + * We consider EPIPE as expected. + */ + if (errno != EPIPE || !lttng_opt_quiet) { + PERROR("sendmsg inet"); + } + } + + return ret; +} + +/* + * Shutdown cleanly and close. + */ +int lttcomm_close_inet_sock(struct lttcomm_sock *sock) +{ + int ret, closeret; + + /* Don't try to close an invalid mark socket */ + if (sock->fd == -1) { + return 0; + } + + closeret = close(sock->fd); + if (closeret) { + PERROR("close inet"); + } + + /* Mark socket */ + sock->fd = -1; + + return ret; +} diff --git a/src/common/sessiond-comm/inet.h b/src/common/sessiond-comm/inet.h new file mode 100644 index 000000000..89716b8ba --- /dev/null +++ b/src/common/sessiond-comm/inet.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2012 - David Goulet + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License, version 2 only, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef _LTTCOMM_INET_H +#define _LTTCOMM_INET_H + +#define _GNU_SOURCE +#include + +#include "sessiond-comm.h" + +/* Stub */ +struct lttcomm_sock; + +/* Net family callback */ +extern int lttcomm_create_inet_sock(struct lttcomm_sock *sock, int type, + int proto); + +extern struct lttcomm_sock *lttcomm_accept_inet_sock(struct lttcomm_sock *sock); +extern int lttcomm_bind_inet_sock(struct lttcomm_sock *sock); +extern int lttcomm_close_inet_sock(struct lttcomm_sock *sock); +extern int lttcomm_connect_inet_sock(struct lttcomm_sock *sock); +extern int lttcomm_listen_inet_sock(struct lttcomm_sock *sock, int backlog); + +extern ssize_t lttcomm_recvmsg_inet_sock(struct lttcomm_sock *sock, void *buf, + size_t len, int flags); +extern ssize_t lttcomm_sendmsg_inet_sock(struct lttcomm_sock *sock, void *buf, + size_t len, int flags); + +#endif /* _LTTCOMM_INET_H */ diff --git a/src/common/sessiond-comm/inet6.c b/src/common/sessiond-comm/inet6.c new file mode 100644 index 000000000..38822ca63 --- /dev/null +++ b/src/common/sessiond-comm/inet6.c @@ -0,0 +1,291 @@ +/* + * Copyright (C) 2012 - David Goulet + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License, version 2 only, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "inet6.h" + +/* + * INET protocol operations. + */ +static const struct lttcomm_proto_ops inet6_ops = { + .bind = lttcomm_bind_inet6_sock, + .close = lttcomm_close_inet6_sock, + .connect = lttcomm_connect_inet6_sock, + .accept = lttcomm_accept_inet6_sock, + .listen = lttcomm_listen_inet6_sock, + .recvmsg = lttcomm_recvmsg_inet6_sock, + .sendmsg = lttcomm_sendmsg_inet6_sock, +}; + +/* + * Creates an PF_INET socket. + */ +int lttcomm_create_inet6_sock(struct lttcomm_sock *sock, int type, int proto) +{ + int val, ret; + + /* Create server socket */ + if ((sock->fd = socket(PF_INET, type, proto)) < 0) { + PERROR("socket inet6"); + goto error; + } + + sock->ops = &inet6_ops; + + /* + * Set socket option to reuse the address. + */ + ret = setsockopt(sock->fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(int)); + if (ret < 0) { + PERROR("setsockopt inet6"); + goto error; + } + + return 0; + +error: + return -1; +} + +/* + * Bind socket and return. + */ +int lttcomm_bind_inet6_sock(struct lttcomm_sock *sock) +{ + int ret; + + ret = bind(sock->fd, &sock->sockaddr.addr.sin6, + sizeof(sock->sockaddr.addr.sin6)); + if (ret < 0) { + PERROR("bind inet6"); + } + + return ret; +} + +/* + * Connect PF_INET socket. + */ +int lttcomm_connect_inet6_sock(struct lttcomm_sock *sock) +{ + int ret, closeret; + + ret = connect(sock->fd, (struct sockaddr *) &sock->sockaddr.addr.sin6, + sizeof(sock->sockaddr.addr.sin6)); + if (ret < 0) { + /* + * Don't print message on connect error, because connect is used in + * normal execution to detect if sessiond is alive. + */ + goto error_connect; + } + + return ret; + +error_connect: + closeret = close(sock->fd); + if (closeret) { + PERROR("close inet6"); + } + + return ret; +} + +/* + * Do an accept(2) on the sock and return the new lttcomm socket. The socket + * MUST be bind(2) before. + */ +struct lttcomm_sock *lttcomm_accept_inet6_sock(struct lttcomm_sock *sock) +{ + int new_fd; + socklen_t len = 0; + struct lttcomm_sock *new_sock; + + if (sock->proto == LTTCOMM_SOCK_UDP) { + /* + * accept(2) does not exist for UDP so simply return the passed socket. + */ + new_sock = sock; + goto end; + } + + new_sock = lttcomm_alloc_sock(LTTCOMM_INET, sock->proto); + if (new_sock == NULL) { + goto error; + } + + /* Blocking call */ + new_fd = accept(sock->fd, + (struct sockaddr *) &new_sock->sockaddr.addr.sin6, &len); + if (new_fd < 0) { + PERROR("accept inet6"); + goto error; + } + + new_sock->fd = new_fd; + +end: + return new_sock; + +error: + free(new_sock); + return NULL; +} + +/* + * Make the socket listen using LTTNG_SESSIOND_COMM_MAX_LISTEN. + */ +int lttcomm_listen_inet6_sock(struct lttcomm_sock *sock, int backlog) +{ + int ret; + + if (sock->proto == LTTCOMM_SOCK_UDP) { + /* listen(2) does not exist for UDP so simply return success. */ + ret = 0; + goto end; + } + + /* Default listen backlog */ + if (backlog <= 0) { + backlog = LTTNG_SESSIOND_COMM_MAX_LISTEN; + } + + ret = listen(sock->fd, backlog); + if (ret < 0) { + PERROR("listen inet6"); + } + +end: + return ret; +} + +/* + * Receive data of size len in put that data into the buf param. Using recvmsg + * API. + * + * Return the size of received data. + */ +ssize_t lttcomm_recvmsg_inet6_sock(struct lttcomm_sock *sock, void *buf, + size_t len, int flags) +{ + struct msghdr msg; + struct iovec iov[1]; + ssize_t ret = -1; + + memset(&msg, 0, sizeof(msg)); + + iov[0].iov_base = buf; + iov[0].iov_len = len; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + + msg.msg_name = (struct sockaddr *) &sock->sockaddr.addr.sin6; + msg.msg_namelen = sizeof(sock->sockaddr.addr.sin6); + + if (flags == 0) { + flags = MSG_WAITALL; + } + + do { + ret = recvmsg(sock->fd, &msg, flags); + } while (ret < 0 && errno == EINTR); + if (ret < 0) { + PERROR("recvmsg inet6"); + } + + return ret; +} + +/* + * Send buf data of size len. Using sendmsg API. + * + * Return the size of sent data. + */ +ssize_t lttcomm_sendmsg_inet6_sock(struct lttcomm_sock *sock, void *buf, + size_t len, int flags) +{ + struct msghdr msg; + struct iovec iov[1]; + ssize_t ret = -1; + + memset(&msg, 0, sizeof(msg)); + + iov[0].iov_base = buf; + iov[0].iov_len = len; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + + switch (sock->proto) { + case LTTCOMM_SOCK_UDP: + msg.msg_name = (struct sockaddr *) &sock->sockaddr.addr.sin6; + msg.msg_namelen = sizeof(sock->sockaddr.addr.sin6); + break; + default: + break; + } + + do { + ret = sendmsg(sock->fd, &msg, flags); + } while (ret < 0 && errno == EINTR); + if (ret < 0) { + /* + * Only warn about EPIPE when quiet mode is deactivated. + * We consider EPIPE as expected. + */ + if (errno != EPIPE || !lttng_opt_quiet) { + PERROR("sendmsg inet6"); + } + } + + return ret; +} + +/* + * Shutdown cleanly and close. + */ +int lttcomm_close_inet6_sock(struct lttcomm_sock *sock) +{ + int ret, closeret; + + /* Don't try to close an invalid mark socket */ + if (sock->fd == -1) { + return 0; + } + + closeret = close(sock->fd); + if (closeret) { + PERROR("close inet6"); + } + + /* Mark socket */ + sock->fd = -1; + + return ret; +} diff --git a/src/common/sessiond-comm/inet6.h b/src/common/sessiond-comm/inet6.h new file mode 100644 index 000000000..4cb4dca3e --- /dev/null +++ b/src/common/sessiond-comm/inet6.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2012 - David Goulet + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License, version 2 only, as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 51 + * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef _LTTCOMM_INET6_H +#define _LTTCOMM_INET6_H + +#define _GNU_SOURCE +#include + +#include "sessiond-comm.h" + +/* Stub */ +struct lttcomm_sock; + +/* Net family callback */ +extern int lttcomm_create_inet6_sock(struct lttcomm_sock *sock, int type, + int proto); + +extern struct lttcomm_sock *lttcomm_accept_inet6_sock( + struct lttcomm_sock *sock); +extern int lttcomm_bind_inet6_sock(struct lttcomm_sock *sock); +extern int lttcomm_close_inet6_sock(struct lttcomm_sock *sock); +extern int lttcomm_connect_inet6_sock(struct lttcomm_sock *sock); +extern int lttcomm_listen_inet6_sock(struct lttcomm_sock *sock, int backlog); + +extern ssize_t lttcomm_recvmsg_inet6_sock(struct lttcomm_sock *sock, void *buf, + size_t len, int flags); +extern ssize_t lttcomm_sendmsg_inet6_sock(struct lttcomm_sock *sock, void *buf, + size_t len, int flags); + +#endif /* _LTTCOMM_INET6_H */ diff --git a/src/common/sessiond-comm/sessiond-comm.c b/src/common/sessiond-comm/sessiond-comm.c index 706b8a7cd..eaa14a549 100644 --- a/src/common/sessiond-comm/sessiond-comm.c +++ b/src/common/sessiond-comm/sessiond-comm.c @@ -32,6 +32,18 @@ #include "sessiond-comm.h" +/* For Unix socket */ +#include "unix.h" +/* For Inet socket */ +#include "inet.h" +/* For Inet6 socket */ +#include "inet6.h" + +struct lttcomm_net_family net_families[] = { + { LTTCOMM_INET, lttcomm_create_inet_sock }, + { LTTCOMM_INET6, lttcomm_create_inet6_sock }, +}; + /* * Human readable error message. */ @@ -144,3 +156,141 @@ const char *lttcomm_get_readable_code(enum lttcomm_return_code code) return "Unknown error code"; } + +/* + * Alloc lttcomm socket and set protocol. + */ +static struct lttcomm_sock *alloc_sock(enum lttcomm_sock_proto proto) +{ + struct lttcomm_sock *sock; + + sock = zmalloc(sizeof(struct lttcomm_sock)); + if (sock == NULL) { + PERROR("zmalloc create sock"); + goto end; + } + + sock->proto = proto; + +end: + return sock; +} + +/* + * Create socket from an already allocated lttcomm socket structure. + */ +int lttcomm_create_sock(struct lttcomm_sock *sock, + enum lttcomm_sock_domain domain, enum lttcomm_sock_proto proto) +{ + int ret, _sock_type, _sock_proto; + + assert(sock); + + switch (proto) { + case LTTCOMM_SOCK_UDP: + _sock_type = SOCK_DGRAM; + _sock_proto = IPPROTO_UDP; + break; + case LTTCOMM_SOCK_TCP: + _sock_type = SOCK_STREAM; + _sock_proto = IPPROTO_TCP; + break; + default: + ret = -1; + goto error; + } + + ret = net_families[domain].create(sock, _sock_type, _sock_proto); + if (ret < 0) { + goto error; + } + + sock->proto = proto; + +error: + return ret; +} + +/* + * Return allocated lttcomm socket structure. + */ +struct lttcomm_sock *lttcomm_alloc_sock(enum lttcomm_sock_domain domain, + enum lttcomm_sock_proto proto) +{ + int ret; + struct lttcomm_sock *sock; + + sock = alloc_sock(proto); + if (sock == NULL) { + goto alloc_error; + } + + ret = lttcomm_create_sock(sock, domain, proto); + if (ret < 0) { + goto error; + } + + return sock; + +error: + free(sock); +alloc_error: + return NULL; +} + +/* + * Init IPv4 sockaddr structure. + */ +int lttcomm_init_inet_sockaddr(struct lttcomm_sockaddr *sockaddr, + const char *ip, unsigned int port) +{ + int ret; + + assert(sockaddr); + assert(ip); + assert(port > 0 && port <= 65535); + + memset(sockaddr, 0, sizeof(struct lttcomm_sockaddr)); + + sockaddr->type = LTTCOMM_INET; + sockaddr->addr.sin.sin_family = AF_INET; + sockaddr->addr.sin.sin_port = htons(port); + ret = inet_pton(sockaddr->addr.sin.sin_family, ip, + &sockaddr->addr.sin.sin_addr); + if (ret < 1) { + ret = -1; + goto error; + } + memset(sockaddr->addr.sin.sin_zero, 0, sizeof(sockaddr->addr.sin.sin_zero)); + +error: + return ret; +} + +/* + * Init IPv6 sockaddr structure. + */ +int lttcomm_init_inet6_sockaddr(struct lttcomm_sockaddr *sockaddr, + const char *ip, unsigned int port) +{ + int ret; + + assert(sockaddr); + assert(ip); + assert(port > 0 && port <= 65535); + + memset(sockaddr, 0, sizeof(struct lttcomm_sockaddr)); + + sockaddr->type = LTTCOMM_INET6; + sockaddr->addr.sin6.sin6_family = AF_INET6; + sockaddr->addr.sin6.sin6_port = htons(port); + ret = inet_pton(sockaddr->addr.sin6.sin6_family, ip, + &sockaddr->addr.sin6.sin6_addr); + if (ret < 1) { + ret = -1; + goto error; + } + +error: + return ret; +} diff --git a/src/common/sessiond-comm/sessiond-comm.h b/src/common/sessiond-comm/sessiond-comm.h index 118353584..52369dc62 100644 --- a/src/common/sessiond-comm/sessiond-comm.h +++ b/src/common/sessiond-comm/sessiond-comm.h @@ -30,6 +30,12 @@ #include #include +#include +#include +#include + +#include "inet.h" +#include "inet6.h" #include "unix.h" /* Queue size of listen(2) */ @@ -288,6 +294,62 @@ struct lttcomm_ust_reply { #endif /* HAVE_LIBLTTNG_UST_CTL */ +/* lttng socket protocol. */ +enum lttcomm_sock_proto { + LTTCOMM_SOCK_UDP, + LTTCOMM_SOCK_TCP, +}; + +/* + * Index in the net_families array below. Please keep in sync! + */ +enum lttcomm_sock_domain { + LTTCOMM_INET, + LTTCOMM_INET6, +}; + +struct lttcomm_sockaddr { + enum lttcomm_sock_domain type; + union { + struct sockaddr_in sin; + struct sockaddr_in6 sin6; + } addr; +}; + +struct lttcomm_sock { + int fd; + enum lttcomm_sock_proto proto; + struct lttcomm_sockaddr sockaddr; + const struct lttcomm_proto_ops *ops; +}; + +struct lttcomm_net_family { + int family; + int (*create) (struct lttcomm_sock *sock, int type, int proto); +}; + +struct lttcomm_proto_ops { + int (*bind) (struct lttcomm_sock *sock); + int (*close) (struct lttcomm_sock *sock); + int (*connect) (struct lttcomm_sock *sock); + struct lttcomm_sock *(*accept) (struct lttcomm_sock *sock); + int (*listen) (struct lttcomm_sock *sock, int backlog); + ssize_t (*recvmsg) (struct lttcomm_sock *sock, void *buf, size_t len, + int flags); + ssize_t (*sendmsg) (struct lttcomm_sock *sock, void *buf, size_t len, + int flags); +}; + extern const char *lttcomm_get_readable_code(enum lttcomm_return_code code); +extern int lttcomm_init_inet_sockaddr(struct lttcomm_sockaddr *sockaddr, + const char *ip, unsigned int port); +extern int lttcomm_init_inet6_sockaddr(struct lttcomm_sockaddr *sockaddr, + const char *ip, unsigned int port); + +extern struct lttcomm_sock *lttcomm_alloc_sock(enum lttcomm_sock_domain domain, + enum lttcomm_sock_proto proto); +extern int lttcomm_create_sock(struct lttcomm_sock *sock, + enum lttcomm_sock_domain domain, enum lttcomm_sock_proto proto); + #endif /* _LTTNG_SESSIOND_COMM_H */ diff --git a/tests/kernel/Makefile.am b/tests/kernel/Makefile.am index 94b9b959e..2a56e5f98 100644 --- a/tests/kernel/Makefile.am +++ b/tests/kernel/Makefile.am @@ -8,7 +8,9 @@ noinst_PROGRAMS = kernel_all_events_basic kernel_event_basic UTILS=utils.h LIBLTTNG=$(top_srcdir)/src/lib/lttng-ctl/lttng-ctl.c \ $(top_srcdir)/src/common/sessiond-comm/sessiond-comm.c \ - $(top_srcdir)/src/common/sessiond-comm/unix.c + $(top_srcdir)/src/common/sessiond-comm/unix.c \ + $(top_srcdir)/src/common/sessiond-comm/inet.c \ + $(top_srcdir)/src/common/sessiond-comm/inet6.c kernel_all_events_basic_SOURCES = kernel_all_events_basic.c $(UTILS) $(LIBLTTNG) diff --git a/tests/ust/Makefile.am b/tests/ust/Makefile.am index fee5c8402..4e5c8042d 100644 --- a/tests/ust/Makefile.am +++ b/tests/ust/Makefile.am @@ -11,7 +11,9 @@ noinst_PROGRAMS = ust_global_event_basic ust_global_event_wildcard UTILS=utils.h LIBLTTNG=$(top_srcdir)/src/lib/lttng-ctl/lttng-ctl.c \ $(top_srcdir)/src/common/sessiond-comm/sessiond-comm.c \ - $(top_srcdir)/src/common/sessiond-comm/unix.c + $(top_srcdir)/src/common/sessiond-comm/unix.c \ + $(top_srcdir)/src/common/sessiond-comm/inet.c \ + $(top_srcdir)/src/common/sessiond-comm/inet6.c ust_global_event_wildcard_SOURCES = ust_global_event_wildcard.c $(UTILS) $(LIBLTTNG) -- 2.34.1