fix: relayd: unaligned access in trace_chunk_registry_ht_key_hash
[lttng-tools.git] / src / common / sessiond-comm / sessiond-comm.cpp
index 6a011b8b4cea9dfbb02661bb8bccb0668999bd95..593ab265ccc25f6a1d7e06d098c31c0568529b27 100644 (file)
@@ -1,12 +1,19 @@
 /*
- * Copyright (C) 2011 David Goulet <david.goulet@polymtl.ca>
+ * Copyright (C) 2011 EfficiOS Inc.
  * Copyright (C) 2011 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
  *
  * SPDX-License-Identifier: GPL-2.0-only
  *
  */
 
+#include <sys/socket.h>
 #define _LGPL_SOURCE
+#include "sessiond-comm.hpp"
+
+#include <common/common.hpp>
+#include <common/compat/errno.hpp>
+
+#include <inttypes.h>
 #include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
-#include <inttypes.h>
-
-#include <common/common.h>
-#include <common/compat/errno.h>
-
-#include "sessiond-comm.h"
 
 /* For Unix socket */
-#include <common/unix.h>
+#include <common/unix.hpp>
 /* For Inet socket */
-#include "inet.h"
+#include "inet.hpp"
 /* For Inet6 socket */
-#include "inet6.h"
+#include "inet6.hpp"
 
