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>
6 * SPDX-License-Identifier: GPL-2.0-only
11 #include "connection.hpp"
13 #include "viewer-session.hpp"
15 #include <common/common.hpp>
16 #include <common/urcu.hpp>
18 #include <urcu/rculist.h>
20 bool connection_get(struct relay_connection
*conn
)
22 return urcu_ref_get_unless_zero(&conn
->ref
);
25 struct relay_connection
*connection_get_by_sock(struct lttng_ht
*relay_connections_ht
, int sock
)
27 struct lttng_ht_node_ulong
*node
;
28 struct lttng_ht_iter iter
;
29 struct relay_connection
*conn
= nullptr;
31 LTTNG_ASSERT(sock
>= 0);
33 lttng::urcu::read_lock_guard read_lock
;
34 lttng_ht_lookup(relay_connections_ht
, (void *) ((unsigned long) sock
), &iter
);
35 node
= lttng_ht_iter_get_node_ulong(&iter
);
37 DBG2("Relay connection by sock %d not found", sock
);
40 conn
= lttng::utils::container_of(node
, &relay_connection::sock_n
);
41 if (!connection_get(conn
)) {
48 int connection_reset_protocol_state(struct relay_connection
*connection
)
52 switch (connection
->type
) {
54 connection
->protocol
.data
.state_id
= DATA_CONNECTION_STATE_RECEIVE_HEADER
;
55 memset(&connection
->protocol
.data
.state
.receive_header
,
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
);
62 connection
->protocol
.ctrl
.state_id
= CTRL_CONNECTION_STATE_RECEIVE_HEADER
;
63 memset(&connection
->protocol
.ctrl
.state
.receive_header
,
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
));
71 ERR("Failed to reinitialize control connection reception buffer size to %zu bytes.",
72 sizeof(struct lttcomm_relayd_hdr
));
79 DBG("Reset communication state of relay connection (fd = %i)", connection
->sock
->fd
);
84 struct relay_connection
*connection_create(struct lttcomm_sock
*sock
, enum connection_type type
)
86 struct relay_connection
*conn
;
88 conn
= zmalloc
<relay_connection
>();
90 PERROR("zmalloc relay connection");
93 urcu_ref_init(&conn
->ref
);
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
);
100 connection_reset_protocol_state(conn
);
105 static void rcu_free_connection(struct rcu_head
*head
)
107 struct relay_connection
*conn
=
108 lttng::utils::container_of(head
, &relay_connection::rcu_node
);
110 lttcomm_destroy_sock(conn
->sock
);
111 if (conn
->viewer_session
) {
112 viewer_session_destroy(conn
->viewer_session
);
113 conn
->viewer_session
= nullptr;
115 if (conn
->type
== RELAY_CONTROL
) {
116 lttng_dynamic_buffer_reset(&conn
->protocol
.ctrl
.reception_buffer
);
121 static void destroy_connection(struct relay_connection
*conn
)
123 call_rcu(&conn
->rcu_node
, rcu_free_connection
);
126 static void connection_release(struct urcu_ref
*ref
)
128 struct relay_connection
*conn
= lttng::utils::container_of(ref
, &relay_connection::ref
);
130 if (conn
->in_socket_ht
) {
131 struct lttng_ht_iter iter
;
134 iter
.iter
.node
= &conn
->sock_n
.node
;
135 ret
= lttng_ht_del(conn
->socket_ht
, &iter
);
140 if (session_close(conn
->session
)) {
141 ERR("session_close");
143 conn
->session
= nullptr;
145 if (conn
->viewer_session
) {
146 viewer_session_close(conn
->viewer_session
);
148 destroy_connection(conn
);
151 void connection_put(struct relay_connection
*conn
)
153 lttng::urcu::read_lock_guard read_lock
;
154 urcu_ref_put(&conn
->ref
, connection_release
);
157 void connection_ht_add(struct lttng_ht
*relay_connections_ht
, struct relay_connection
*conn
)
159 LTTNG_ASSERT(!conn
->in_socket_ht
);
160 lttng_ht_add_unique_ulong(relay_connections_ht
, &conn
->sock_n
);
161 conn
->in_socket_ht
= true;
162 conn
->socket_ht
= relay_connections_ht
;
165 int connection_set_session(struct relay_connection
*conn
, struct relay_session
*session
)
170 LTTNG_ASSERT(session
);
171 LTTNG_ASSERT(!conn
->session
);
173 if (connection_get(conn
)) {
174 if (session_get(session
)) {
175 conn
->session
= session
;
177 ERR("Failed to get session reference in connection_set_session()");
180 connection_put(conn
);
182 ERR("Failed to get connection reference in connection_set_session()");