Add network transport layer to sessiond-comm
authorDavid Goulet <dgoulet@efficios.com>
Thu, 14 Jun 2012 18:48:49 +0000 (14:48 -0400)
committerDavid Goulet <dgoulet@efficios.com>
Thu, 14 Jun 2012 18:53:43 +0000 (14:53 -0400)
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 <dgoulet@efficios.com>
src/common/sessiond-comm/Makefile.am
src/common/sessiond-comm/inet.c [new file with mode: 0644]
src/common/sessiond-comm/inet.h [new file with mode: 0644]
src/common/sessiond-comm/inet6.c [new file with mode: 0644]
src/common/sessiond-comm/inet6.h [new file with mode: 0644]
src/common/sessiond-comm/sessiond-comm.c
src/common/sessiond-comm/sessiond-comm.h
tests/kernel/Makefile.am
tests/ust/Makefile.am

index c0beee01e4469f2a9a6c62709b72ef56b1e15502..1c73dcb9ea690bd7c7dd0b18f29089fe48f5a4e2 100644 (file)
@@ -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 (file)
index 0000000..51ac670
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2012 - David Goulet <dgoulet@efficios.com>
+ *
+ * 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 <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <common/defaults.h>
+#include <common/error.h>
+
+#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 (file)
index 0000000..89716b8
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2012 - David Goulet <dgoulet@efficios.com>
+ *
+ * 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 <limits.h>
+
+#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 (file)
index 0000000..38822ca
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2012 - David Goulet <dgoulet@efficios.com>
+ *
+ * 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 <assert.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <common/defaults.h>
+#include <common/error.h>
+
+#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 (file)
index 0000000..4cb4dca
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2012 - David Goulet <dgoulet@efficios.com>
+ *
+ * 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 <limits.h>
+
+#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 */
index 706b8a7cd69063cbc9b4f0d15a0af34be81090c3..eaa14a549863200e6f907476f7c43671b5f0d33c 100644 (file)
 
 #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;
+}
index 1183535841453a3b220767476d04b63bdfaa41c8..52369dc625d565a1e8c26d31520caecea48f5cd8 100644 (file)
 #include <lttng/lttng.h>
 #include <common/compat/socket.h>
 
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/un.h>
+
+#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 */
index 94b9b959e0cae4d6e37f2cfa30c7a2f6bcc96ce4..2a56e5f98953b80a228b3b2d36295ea9495ebd79 100644 (file)
@@ -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)
 
index fee5c840214868849ee8376ade88c028aa67b07d..4e5c8042deb5bfa7ea851d81b28b7b4682c12de7 100644 (file)
@@ -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)
 
This page took 0.036613 seconds and 5 git commands to generate.