-#define NETWORK_TIMEOUT_ENV    "LTTNG_NETWORK_SOCKET_TIMEOUT"
+#define NETWORK_TIMEOUT_ENV "LTTNG_NETWORK_SOCKET_TIMEOUT"
 
 static struct lttcomm_net_family net_families[] = {
        { LTTCOMM_INET, lttcomm_create_inet_sock },
@@ -38,8 +39,8 @@ static struct lttcomm_net_family net_families[] = {
 /*
  * Human readable error message.
  */
-static
-const char *lttcomm_return_code_str(lttcomm_return_code code) {
+static const char *lttcomm_return_code_str(lttcomm_return_code code)
+{
        switch (code) {
        case LTTCOMM_CONSUMERD_SUCCESS:
                return "consumerd success";
@@ -125,7 +126,7 @@ const char *lttcomm_get_readable_code(enum lttcomm_return_code code)
        code = (lttcomm_return_code) -code;
 
        if (code != LTTCOMM_CONSUMERD_SUCCESS &&
-                       !(code >= LTTCOMM_CONSUMERD_COMMAND_SOCK_READY && code < LTTCOMM_NR)) {
+           !(code >= LTTCOMM_CONSUMERD_COMMAND_SOCK_READY && code < LTTCOMM_NR)) {
                code = LTTCOMM_CONSUMERD_UNKNOWN_ERROR;
        }
 
@@ -177,10 +178,9 @@ error:
  */
 struct lttcomm_sock *lttcomm_alloc_sock(enum lttcomm_sock_proto proto)
 {
-       struct lttcomm_sock *sock;
+       struct lttcomm_sock *sock = zmalloc<lttcomm_sock>();
 
-       sock = (lttcomm_sock *) zmalloc(sizeof(lttcomm_sock));
-       if (sock == NULL) {
+       if (sock == nullptr) {
                PERROR("zmalloc create sock");
                goto end;
        }
@@ -207,7 +207,7 @@ struct lttcomm_sock *lttcomm_alloc_copy_sock(struct lttcomm_sock *src)
        LTTNG_ASSERT(src);
 
        sock = lttcomm_alloc_sock(src->proto);
-       if (sock == NULL) {
+       if (sock == nullptr) {
                goto alloc_error;
        }
 
@@ -239,8 +239,7 @@ void lttcomm_copy_sock(struct lttcomm_sock *dst, struct lttcomm_sock *src)
 /*
  * Init IPv4 sockaddr structure.
  */
-int lttcomm_init_inet_sockaddr(struct lttcomm_sockaddr *sockaddr,
-               const char *ip, unsigned int port)
+int lttcomm_init_inet_sockaddr(struct lttcomm_sockaddr *sockaddr, const char *ip, unsigned int port)
 {
        int ret;
 
@@ -253,8 +252,7 @@ int lttcomm_init_inet_sockaddr(struct lttcomm_sockaddr *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);
+       ret = inet_pton(sockaddr->addr.sin.sin_family, ip, &sockaddr->addr.sin.sin_addr);
        if (ret < 1) {
                ret = -1;
                ERR("%s with port %d: unrecognized IPv4 address", ip, port);
@@ -270,7 +268,8 @@ error:
  * Init IPv6 sockaddr structure.
  */
 int lttcomm_init_inet6_sockaddr(struct lttcomm_sockaddr *sockaddr,
-               const char *ip, unsigned int port)
+                               const char *ip,
+                               unsigned int port)
 {
        int ret;
 
@@ -283,8 +282,7 @@ int lttcomm_init_inet6_sockaddr(struct lttcomm_sockaddr *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);
+       ret = inet_pton(sockaddr->addr.sin6.sin6_family, ip, &sockaddr->addr.sin6.sin6_addr);
        if (ret < 1) {
                ret = -1;
                goto error;
@@ -301,7 +299,7 @@ struct lttcomm_sock *lttcomm_alloc_sock_from_uri(struct lttng_uri *uri)
 {
        int ret;
        int _sock_proto;
-       struct lttcomm_sock *sock = NULL;
+       struct lttcomm_sock *sock = nullptr;
 
        /* Safety net */
        LTTNG_ASSERT(uri);
@@ -315,20 +313,18 @@ struct lttcomm_sock *lttcomm_alloc_sock_from_uri(struct lttng_uri *uri)
        }
 
        sock = lttcomm_alloc_sock((lttcomm_sock_proto) _sock_proto);
-       if (sock == NULL) {
+       if (sock == nullptr) {
                goto alloc_error;
        }
 
        /* Check destination type */
        if (uri->dtype == LTTNG_DST_IPV4) {
-               ret = lttcomm_init_inet_sockaddr(&sock->sockaddr, uri->dst.ipv4,
-                               uri->port);
+               ret = lttcomm_init_inet_sockaddr(&sock->sockaddr, uri->dst.ipv4, uri->port);
                if (ret < 0) {
                        goto error;
                }
        } else if (uri->dtype == LTTNG_DST_IPV6) {
-               ret = lttcomm_init_inet6_sockaddr(&sock->sockaddr, uri->dst.ipv6,
-                               uri->port);
+               ret = lttcomm_init_inet6_sockaddr(&sock->sockaddr, uri->dst.ipv6, uri->port);
                if (ret < 0) {
                        goto error;
                }
@@ -343,7 +339,7 @@ struct lttcomm_sock *lttcomm_alloc_sock_from_uri(struct lttng_uri *uri)
 error:
        lttcomm_destroy_sock(sock);
 alloc_error:
-       return NULL;
+       return nullptr;
 }
 
 /*
@@ -360,16 +356,15 @@ void lttcomm_destroy_sock(struct lttcomm_sock *sock)
  *
  * On error, NULL is returned.
  */
-struct lttcomm_relayd_sock *lttcomm_alloc_relayd_sock(struct lttng_uri *uri,
-               uint32_t major, uint32_t minor)
+struct lttcomm_relayd_sock *
+lttcomm_alloc_relayd_sock(struct lttng_uri *uri, uint32_t major, uint32_t minor)
 {
        int ret;
-       struct lttcomm_sock *tmp_sock = NULL;
-       struct lttcomm_relayd_sock *rsock = NULL;
+       struct lttcomm_sock *tmp_sock = nullptr;
+       struct lttcomm_relayd_sock *rsock = zmalloc<lttcomm_relayd_sock>();
 
        LTTNG_ASSERT(uri);
 
-       rsock = (lttcomm_relayd_sock *) zmalloc(sizeof(*rsock));
        if (!rsock) {
                PERROR("zmalloc relayd sock");
                goto error;
@@ -377,7 +372,7 @@ struct lttcomm_relayd_sock *lttcomm_alloc_relayd_sock(struct lttng_uri *uri,
 
        /* Allocate socket object from URI */
        tmp_sock = lttcomm_alloc_sock_from_uri(uri);
-       if (tmp_sock == NULL) {
+       if (tmp_sock == nullptr) {
                goto error_free;
        }
 
@@ -401,7 +396,7 @@ struct lttcomm_relayd_sock *lttcomm_alloc_relayd_sock(struct lttng_uri *uri,
 error_free:
        free(rsock);
 error:
-       return NULL;
+       return nullptr;
 }
 
 /*
@@ -446,10 +441,8 @@ int lttcomm_sock_get_port(const struct lttcomm_sock *sock, uint16_t *port)
 {
        LTTNG_ASSERT(sock);
        LTTNG_ASSERT(port);
-       LTTNG_ASSERT(sock->sockaddr.type == LTTCOMM_INET ||
-                       sock->sockaddr.type == LTTCOMM_INET6);
-       LTTNG_ASSERT(sock->proto == LTTCOMM_SOCK_TCP ||
-                       sock->proto == LTTCOMM_SOCK_UDP);
+       LTTNG_ASSERT(sock->sockaddr.type == LTTCOMM_INET || sock->sockaddr.type == LTTCOMM_INET6);
+       LTTNG_ASSERT(sock->proto == LTTCOMM_SOCK_TCP || sock->proto == LTTCOMM_SOCK_UDP);
 
        switch (sock->sockaddr.type) {
        case LTTCOMM_INET:
@@ -468,10 +461,8 @@ int lttcomm_sock_get_port(const struct lttcomm_sock *sock, uint16_t *port)
 int lttcomm_sock_set_port(struct lttcomm_sock *sock, uint16_t port)
 {
        LTTNG_ASSERT(sock);
-       LTTNG_ASSERT(sock->sockaddr.type == LTTCOMM_INET ||
-                       sock->sockaddr.type == LTTCOMM_INET6);
-       LTTNG_ASSERT(sock->proto == LTTCOMM_SOCK_TCP ||
-                       sock->proto == LTTCOMM_SOCK_UDP);
+       LTTNG_ASSERT(sock->sockaddr.type == LTTCOMM_INET || sock->sockaddr.type == LTTCOMM_INET6);
+       LTTNG_ASSERT(sock->proto == LTTCOMM_SOCK_TCP || sock->proto == LTTCOMM_SOCK_UDP);
 
        switch (sock->sockaddr.type) {
        case LTTCOMM_INET:
@@ -487,7 +478,7 @@ int lttcomm_sock_set_port(struct lttcomm_sock *sock, uint16_t port)
        return 0;
 }
 
-void lttcomm_init(void)
+void lttcomm_init()
 {
        const char *env;
 
@@ -496,7 +487,7 @@ void lttcomm_init(void)
                long timeout;
 
                errno = 0;
-               timeout = strtol(env, NULL, 0);
+               timeout = strtol(env, nullptr, 0);
                if (errno != 0 || timeout < -1L) {
                        PERROR("Network timeout");
                } else {
@@ -507,7 +498,71 @@ void lttcomm_init(void)
        }
 }
 
-unsigned long lttcomm_get_network_timeout(void)
+unsigned long lttcomm_get_network_timeout()
 {
        return network_timeout;
 }
+
+/*
+ * Only valid for an ipv4 and ipv6 bound socket that is already connected to its
+ * peer.
+ */
+int lttcomm_populate_sock_from_open_socket(struct lttcomm_sock *sock,
+                                          int fd,
+                                          enum lttcomm_sock_proto protocol)
+{
+       int ret = 0;
+       socklen_t storage_len;
+       struct sockaddr_storage storage = {};
+
+       assert(sock);
+       assert(fd >= 0);
+
+       sock->proto = protocol;
+
+       storage_len = sizeof(storage);
+       ret = getpeername(fd, (struct sockaddr *) &storage, &storage_len);
+       if (ret) {
+               ERR("Failed to get peer info for socket %d (errno: %d)", fd, errno);
+               ret = -1;
+               goto end;
+       }
+
+       if (storage_len > sizeof(storage)) {
+               ERR("Failed to get peer info for socket %d: storage size is too small", fd);
+               ret = -1;
+               goto end;
+       }
+
+       switch (storage.ss_family) {
+       case AF_INET:
+               sock->sockaddr.type = LTTCOMM_INET;
+               memcpy(&sock->sockaddr.addr, &storage, sizeof(struct sockaddr_in));
+               break;
+       case AF_INET6:
+               sock->sockaddr.type = LTTCOMM_INET6;
+               memcpy(&sock->sockaddr.addr, &storage, sizeof(struct sockaddr_in6));
+               break;
+       default:
+               abort();
+               break;
+       }
+
+       /* Create a valid socket object with a temporary fd. */
+       ret = lttcomm_create_sock(sock);
+       if (ret < 0) {
+               ERR("Failed to create temporary socket object");
+               ret = -1;
+               goto end;
+       }
+
+       /* Substitute the fd. */
+       if (sock->ops->close(sock)) {
+               ret = -1;
+               goto end;
+       }
+       sock->fd = fd;
+
+end:
+       return ret;
+}
This page took 0.028799 seconds and 4 git commands to generate.