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>
b0563fed 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
b0563fed 24 urcu_ref_init(&location->ref);
434131e4
JG
25 location->type = type;
26end:
27 return location;
28}
29
b0563fed
JR
30static
31void trace_archive_location_destroy_ref(struct urcu_ref *ref)
434131e4 32{
b0563fed
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
b0563fed
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:
b0563fed 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:
b0563fed 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));
144 if (!location_comm_view.data) {
145 goto error;
146 }
147 offset += location_comm_view.size;
148 location_comm = (const struct lttng_trace_archive_location_comm *) view->data;
149
150 switch ((enum lttng_trace_archive_location_type) location_comm->type) {
151 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
152 {
153 const struct lttng_buffer_view absolute_path_view =
154 lttng_buffer_view_from_view(view, offset,
155 location_comm->types.local.absolute_path_len);
156
157 if (!absolute_path_view.data) {
158 goto error;
159 }
160 if (absolute_path_view.data[absolute_path_view.size - 1] != '\0') {
161 goto error;
162 }
163 offset += absolute_path_view.size;
164
165 *location = lttng_trace_archive_location_local_create(
166 absolute_path_view.data);
167 if (!*location) {
168 goto error;
169 }
170 break;
171 }
172 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
173 {
174 const struct lttng_buffer_view hostname_view =
175 lttng_buffer_view_from_view(view, offset,
176 location_comm->types.relay.hostname_len);
177 const struct lttng_buffer_view relative_path_view =
178 lttng_buffer_view_from_view(view,
179 offset + hostname_view.size,
180 location_comm->types.relay.relative_path_len);
181
182 if (!hostname_view.data || !relative_path_view.data) {
183 goto error;
184 }
185 if (hostname_view.data[hostname_view.size - 1] != '\0') {
186 goto error;
187 }
188 if (relative_path_view.data[relative_path_view.size - 1] != '\0') {
189 goto error;
190 }
191 offset += hostname_view.size + relative_path_view.size;
192
193 *location = lttng_trace_archive_location_relay_create(
194 hostname_view.data,
195 (enum lttng_trace_archive_location_relay_protocol_type) location_comm->types.relay.protocol,
196 location_comm->types.relay.ports.control,
197 location_comm->types.relay.ports.data,
198 relative_path_view.data);
199 if (!*location) {
200 goto error;
201 }
202 break;
203 }
204 default:
205 goto error;
206 }
207
e4b6e50f 208 return offset;
1e9f1cf8
JG
209error:
210 return -1;
211}
212
213LTTNG_HIDDEN
214ssize_t lttng_trace_archive_location_serialize(
215 const struct lttng_trace_archive_location *location,
216 struct lttng_dynamic_buffer *buffer)
217{
218 int ret;
219 struct lttng_trace_archive_location_comm location_comm;
1e9f1cf8
JG
220
221 location_comm.type = (int8_t) location->type;
222
223 switch (location->type) {
224 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
225 location_comm.types.local.absolute_path_len =
226 strlen(location->types.local.absolute_path) + 1;
227 break;
228 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
229 location_comm.types.relay.hostname_len =
230 strlen(location->types.relay.host) + 1;
231 location_comm.types.relay.protocol =
232 (int8_t) location->types.relay.protocol;
233 location_comm.types.relay.ports.control =
234 location->types.relay.ports.control;
235 location_comm.types.relay.ports.data =
236 location->types.relay.ports.data;
237 location_comm.types.relay.relative_path_len =
238 strlen(location->types.relay.relative_path) + 1;
239 break;
240 default:
241 abort();
242 }
243
244 ret = lttng_dynamic_buffer_append(buffer, &location_comm,
245 sizeof(location_comm));
246 if (ret) {
247 goto error;
248 }
249
250 switch (location->type) {
251 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL:
252 ret = lttng_dynamic_buffer_append(buffer,
253 location->types.local.absolute_path,
254 location_comm.types.local.absolute_path_len);
255 if (ret) {
256 goto error;
257 }
258 break;
259 case LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY:
260 ret = lttng_dynamic_buffer_append(buffer,
261 location->types.relay.host,
262 location_comm.types.relay.hostname_len);
263 if (ret) {
264 goto error;
265 }
266 ret = lttng_dynamic_buffer_append(buffer,
267 location->types.relay.relative_path,
268 location_comm.types.relay.relative_path_len);
269 if (ret) {
270 goto error;
271 }
272 break;
273 default:
274 abort();
275 }
276
f7daf93a 277 return 0;
1e9f1cf8
JG
278error:
279 return -1;
280}
281
434131e4
JG
282enum lttng_trace_archive_location_type lttng_trace_archive_location_get_type(
283 const struct lttng_trace_archive_location *location)
284{
285 enum lttng_trace_archive_location_type type;
286
287 if (!location) {
288 type = LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_UNKNOWN;
289 goto end;
290 }
291
292 type = location->type;
293end:
294 return type;
295}
296
297enum lttng_trace_archive_location_status
298lttng_trace_archive_location_local_get_absolute_path(
299 const struct lttng_trace_archive_location *location,
300 const char **absolute_path)
301{
302 enum lttng_trace_archive_location_status status =
303 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
304
305 if (!location || !absolute_path ||
306 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_LOCAL) {
307 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
308 goto end;
309 }
310
311 *absolute_path = location->types.local.absolute_path;
312end:
313 return status;
314}
315
316enum lttng_trace_archive_location_status
317lttng_trace_archive_location_relay_get_host(
318 const struct lttng_trace_archive_location *location,
319 const char **relay_host)
320{
321 enum lttng_trace_archive_location_status status =
322 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
323
324 if (!location || !relay_host ||
325 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
326 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
327 goto end;
328 }
329
330 *relay_host = location->types.relay.host;
331end:
332 return status;
333}
334
335enum lttng_trace_archive_location_status
336lttng_trace_archive_location_relay_get_relative_path(
337 const struct lttng_trace_archive_location *location,
338 const char **relative_path)
339{
340 enum lttng_trace_archive_location_status status =
341 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
342
343 if (!location || !relative_path ||
344 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
345 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
346 goto end;
347 }
348
349 *relative_path = location->types.relay.relative_path;
350end:
351 return status;
352}
353
354enum lttng_trace_archive_location_status
355lttng_trace_archive_location_relay_get_control_port(
356 const struct lttng_trace_archive_location *location,
357 uint16_t *control_port)
358{
359 enum lttng_trace_archive_location_status status =
360 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
361
362 if (!location || !control_port ||
363 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
364 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
365 goto end;
366 }
367
368 *control_port = location->types.relay.ports.control;
369end:
370 return status;
371}
372
373enum lttng_trace_archive_location_status
374lttng_trace_archive_location_relay_get_data_port(
375 const struct lttng_trace_archive_location *location,
376 uint16_t *data_port)
377{
378 enum lttng_trace_archive_location_status status =
379 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
380
381 if (!location || !data_port ||
382 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
383 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
384 goto end;
385 }
386
387 *data_port = location->types.relay.ports.data;
388end:
389 return status;
390}
391
392enum lttng_trace_archive_location_status
393lttng_trace_archive_location_relay_get_protocol_type(
394 const struct lttng_trace_archive_location *location,
395 enum lttng_trace_archive_location_relay_protocol_type *protocol)
396{
397 enum lttng_trace_archive_location_status status =
398 LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_OK;
399
400 if (!location || !protocol ||
401 location->type != LTTNG_TRACE_ARCHIVE_LOCATION_TYPE_RELAY) {
402 status = LTTNG_TRACE_ARCHIVE_LOCATION_STATUS_INVALID;
403 goto end;
404 }
405
406 *protocol = location->types.relay.protocol;
407end:
408 return status;
409}
This page took 0.056706 seconds and 5 git commands to generate.