Run clang-format on the whole tree
[lttng-tools.git] / src / bin / lttng-relayd / connection.cpp
1 /*
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>
5 *
6 * SPDX-License-Identifier: GPL-2.0-only
7 *
8 */
9
10 #define _LGPL_SOURCE
11 #include "connection.hpp"
12 #include "stream.hpp"
13 #include "viewer-session.hpp"
14
15 #include <common/common.hpp>
16
17 #include <urcu/rculist.h>
18
19 bool connection_get(struct relay_connection *conn)
20 {
21 return urcu_ref_get_unless_zero(&conn->ref);
22 }
23
24 struct relay_connection *connection_get_by_sock(struct lttng_ht *relay_connections_ht, int sock)
25 {
26 struct lttng_ht_node_ulong *node;
27 struct lttng_ht_iter iter;
28 struct relay_connection *conn = NULL;
29
30 LTTNG_ASSERT(sock >= 0);
31
32 rcu_read_lock();
33 lttng_ht_lookup(relay_connections_ht, (void *) ((unsigned long) sock), &iter);
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 }
39 conn = lttng::utils::container_of(node, &relay_connection::sock_n);
40 if (!connection_get(conn)) {
41 conn = NULL;
42 }
43 end:
44 rcu_read_unlock();
45 return conn;
46 }
47
48 int connection_reset_protocol_state(struct relay_connection *connection)
49 {
50 int ret = 0;
51
52 switch (connection->type) {
53 case RELAY_DATA:
54 connection->protocol.data.state_id = DATA_CONNECTION_STATE_RECEIVE_HEADER;
55 memset(&connection->protocol.data.state.receive_header,
56 0,
57 sizeof(connection->protocol.data.state.receive_header));
58 connection->protocol.data.state.receive_header.left_to_receive =
59 sizeof(struct lttcomm_relayd_data_hdr);
60 break;
61 case RELAY_CONTROL:
62 connection->protocol.ctrl.state_id = CTRL_CONNECTION_STATE_RECEIVE_HEADER;
63 memset(&connection->protocol.ctrl.state.receive_header,
64 0,
65 sizeof(connection->protocol.ctrl.state.receive_header));
66 connection->protocol.data.state.receive_header.left_to_receive =
67 sizeof(struct lttcomm_relayd_hdr);
68 ret = lttng_dynamic_buffer_set_size(&connection->protocol.ctrl.reception_buffer,
69 sizeof(struct lttcomm_relayd_hdr));
70 if (ret) {
71 ERR("Failed to reinitialize control connection reception buffer size to %zu bytes.",
72 sizeof(struct lttcomm_relayd_hdr));
73 goto end;
74 }
75 break;
76 default:
77 goto end;
78 }
79 DBG("Reset communication state of relay connection (fd = %i)", connection->sock->fd);
80 end:
81 return ret;
82 }
83
84 struct relay_connection *connection_create(struct lttcomm_sock *sock, enum connection_type type)
85 {
86 struct relay_connection *conn;
87
88 conn = zmalloc<relay_connection>();
89 if (!conn) {
90 PERROR("zmalloc relay connection");
91 goto end;
92 }
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);
97 if (conn->type == RELAY_CONTROL) {
98 lttng_dynamic_buffer_init(&conn->protocol.ctrl.reception_buffer);
99 }
100 connection_reset_protocol_state(conn);
101 end:
102 return conn;
103 }
104
105 static void rcu_free_connection(struct rcu_head *head)
106 {
107 struct relay_connection *conn =
108 lttng::utils::container_of(head, &relay_connection::rcu_node);
109
110 lttcomm_destroy_sock(conn->sock);
111 if (conn->viewer_session) {
112 viewer_session_destroy(conn->viewer_session);
113 conn->viewer_session = NULL;
114 }
115 if (conn->type == RELAY_CONTROL) {
116 lttng_dynamic_buffer_reset(&conn->protocol.ctrl.reception_buffer);
117 }
118 free(conn);
119 }
120
121 static void destroy_connection(struct relay_connection *conn)
122 {
123 call_rcu(&conn->rcu_node, rcu_free_connection);
124 }
125
126 static void connection_release(struct urcu_ref *ref)
127 {
128 struct relay_connection *conn = lttng::utils::container_of(ref, &relay_connection::ref);
129
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);
136 LTTNG_ASSERT(!ret);
137 }
138
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);
149 }
150
151 void connection_put(struct relay_connection *conn)
152 {
153 rcu_read_lock();
154 urcu_ref_put(&conn->ref, connection_release);
155 rcu_read_unlock();
156 }
157
158 void connection_ht_add(struct lttng_ht *relay_connections_ht, struct relay_connection *conn)
159 {
160 LTTNG_ASSERT(!conn->in_socket_ht);
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;
164 }
165
166 int connection_set_session(struct relay_connection *conn, struct relay_session *session)
167 {
168 int ret = 0;
169
170 LTTNG_ASSERT(conn);
171 LTTNG_ASSERT(session);
172 LTTNG_ASSERT(!conn->session);
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.032716 seconds and 4 git commands to generate.