2 * Copyright (C) 2018 Jonathan Rajotte <jonathan.rajotte-julien@efficios.com>
4 * SPDX-License-Identifier: GPL-2.0-only
9 #include "cmd-2-11.hpp"
12 #include <common/common.hpp>
13 #include <common/compat/endian.hpp>
14 #include <common/compat/string.hpp>
15 #include <common/sessiond-comm/relayd.hpp>
17 #include <lttng/constant.h>
21 int cmd_create_session_2_11(const struct lttng_buffer_view
*payload
,
27 uint64_t *id_sessiond
,
28 lttng_uuid
& sessiond_uuid
,
29 bool *has_current_chunk
,
30 uint64_t *current_chunk_id
,
31 time_t *creation_time
,
32 bool *session_name_contains_creation_time
)
35 struct lttcomm_relayd_create_session_2_11 header
;
36 size_t header_len
, received_names_size
, offset
;
37 struct lttng_buffer_view session_name_view
;
38 struct lttng_buffer_view hostname_view
;
39 struct lttng_buffer_view base_path_view
;
41 header_len
= sizeof(header
);
43 if (payload
->size
< header_len
) {
44 ERR("Unexpected payload size in \"cmd_create_session_2_11\": expected >= %zu bytes, got %zu bytes",
50 memcpy(&header
, payload
->data
, header_len
);
52 header
.session_name_len
= be32toh(header
.session_name_len
);
53 header
.hostname_len
= be32toh(header
.hostname_len
);
54 header
.base_path_len
= be32toh(header
.base_path_len
);
55 header
.live_timer
= be32toh(header
.live_timer
);
56 header
.current_chunk_id
.value
= be64toh(header
.current_chunk_id
.value
);
57 header
.current_chunk_id
.is_set
= !!header
.current_chunk_id
.is_set
;
58 header
.creation_time
= be64toh(header
.creation_time
);
59 header
.session_id
= be64toh(header
.session_id
);
61 std::copy(std::begin(header
.sessiond_uuid
),
62 std::end(header
.sessiond_uuid
),
63 sessiond_uuid
.begin());
65 received_names_size
= header
.session_name_len
+ header
.hostname_len
+ header
.base_path_len
;
66 if (payload
->size
< header_len
+ received_names_size
) {
67 ERR("Unexpected payload size in \"cmd_create_session_2_11\": expected >= %zu bytes, got %zu bytes",
68 header_len
+ received_names_size
,
74 /* Validate length against defined constant. */
75 if (header
.session_name_len
> LTTNG_NAME_MAX
) {
77 ERR("Length of session name (%" PRIu32
78 " bytes) received in create_session command exceeds maximum length (%d bytes)",
79 header
.session_name_len
,
82 } else if (header
.session_name_len
== 0) {
84 ERR("Illegal session name length of 0 received");
87 if (header
.hostname_len
> LTTNG_HOST_NAME_MAX
) {
89 ERR("Length of hostname (%" PRIu32
90 " bytes) received in create_session command exceeds maximum length (%d bytes)",
95 if (header
.base_path_len
> LTTNG_PATH_MAX
) {
97 ERR("Length of base_path (%" PRIu32
98 " bytes) received in create_session command exceeds maximum length (%d bytes)",
105 session_name_view
= lttng_buffer_view_from_view(payload
, offset
, header
.session_name_len
);
106 if (!lttng_buffer_view_is_valid(&session_name_view
)) {
107 ERR("Invalid payload in \"cmd_create_session_2_11\": buffer too short to contain session name");
112 offset
+= header
.session_name_len
;
113 hostname_view
= lttng_buffer_view_from_view(payload
, offset
, header
.hostname_len
);
114 if (!lttng_buffer_view_is_valid(&hostname_view
)) {
115 ERR("Invalid payload in \"cmd_create_session_2_11\": buffer too short to contain hostname");
120 offset
+= header
.hostname_len
;
121 base_path_view
= lttng_buffer_view_from_view(payload
, offset
, header
.base_path_len
);
122 if (header
.base_path_len
> 0 && !lttng_buffer_view_is_valid(&base_path_view
)) {
123 ERR("Invalid payload in \"cmd_create_session_2_11\": buffer too short to contain base path");
128 /* Validate that names are NULL terminated. */
129 if (session_name_view
.data
[session_name_view
.size
- 1] != '\0') {
130 ERR("cmd_create_session_2_11 session_name is invalid (not NULL terminated)");
135 if (hostname_view
.data
[hostname_view
.size
- 1] != '\0') {
136 ERR("cmd_create_session_2_11 hostname is invalid (not NULL terminated)");
141 if (base_path_view
.size
!= 0 && base_path_view
.data
[base_path_view
.size
- 1] != '\0') {
142 ERR("cmd_create_session_2_11 base_path is invalid (not NULL terminated)");
148 * Length and null-termination check are already performed.
149 * LTTNG_NAME_MAX, LTTNG_HOST_NAME_MAX, and LTTNG_PATH_MAX max sizes are expected.
151 strcpy(session_name
, session_name_view
.data
);
152 strcpy(hostname
, hostname_view
.data
);
153 strcpy(base_path
, base_path_view
.size
? base_path_view
.data
: "");
155 *live_timer
= header
.live_timer
;
156 *snapshot
= !!header
.snapshot
;
157 *current_chunk_id
= header
.current_chunk_id
.value
;
158 *has_current_chunk
= header
.current_chunk_id
.is_set
;
159 *creation_time
= (time_t) header
.creation_time
;
160 *session_name_contains_creation_time
= header
.session_name_contains_creation_time
;
161 *id_sessiond
= header
.session_id
;
170 * cmd_recv_stream_2_11 allocates path_name and channel_name.
172 int cmd_recv_stream_2_11(const struct lttng_buffer_view
*payload
,
173 char **ret_path_name
,
174 char **ret_channel_name
,
175 uint64_t *tracefile_size
,
176 uint64_t *tracefile_count
,
177 uint64_t *trace_archive_id
)
180 struct lttcomm_relayd_add_stream_2_11 header
;
181 size_t header_len
, received_names_size
;
182 struct lttng_buffer_view channel_name_view
;
183 struct lttng_buffer_view pathname_view
;
184 char *path_name
= nullptr;
185 char *channel_name
= nullptr;
187 header_len
= sizeof(header
);
189 if (payload
->size
< header_len
) {
190 ERR("Unexpected payload size in \"cmd_recv_stream_2_11\": expected >= %zu bytes, got %zu bytes",
196 memcpy(&header
, payload
->data
, header_len
);
198 header
.channel_name_len
= be32toh(header
.channel_name_len
);
199 header
.pathname_len
= be32toh(header
.pathname_len
);
200 header
.tracefile_size
= be64toh(header
.tracefile_size
);
201 header
.tracefile_count
= be64toh(header
.tracefile_count
);
202 header
.trace_chunk_id
= be64toh(header
.trace_chunk_id
);
204 received_names_size
= header
.channel_name_len
+ header
.pathname_len
;
205 if (payload
->size
< header_len
+ received_names_size
) {
206 ERR("Unexpected payload size in \"cmd_recv_stream_2_11\": expected >= %zu bytes, got %zu bytes",
207 header_len
+ received_names_size
,
213 /* Validate length against defined constant. */
214 if (header
.channel_name_len
> DEFAULT_STREAM_NAME_LEN
) {
216 ERR("Channel name too long");
219 if (header
.pathname_len
> LTTNG_NAME_MAX
) {
221 ERR("Pathname too long");
225 /* Validate that names are (NULL terminated. */
227 lttng_buffer_view_from_view(payload
, header_len
, header
.channel_name_len
);
228 if (!lttng_buffer_view_is_valid(&channel_name_view
)) {
229 ERR("Invalid payload received in \"cmd_recv_stream_2_11\": buffer too short for channel name");
234 if (channel_name_view
.data
[channel_name_view
.size
- 1] != '\0') {
235 ERR("cmd_recv_stream_2_11 channel_name is invalid (not NULL terminated)");
240 pathname_view
= lttng_buffer_view_from_view(
241 payload
, header_len
+ header
.channel_name_len
, header
.pathname_len
);
242 if (!lttng_buffer_view_is_valid(&pathname_view
)) {
243 ERR("Invalid payload received in \"cmd_recv_stream_2_11\": buffer too short for path name");
248 if (pathname_view
.data
[pathname_view
.size
- 1] != '\0') {
249 ERR("cmd_recv_stream_2_11 patname is invalid (not NULL terminated)");
254 channel_name
= strdup(channel_name_view
.data
);
257 PERROR("Channel name allocation");
261 path_name
= strdup(pathname_view
.data
);
263 PERROR("Path name allocation");
268 *tracefile_size
= header
.tracefile_size
;
269 *tracefile_count
= header
.tracefile_count
;
270 *trace_archive_id
= header
.trace_chunk_id
;
271 *ret_path_name
= path_name
;
272 *ret_channel_name
= channel_name
;
273 /* Move ownership to caller */
275 channel_name
= nullptr;