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