Fix: lttng_trace_archive_location_serialize is called on freed memory
[lttng-tools.git] / src / common / location.c
CommitLineData
434131e4 1/*
ab5be9fa 2 * Copyright (C) 2018 Jérémie Galarneau <jeremie.galarneau@efficios.com>
434131e4 3 *
ab5be9fa 4 * SPDX-License-Identifier: LGPL-2.1-only
434131e4 5 *
434131e4
JG
6 */
7
8#include <lttng/location-internal.h>
9#include <common/macros.h>
10#include <stdlib.h>
d3740619 11#include <common/error.h>
434131e4
JG
12
13static
14struct lttng_trace_archive_location *lttng_trace_archive_location_create(
15 enum lttng_trace_archive_location_type type)
16{
17 struct lttng_trace_archive_location *location;
18
19 location = zmalloc(sizeof(*location));
20 if (!location) {
21 goto end;
22 }
23
d3740619 24 urcu_ref_init(&location->ref);
434131e4
JG
25 location->type = type;
26end:
27 return location;
28}
29
d3740619
JR
30static
31void trace_archive_location_destroy_ref(struct urcu_ref *ref)
434131e4 32{
d3740619
JR
33 struct lttng_trace_archive_location *location =
34 container_of(ref, struct lttng_trace_archive_location, ref);
434131e4
JG
35
36 switch (location->type) {
37 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
38 free(location->types.local.absolute_path);
39 break;
40 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
41 free(location->types.relay.host);
42 free(location->types.relay.relative_path);
43 break;
44 default:
45 abort();
46 }
47
48 free(location);
49}
50
d3740619
JR
51LTTNG_HIDDEN
52void lttng_trace_archive_location_get(struct lttng_trace_archive_location *location)
53{
54 urcu_ref_get(&location->ref);
55}
56
57LTTNG_HIDDEN
58void lttng_trace_archive_location_put(struct lttng_trace_archive_location *location)
59{
60 if (!location) {
61 return;
62 }
63
64 urcu_ref_put(&location->ref, trace_archive_location_destroy_ref);
65}
66
434131e4
JG
67LTTNG_HIDDEN
68struct lttng_trace_archive_location *lttng_trace_archive_location_local_create(
69 const char *absolute_path)
70{
71 struct lttng_trace_archive_location *location = NULL;
72
73 if (!absolute_path) {
74 goto end;
75 }
76
77 location = lttng_trace_archive_location_create(
78 LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL);
79 if (!location) {
80 goto end;
81 }
82
83 location->types.local.absolute_path = strdup(absolute_path);
84 if (!location->types.local.absolute_path) {
85 goto error;
86 }
87
88end:
89 return location;
90error:
d3740619 91 lttng_trace_archive_location_put(location);
434131e4
JG
92 return NULL;
93}
94
95LTTNG_HIDDEN
96struct lttng_trace_archive_location *lttng_trace_archive_location_relay_create(
97 const char *host,
98 enum lttng_trace_archive_location_relay_protocol_type protocol,
99 uint16_t control_port, uint16_t data_port,
100 const char *relative_path)
101{
102 struct lttng_trace_archive_location *location = NULL;
103
104 if (!host || !relative_path) {
105 goto end;
106 }
107
108 location = lttng_trace_archive_location_create(
109 LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY);
110 if (!location) {
111 goto end;
112 }
113
114 location->types.relay.host = strdup(host);
115 if (!location->types.relay.host) {
116 goto error;
117 }
118 location->types.relay.relative_path = strdup(relative_path);
119 if (!location->types.relay.relative_path) {
120 goto error;
121 }
122
123 location->types.relay.protocol = protocol;
124 location->types.relay.ports.control = control_port;
125 location->types.relay.ports.data = data_port;
126end:
127 return location;
128error:
d3740619 129 lttng_trace_archive_location_put(location);
434131e4
JG
130 return NULL;
131}
132
1e9f1cf8
JG
133LTTNG_HIDDEN
134ssize_t lttng_trace_archive_location_create_from_buffer(
135 const struct lttng_buffer_view *view,
136 struct lttng_trace_archive_location **location)
137{
138 size_t offset = 0;
139 const struct lttng_trace_archive_location_comm *location_comm;
140 struct lttng_buffer_view location_comm_view;
141
142 location_comm_view = lttng_buffer_view_from_view(view, 0,
143 sizeof(*location_comm));
3e6e0df2 144 if (!lttng_buffer_view_is_valid(&location_comm_view)) {
1e9f1cf8
JG
145 goto error;
146 }
3e6e0df2 147
1e9f1cf8 148 offset += location_comm_view.size;
3e6e0df2 149 location_comm = (const struct lttng_trace_archive_location_comm *) location_comm_view.data;
1e9f1cf8
JG
150
151 switch ((enum lttng_trace_archive_location_type) location_comm->type) {
152 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
153 {
154 const struct lttng_buffer_view absolute_path_view =
155 lttng_buffer_view_from_view(view, offset,
156 location_comm->types.local.absolute_path_len);
157
3e6e0df2 158 if (!lttng_buffer_view_is_valid(&absolute_path_view)) {
1e9f1cf8
JG
159 goto error;
160 }
3e6e0df2 161
1e9f1cf8
JG
162 if (absolute_path_view.data[absolute_path_view.size - 1] != '\0') {
163 goto error;
164 }
165 offset += absolute_path_view.size;
166
167 *location = lttng_trace_archive_location_local_create(
168 absolute_path_view.data);
169 if (!*location) {
170 goto error;
171 }
172 break;
173 }
174 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
175 {
176 const struct lttng_buffer_view hostname_view =
177 lttng_buffer_view_from_view(view, offset,
178 location_comm->types.relay.hostname_len);
179 const struct lttng_buffer_view relative_path_view =
180 lttng_buffer_view_from_view(view,
181 offset + hostname_view.size,
182 location_comm->types.relay.relative_path_len);
183
3e6e0df2
JG
184 if (!lttng_buffer_view_is_valid(&hostname_view) ||
185 !lttng_buffer_view_is_valid(
186 &relative_path_view)) {
1e9f1cf8
JG
187 goto error;
188 }
3e6e0df2 189
1e9f1cf8
JG
190 if (hostname_view.data[hostname_view.size - 1] != '\0') {
191 goto error;
192 }
193 if (relative_path_view.data[relative_path_view.size - 1] != '\0') {
194 goto error;
195 }
196 offset += hostname_view.size + relative_path_view.size;
197
198 *location = lttng_trace_archive_location_relay_create(
199 hostname_view.data,
200 (enum lttng_trace_archive_location_relay_protocol_type) location_comm->types.relay.protocol,
201 location_comm->types.relay.ports.control,
202 location_comm->types.relay.ports.data,
203 relative_path_view.data);
204 if (!*location) {
205 goto error;
206 }
207 break;
208 }
209 default:
210 goto error;
211 }
212
e4b6e50f 213 return offset;
1e9f1cf8
JG
214error:
215 return -1;
216}
217
218LTTNG_HIDDEN
219ssize_t lttng_trace_archive_location_serialize(
220 const struct lttng_trace_archive_location *location,
221 struct lttng_dynamic_buffer *buffer)
222{
223 int ret;
224 struct lttng_trace_archive_location_comm location_comm;
1e9f1cf8
JG
225
226 location_comm.type = (int8_t) location->type;
227
228 switch (location->type) {
229 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
230 location_comm.types.local.absolute_path_len =
231 strlen(location->types.local.absolute_path) + 1;
232 break;
233 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
234 location_comm.types.relay.hostname_len =
235 strlen(location->types.relay.host) + 1;
236 location_comm.types.relay.protocol =
237 (int8_t) location->types.relay.protocol;
238 location_comm.types.relay.ports.control =
239 location->types.relay.ports.control;
240 location_comm.types.relay.ports.data =
241 location->types.relay.ports.data;
242 location_comm.types.relay.relative_path_len =
243 strlen(location->types.relay.relative_path) + 1;
244 break;
245 default:
246 abort();
247 }
248
249 ret = lttng_dynamic_buffer_append(buffer, &location_comm,
250 sizeof(location_comm));
251 if (ret) {
252 goto error;
253 }
254
255 switch (location->type) {
256 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
257 ret = lttng_dynamic_buffer_append(buffer,
258 location->types.local.absolute_path,
259 location_comm.types.local.absolute_path_len);
260 if (ret) {
261 goto error;
262 }
263 break;
264 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
265 ret = lttng_dynamic_buffer_append(buffer,
266 location->types.relay.host,
267 location_comm.types.relay.hostname_len);
268 if (ret) {
269 goto error;
270 }
271 ret = lttng_dynamic_buffer_append(buffer,
272 location->types.relay.relative_path,
273 location_comm.types.relay.relative_path_len);
274 if (ret) {
275 goto error;
276 }
277 break;
278 default:
279 abort();
280 }
281
f7daf93a 282 return 0;
1e9f1cf8
JG
283error:
284 return -1;
285}
286
434131e4
JG
287enum lttng_trace_archive_location_type lttng_trace_archive_location_get_type(
288 const struct lttng_trace_archive_location *location)
289{
290 enum lttng_trace_archive_location_type type;
291
292 if (!location) {
293 type = LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_UNKNOWN;
294 goto end;
295 }
296
297 type = location->type;
298end:
299 return type;
300}
301
302enum lttng_trace_archive_location_status
303lttng_trace_archive_location_local_get_absolute_path(
304 const struct lttng_trace_archive_location *location,
305 const char **absolute_path)
306{
307 enum lttng_trace_archive_location_status status =
308 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
309
310 if (!location || !absolute_path ||
311 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL) {
312 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
313 goto end;
314 }
315
316 *absolute_path = location->types.local.absolute_path;
317end:
318 return status;
319}
320
321enum lttng_trace_archive_location_status
322lttng_trace_archive_location_relay_get_host(
323 const struct lttng_trace_archive_location *location,
324 const char **relay_host)
325{
326 enum lttng_trace_archive_location_status status =
327 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
328
329 if (!location || !relay_host ||
330 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
331 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
332 goto end;
333 }
334
335 *relay_host = location->types.relay.host;
336end:
337 return status;
338}
339
340enum lttng_trace_archive_location_status
341lttng_trace_archive_location_relay_get_relative_path(
342 const struct lttng_trace_archive_location *location,
343 const char **relative_path)
344{
345 enum lttng_trace_archive_location_status status =
346 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
347
348 if (!location || !relative_path ||
349 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
350 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
351 goto end;
352 }
353
354 *relative_path = location->types.relay.relative_path;
355end:
356 return status;
357}
358
359enum lttng_trace_archive_location_status
360lttng_trace_archive_location_relay_get_control_port(
361 const struct lttng_trace_archive_location *location,
362 uint16_t *control_port)
363{
364 enum lttng_trace_archive_location_status status =
365 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
366
367 if (!location || !control_port ||
368 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
369 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
370 goto end;
371 }
372
373 *control_port = location->types.relay.ports.control;
374end:
375 return status;
376}
377
378enum lttng_trace_archive_location_status
379lttng_trace_archive_location_relay_get_data_port(
380 const struct lttng_trace_archive_location *location,
381 uint16_t *data_port)
382{
383 enum lttng_trace_archive_location_status status =
384 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
385
386 if (!location || !data_port ||
387 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
388 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
389 goto end;
390 }
391
392 *data_port = location->types.relay.ports.data;
393end:
394 return status;
395}
396
397enum lttng_trace_archive_location_status
398lttng_trace_archive_location_relay_get_protocol_type(
399 const struct lttng_trace_archive_location *location,
400 enum lttng_trace_archive_location_relay_protocol_type *protocol)
401{
402 enum lttng_trace_archive_location_status status =
403 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
404
405 if (!location || !protocol ||
406 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
407 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
408 goto end;
409 }
410
411 *protocol = location->types.relay.protocol;
412end:
413 return status;
414}
This page took 0.050718 seconds and 4 git commands to generate.