Run clang-format on the whole tree
[lttng-tools.git] / src / bin / lttng-relayd / connection.cpp
CommitLineData
58eb9381 1/*
ab5be9fa
MJ
2 * Copyright (C) 2013 Julien Desfossez <jdesfossez@efficios.com>
3 * Copyright (C) 2013 David Goulet <dgoulet@efficios.com>
4 * Copyright (C) 2015 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
58eb9381 5 *
ab5be9fa 6 * SPDX-License-Identifier: GPL-2.0-only
58eb9381 7 *
58eb9381
DG
8 */
9
6c1c0768 10#define _LGPL_SOURCE
c9e313bc
SM
11#include "connection.hpp"
12#include "stream.hpp"
13#include "viewer-session.hpp"
58eb9381 14
28ab034a
JG
15#include <common/common.hpp>
16
17#include <urcu/rculist.h>
18
7591bab1 19bool connection_get(struct relay_connection *conn)
58eb9381 20{
ce4d4083 21 return urcu_ref_get_unless_zero(&conn->ref);
58eb9381
DG
22}
23
28ab034a 24struct relay_connection *connection_get_by_sock(struct lttng_ht *relay_connections_ht, int sock)
58eb9381
DG
25{
26 struct lttng_ht_node_ulong *node;
27 struct lttng_ht_iter iter;
28 struct relay_connection *conn = NULL;
29
a0377dfe 30 LTTNG_ASSERT(sock >= 0);
58eb9381 31
7591bab1 32 rcu_read_lock();
28ab034a 33 lttng_ht_lookup(relay_connections_ht, (void *) ((unsigned long) sock), &iter);
58eb9381
DG
34 node = lttng_ht_iter_get_node_ulong(&iter);
35 if (!node) {
36 DBG2("Relay connection by sock %d not found", sock);
37 goto end;
38 }
0114db0e 39 conn = lttng::utils::container_of(node, &relay_connection::sock_n);
7591bab1
MD
40 if (!connection_get(conn)) {
41 conn = NULL;
42 }
58eb9381 43end:
7591bab1 44 rcu_read_unlock();
58eb9381
DG
45 return conn;
46}
47
5312a3ed
JG
48int connection_reset_protocol_state(struct relay_connection *connection)
49{
50 int ret = 0;
51
52 switch (connection->type) {
53 case RELAY_DATA:
28ab034a 54 connection->protocol.data.state_id = DATA_CONNECTION_STATE_RECEIVE_HEADER;
5312a3ed 55 memset(&connection->protocol.data.state.receive_header,
28ab034a
JG
56 0,
57 sizeof(connection->protocol.data.state.receive_header));
5312a3ed 58 connection->protocol.data.state.receive_header.left_to_receive =
28ab034a 59 sizeof(struct lttcomm_relayd_data_hdr);
5312a3ed
JG
60 break;
61 case RELAY_CONTROL:
28ab034a 62 connection->protocol.ctrl.state_id = CTRL_CONNECTION_STATE_RECEIVE_HEADER;
5312a3ed 63 memset(&connection->protocol.ctrl.state.receive_header,
28ab034a
JG
64 0,
65 sizeof(connection->protocol.ctrl.state.receive_header));
5312a3ed 66 connection->protocol.data.state.receive_header.left_to_receive =
28ab034a
JG
67 sizeof(struct lttcomm_relayd_hdr);
68 ret = lttng_dynamic_buffer_set_size(&connection->protocol.ctrl.reception_buffer,
69 sizeof(struct lttcomm_relayd_hdr));
5312a3ed 70 if (ret) {
28ab034a
JG
71 ERR("Failed to reinitialize control connection reception buffer size to %zu bytes.",
72 sizeof(struct lttcomm_relayd_hdr));
5312a3ed
JG
73 goto end;
74 }
75 break;
76 default:
77 goto end;
78 }
28ab034a 79 DBG("Reset communication state of relay connection (fd = %i)", connection->sock->fd);
5312a3ed
JG
80end:
81 return ret;
82}
83
28ab034a 84struct relay_connection *connection_create(struct lttcomm_sock *sock, enum connection_type type)
58eb9381 85{
7591bab1 86 struct relay_connection *conn;
58eb9381 87
64803277 88 conn = zmalloc<relay_connection>();
7591bab1
MD
89 if (!conn) {
90 PERROR("zmalloc relay connection");
91 goto end;
92 }
7591bab1
MD
93 urcu_ref_init(&conn->ref);
94 conn->type = type;
95 conn->sock = sock;
96 lttng_ht_node_init_ulong(&conn->sock_n, (unsigned long) conn->sock->fd);
5312a3ed
JG
97 if (conn->type == RELAY_CONTROL) {
98 lttng_dynamic_buffer_init(&conn->protocol.ctrl.reception_buffer);
99 }
100 connection_reset_protocol_state(conn);
7591bab1
MD
101end:
102 return conn;
58eb9381
DG
103}
104
7591bab1 105static void rcu_free_connection(struct rcu_head *head)
58eb9381 106{
7591bab1 107 struct relay_connection *conn =
0114db0e 108 lttng::utils::container_of(head, &relay_connection::rcu_node);
58eb9381 109
7591bab1
MD
110 lttcomm_destroy_sock(conn->sock);
111 if (conn->viewer_session) {
112 viewer_session_destroy(conn->viewer_session);
113 conn->viewer_session = NULL;
114 }
35be817a 115 if (conn->type == RELAY_CONTROL) {
28ab034a 116 lttng_dynamic_buffer_reset(&conn->protocol.ctrl.reception_buffer);
35be817a 117 }
7591bab1
MD
118 free(conn);
119}
120
121static void destroy_connection(struct relay_connection *conn)
122{
58eb9381
DG
123 call_rcu(&conn->rcu_node, rcu_free_connection);
124}
125
7591bab1 126static void connection_release(struct urcu_ref *ref)
58eb9381 127{
28ab034a 128 struct relay_connection *conn = lttng::utils::container_of(ref, &relay_connection::ref);
58eb9381 129
7591bab1
MD
130 if (conn->in_socket_ht) {
131 struct lttng_ht_iter iter;
132 int ret;
133
134 iter.iter.node = &conn->sock_n.node;
135 ret = lttng_ht_del(conn->socket_ht, &iter);
a0377dfe 136 LTTNG_ASSERT(!ret);
58eb9381
DG
137 }
138
7591bab1
MD
139 if (conn->session) {
140 if (session_close(conn->session)) {
141 ERR("session_close");
142 }
143 conn->session = NULL;
144 }
145 if (conn->viewer_session) {
146 viewer_session_close(conn->viewer_session);
147 }
148 destroy_connection(conn);
58eb9381
DG
149}
150
7591bab1 151void connection_put(struct relay_connection *conn)
58eb9381 152{
7591bab1 153 rcu_read_lock();
7591bab1 154 urcu_ref_put(&conn->ref, connection_release);
7591bab1 155 rcu_read_unlock();
58eb9381
DG
156}
157
28ab034a 158void connection_ht_add(struct lttng_ht *relay_connections_ht, struct relay_connection *conn)
58eb9381 159{
a0377dfe 160 LTTNG_ASSERT(!conn->in_socket_ht);
7591bab1
MD
161 lttng_ht_add_unique_ulong(relay_connections_ht, &conn->sock_n);
162 conn->in_socket_ht = 1;
163 conn->socket_ht = relay_connections_ht;
58eb9381 164}
fd0f1e3e 165
28ab034a 166int connection_set_session(struct relay_connection *conn, struct relay_session *session)
fd0f1e3e
JR
167{
168 int ret = 0;
169
a0377dfe
FD
170 LTTNG_ASSERT(conn);
171 LTTNG_ASSERT(session);
172 LTTNG_ASSERT(!conn->session);
fd0f1e3e
JR
173
174 if (connection_get(conn)) {
175 if (session_get(session)) {
176 conn->session = session;
177 } else {
178 ERR("Failed to get session reference in connection_set_session()");
179 ret = -1;
180 }
181 connection_put(conn);
182 } else {
183 ERR("Failed to get connection reference in connection_set_session()");
184 ret = -1;
185 }
186 return ret;
187}
This page took 0.063366 seconds and 4 git commands to generate.