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