Line data Source code
1 : /* SPDX-License-Identifier: GPL-2.0-only */
2 : /*
3 : * Copyright (c) 2023 Meta Platforms, Inc. and affiliates.
4 : */
5 :
6 : #include "bpfilter/response.h"
7 :
8 : #include <errno.h>
9 : #include <stddef.h>
10 : #include <stdio.h>
11 : #include <stdlib.h>
12 :
13 : #include "bpfilter/dynbuf.h"
14 : #include "bpfilter/helper.h"
15 :
16 : /**
17 : * @brief Response message sent from the daemon to the client.
18 : */
19 : struct bf_response
20 : {
21 : /** Response status: 0 on success, or a negative error value on failure. */
22 : int status;
23 :
24 : /** Number of bytes stored in `data`. */
25 : size_t data_len;
26 :
27 : /** Data carried by the response. */
28 : char data[];
29 : };
30 :
31 0 : int bf_response_new_raw(struct bf_response **response, size_t data_len)
32 : {
33 0 : bf_assert(response);
34 :
35 0 : *response = malloc(sizeof(**response) + data_len);
36 0 : if (!*response)
37 : return -ENOMEM;
38 :
39 0 : (*response)->status = 0;
40 :
41 0 : return 0;
42 : }
43 :
44 0 : int bf_response_new_success(struct bf_response **response, const char *data,
45 : size_t data_len)
46 : {
47 0 : _free_bf_response_ struct bf_response *_response = NULL;
48 :
49 0 : bf_assert(response);
50 0 : bf_assert(!(!!data ^ !!data_len));
51 :
52 0 : _response = calloc(1, sizeof(*_response) + data_len);
53 0 : if (!_response)
54 : return -ENOMEM;
55 :
56 0 : _response->status = 0;
57 0 : _response->data_len = data_len;
58 0 : bf_memcpy(_response->data, data, data_len);
59 :
60 0 : *response = TAKE_PTR(_response);
61 :
62 0 : return 0;
63 : }
64 :
65 0 : int bf_response_new_from_dynbuf(struct bf_response **response,
66 : struct bf_dynbuf *dynbuf)
67 : {
68 : struct bf_response *tmpres;
69 :
70 0 : bf_assert(response);
71 0 : bf_assert(dynbuf);
72 :
73 0 : if (dynbuf->len < sizeof(*tmpres))
74 : return -EINVAL;
75 :
76 0 : tmpres = dynbuf->data;
77 0 : if (bf_response_size(tmpres) != dynbuf->len)
78 : return -EINVAL;
79 :
80 0 : *response = bf_dynbuf_take(dynbuf);
81 :
82 0 : return 0;
83 : }
84 :
85 0 : int bf_response_new_from_pack(struct bf_response **response, bf_wpack_t *pack)
86 : {
87 : const void *data;
88 : size_t data_len;
89 : int r;
90 :
91 0 : bf_assert(response);
92 0 : bf_assert(pack);
93 :
94 0 : if (!bf_wpack_is_valid(pack))
95 : return -EINVAL;
96 :
97 0 : r = bf_wpack_get_data(pack, &data, &data_len);
98 0 : if (r)
99 : return r;
100 :
101 0 : return bf_response_new_success(response, data, data_len);
102 : }
103 :
104 0 : int bf_response_new_failure(struct bf_response **response, int error)
105 : {
106 0 : _free_bf_response_ struct bf_response *_response = NULL;
107 :
108 0 : bf_assert(response);
109 :
110 0 : _response = calloc(1, sizeof(*_response));
111 0 : if (!_response)
112 : return -ENOMEM;
113 :
114 0 : _response->status = error;
115 :
116 0 : *response = TAKE_PTR(_response);
117 :
118 0 : return 0;
119 : }
120 :
121 0 : void bf_response_free(struct bf_response **response)
122 : {
123 0 : free(*response);
124 0 : *response = NULL;
125 0 : }
126 :
127 0 : int bf_response_copy(struct bf_response **dest, const struct bf_response *src)
128 : {
129 0 : _free_bf_response_ struct bf_response *_response = NULL;
130 :
131 0 : bf_assert(dest);
132 0 : bf_assert(src);
133 :
134 0 : _response = bf_memdup(src, bf_response_size(src));
135 0 : if (!_response)
136 : return -ENOMEM;
137 :
138 0 : *dest = TAKE_PTR(_response);
139 :
140 0 : return 0;
141 : }
142 :
143 0 : int bf_response_status(const struct bf_response *response)
144 : {
145 0 : bf_assert(response);
146 :
147 0 : return response->status;
148 : }
149 :
150 0 : const void *bf_response_data(const struct bf_response *response)
151 : {
152 0 : bf_assert(response);
153 :
154 0 : return response->data;
155 : }
156 :
157 0 : size_t bf_response_data_len(const struct bf_response *response)
158 : {
159 0 : bf_assert(response);
160 :
161 0 : return response->data_len;
162 : }
163 :
164 0 : size_t bf_response_size(const struct bf_response *response)
165 : {
166 0 : bf_assert(response);
167 :
168 0 : return sizeof(*response) + response->data_len;
169 : }
|