X-Git-Url: https://git.liburcu.org/?a=blobdiff_plain;f=src%2Fcommon%2Fsessiond-comm%2Fsessiond-comm.c;h=d64374ea9e30bd330c73763b80260b0359bb89cf;hb=fe7bf56464d7747362e1bde77c2769a62c81ac4c;hp=336902a60f597d6c7820f34032f29d6a77b8396f;hpb=2038dd6ce78bc856ece474626b7f039d19860bce;p=lttng-tools.git diff --git a/src/common/sessiond-comm/sessiond-comm.c b/src/common/sessiond-comm/sessiond-comm.c index 336902a60..d64374ea9 100644 --- a/src/common/sessiond-comm/sessiond-comm.c +++ b/src/common/sessiond-comm/sessiond-comm.c @@ -1,21 +1,12 @@ /* - * Copyright (C) 2011 - David Goulet - * Mathieu Desnoyers + * Copyright (C) 2011 EfficiOS Inc. + * Copyright (C) 2011 Mathieu Desnoyers + * + * SPDX-License-Identifier: GPL-2.0-only * - * 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. */ +#include #define _LGPL_SOURCE #include #include @@ -25,9 +16,10 @@ #include #include #include -#include +#include #include +#include #include "sessiond-comm.h" @@ -413,6 +405,53 @@ int lttcomm_setsockopt_snd_timeout(int sock, unsigned int msec) return ret; } +LTTNG_HIDDEN +int lttcomm_sock_get_port(const struct lttcomm_sock *sock, uint16_t *port) +{ + assert(sock); + assert(port); + assert(sock->sockaddr.type == LTTCOMM_INET || + sock->sockaddr.type == LTTCOMM_INET6); + assert(sock->proto == LTTCOMM_SOCK_TCP || + sock->proto == LTTCOMM_SOCK_UDP); + + switch (sock->sockaddr.type) { + case LTTCOMM_INET: + *port = ntohs(sock->sockaddr.addr.sin.sin_port); + break; + case LTTCOMM_INET6: + *port = ntohs(sock->sockaddr.addr.sin6.sin6_port); + break; + default: + abort(); + } + + return 0; +} + +LTTNG_HIDDEN +int lttcomm_sock_set_port(struct lttcomm_sock *sock, uint16_t port) +{ + assert(sock); + assert(sock->sockaddr.type == LTTCOMM_INET || + sock->sockaddr.type == LTTCOMM_INET6); + assert(sock->proto == LTTCOMM_SOCK_TCP || + sock->proto == LTTCOMM_SOCK_UDP); + + switch (sock->sockaddr.type) { + case LTTCOMM_INET: + sock->sockaddr.addr.sin.sin_port = htons(port); + break; + case LTTCOMM_INET6: + sock->sockaddr.addr.sin6.sin6_port = htons(port); + break; + default: + abort(); + } + + return 0; +} + LTTNG_HIDDEN void lttcomm_init(void) { @@ -439,3 +478,72 @@ unsigned long lttcomm_get_network_timeout(void) { 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 = { 0 }; + + 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; +}