X-Git-Url: https://git.lttng.org/?p=lttng-tools.git;a=blobdiff_plain;f=src%2Fcommon%2Fsessiond-comm%2Fsessiond-comm.c;h=6cbd014b8c3db26be2ee7cfeb7ba421d489e2837;hp=706b8a7cd69063cbc9b4f0d15a0af34be81090c3;hb=de5e90863d3824dd3a5bc52d4cba1cd9b0329200;hpb=a027b2d2edced8011ef674f88146253715952af7 diff --git a/src/common/sessiond-comm/sessiond-comm.c b/src/common/sessiond-comm/sessiond-comm.c index 706b8a7cd..6cbd014b8 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. */ @@ -126,6 +138,11 @@ static const char *lttcomm_readable_code[] = { [ LTTCOMM_ERR_INDEX(LTTCOMM_NO_USTCONSUMERD) ] = "No UST consumer detected", [ LTTCOMM_ERR_INDEX(LTTCOMM_NO_KERNCONSUMERD) ] = "No kernel consumer detected", [ LTTCOMM_ERR_INDEX(LTTCOMM_EVENT_EXIST_LOGLEVEL) ] = "Event already enabled with different loglevel", + [ LTTCOMM_ERR_INDEX(LTTCOMM_URI_DATA_MISS) ] = "Missing data path URI", + [ LTTCOMM_ERR_INDEX(LTTCOMM_URI_CTRL_MISS) ] = "Missing control data path URI", + [ LTTCOMM_ERR_INDEX(LTTCOMM_ENABLE_CONSUMER_FAIL) ] = "Enabling consumer failed", + [ LTTCOMM_ERR_INDEX(LTTCOMM_RELAYD_SESSION_FAIL) ] = "Unable to create session on lttng-relayd", + [ LTTCOMM_ERR_INDEX(LTTCOMM_RELAYD_VERSION_FAIL) ] = "Relay daemon not compatible", }; /* @@ -144,3 +161,227 @@ const char *lttcomm_get_readable_code(enum lttcomm_return_code code) return "Unknown error code"; } + +/* + * Create socket from an already allocated lttcomm socket structure and init + * sockaddr in the lttcomm sock. + */ +int lttcomm_create_sock(struct lttcomm_sock *sock) +{ + int ret, _sock_type, _sock_proto, domain; + + assert(sock); + + domain = sock->sockaddr.type; + if (domain != LTTCOMM_INET && domain != LTTCOMM_INET6) { + ERR("Create socket of unknown domain %d", domain); + ret = -1; + goto error; + } + + switch (sock->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; + } + +error: + return ret; +} + +/* + * Return allocated lttcomm socket structure. + */ +struct lttcomm_sock *lttcomm_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; + sock->fd = -1; + +end: + return sock; +} + +/* + * Return an allocated lttcomm socket structure and copy src content into + * the newly created socket. + * + * This is mostly useful when lttcomm_sock are passed between process where the + * fd and ops have to be changed within the correct address space. + */ +struct lttcomm_sock *lttcomm_alloc_copy_sock(struct lttcomm_sock *src) +{ + struct lttcomm_sock *sock; + + /* Safety net */ + assert(src); + + sock = lttcomm_alloc_sock(src->proto); + if (sock == NULL) { + goto alloc_error; + } + + lttcomm_copy_sock(sock, src); + +alloc_error: + return sock; +} + +/* + * Create and copy socket from an allocated lttcomm socket structure. + * + * This is mostly useful when lttcomm_sock are passed between process where the + * fd and ops have to be changed within the correct address space. + */ +void lttcomm_copy_sock(struct lttcomm_sock *dst, struct lttcomm_sock *src) +{ + /* Safety net */ + assert(dst); + assert(src); + + dst->proto = src->proto; + dst->fd = src->fd; + dst->ops = src->ops; + /* Copy sockaddr information from original socket */ + memcpy(&dst->sockaddr, &src->sockaddr, sizeof(dst->sockaddr)); +} + +/* + * 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; + ERR("%s with port %d: unrecognized IPv4 address", ip, port); + 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; +} + +/* + * Return allocated lttcomm socket structure from lttng URI. + */ +struct lttcomm_sock *lttcomm_alloc_sock_from_uri(struct lttng_uri *uri) +{ + int ret; + int _sock_proto; + struct lttcomm_sock *sock = NULL; + + /* Safety net */ + assert(uri); + + /* Check URI protocol */ + if (uri->proto == LTTNG_TCP) { + _sock_proto = LTTCOMM_SOCK_TCP; + } else { + ERR("Relayd invalid URI proto: %d", uri->proto); + goto alloc_error; + } + + sock = lttcomm_alloc_sock(_sock_proto); + if (sock == NULL) { + goto alloc_error; + } + + /* Check destination type */ + if (uri->dtype == LTTNG_DST_IPV4) { + 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); + if (ret < 0) { + goto error; + } + } else { + /* Command URI is invalid */ + ERR("Relayd invalid URI dst type: %d", uri->dtype); + goto error; + } + + return sock; + +error: + lttcomm_destroy_sock(sock); +alloc_error: + return NULL; +} + +/* + * Destroy and free lttcomm socket. + */ +void lttcomm_destroy_sock(struct lttcomm_sock *sock) +{ + if (sock != NULL) { + free(sock); + } +}