/src/opensips/bin_interface.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2013 OpenSIPS Solutions |
3 | | * |
4 | | * This file is part of opensips, a free SIP server. |
5 | | * |
6 | | * opensips is free software; you can redistribute it and/or modify |
7 | | * it under the terms of the GNU General Public License as published by |
8 | | * the Free Software Foundation; either version 2 of the License, or |
9 | | * (at your option) any later version |
10 | | * |
11 | | * opensips is distributed in the hope that it will be useful, |
12 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | | * GNU General Public License for more details. |
15 | | * |
16 | | * You should have received a copy of the GNU General Public License |
17 | | * along with this program; if not, write to the Free Software |
18 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
19 | | * |
20 | | * History: |
21 | | * ------- |
22 | | * 2013-04-10: Created (Liviu) |
23 | | */ |
24 | | |
25 | | #ifndef __BINARY_INTERFACE__ |
26 | | #define __BINARY_INTERFACE__ |
27 | | |
28 | | #include "ip_addr.h" |
29 | | #include "crc.h" |
30 | | #include "net/proto_tcp/tcp_common_defs.h" |
31 | | |
32 | | #define BIN_MAX_BUF_LEN TCP_BUF_SIZE |
33 | | #define BIN_PACKET_MARKER "P4CK" |
34 | | #define BIN_PACKET_MARKER_SIZE 4 |
35 | | #define PKG_LEN_FIELD_SIZE 4 |
36 | | #define VERSION_FIELD_SIZE 2 |
37 | | #define LEN_FIELD_SIZE (sizeof(unsigned short)) |
38 | | #define CMD_FIELD_SIZE sizeof(int) |
39 | | #define HEADER_SIZE \ |
40 | | (BIN_PACKET_MARKER_SIZE + PKG_LEN_FIELD_SIZE + VERSION_FIELD_SIZE) |
41 | | #define MIN_BIN_PACKET_SIZE \ |
42 | | (HEADER_SIZE + LEN_FIELD_SIZE + 1 + CMD_FIELD_SIZE) |
43 | | /* ^ capability */ |
44 | | |
45 | | #define is_valid_bin_packet(_p) \ |
46 | | (memcmp(_p, BIN_PACKET_MARKER, BIN_PACKET_MARKER_SIZE) == 0) |
47 | | |
48 | | /* make sure a BIN packet has an exact version or a range of versions */ |
49 | | #define ensure_bin_version(pkt, needed) _ensure_bin_version(pkt, needed, "") |
50 | | #define ensure_bin_version2(pkt, v1, v2) _ensure_bin_version2(pkt, v1, v2, "") |
51 | | #define _ensure_bin_version(pkt, needed, pkt_desc) \ |
52 | | do { \ |
53 | | if (get_bin_pkg_version(pkt) != (needed)) \ |
54 | | _bin_version_error_return(pkt, pkt_desc, needed) \ |
55 | | } while (0) |
56 | | #define _ensure_bin_version2(pkt, vmin, vmax, pkt_desc) \ |
57 | | do { \ |
58 | | if (get_bin_pkg_version(pkt)<(vmin) || get_bin_pkg_version(pkt)>(vmax)) \ |
59 | | _bin_version_error_return(pkt, pkt_desc, vmax) \ |
60 | | } while (0) |
61 | | #define _bin_version_error_return(pkt, pkt_desc, needed) \ |
62 | | { \ |
63 | | if (pkt_desc && *pkt_desc) \ |
64 | | LM_INFO("discarding %s (%d), ver %d: need ver %d\n", \ |
65 | | pkt_desc, pkt->type, get_bin_pkg_version(pkt), (needed)); \ |
66 | | else \ |
67 | | LM_INFO("discarding packet type %d, ver %d: need ver %d\n", \ |
68 | | pkt->type, get_bin_pkg_version(pkt), (needed)); \ |
69 | | return; \ |
70 | | } |
71 | | |
72 | | typedef unsigned bin_packet_flags_t; |
73 | | #define BINFL_SYSMEM (1U<<0) |
74 | | |
75 | | typedef struct bin_packet { |
76 | | str buffer; |
77 | | char *front_pointer; |
78 | | struct bin_packet *next; |
79 | | int size; |
80 | | int type; |
81 | | bin_packet_flags_t flags; |
82 | | /* not populated by bin_interface */ |
83 | | int src_id; |
84 | | } bin_packet_t; |
85 | | |
86 | | struct packet_cb_list { |
87 | | str capability; /* registered capability */ |
88 | | void (*cbf)(bin_packet_t *, int packet_type, /* callback */ |
89 | | struct receive_info *ri, void *att); |
90 | | void *att; |
91 | | |
92 | | struct packet_cb_list *next; |
93 | | }; |
94 | | |
95 | | /* returns the version of the bin protocol from the given message */ |
96 | | static inline short get_bin_pkg_version(bin_packet_t *packet) |
97 | 0 | { |
98 | 0 | short rval; |
99 | 0 |
|
100 | 0 | memcpy(&rval, packet->buffer.s + BIN_PACKET_MARKER_SIZE |
101 | 0 | + PKG_LEN_FIELD_SIZE, sizeof(rval)); |
102 | 0 | return rval; |
103 | 0 | } Unexecuted instantiation: pt.c:get_bin_pkg_version Unexecuted instantiation: cfg.tab.c:get_bin_pkg_version |
104 | | |
105 | | /* overrides the version of the bin protocol from the given message */ |
106 | | static inline void set_bin_pkg_version(bin_packet_t *packet, short new_version) |
107 | 0 | { |
108 | 0 | memcpy(packet->buffer.s + BIN_PACKET_MARKER_SIZE |
109 | 0 | + PKG_LEN_FIELD_SIZE, &new_version, sizeof(new_version)); |
110 | 0 | } Unexecuted instantiation: pt.c:set_bin_pkg_version Unexecuted instantiation: cfg.tab.c:set_bin_pkg_version |
111 | | |
112 | | /* |
113 | | * returns the capability from the message |
114 | | */ |
115 | | void bin_get_capability(bin_packet_t *packet, str *capability); |
116 | | |
117 | | |
118 | | /** |
119 | | calls all the registered functions |
120 | | |
121 | | @buffer: buffer containing a complete bin message |
122 | | @rcv: information about the sender of the message |
123 | | */ |
124 | | void call_callbacks(char* buffer, struct receive_info *rcv); |
125 | | /* |
126 | | * registers a callback function to be triggered on a received |
127 | | * binary packet marked with the @cap capability |
128 | | */ |
129 | | int bin_register_cb(str *cap, void (*cb)(bin_packet_t *, int, |
130 | | struct receive_info *, void * atr), void *att, int att_len); |
131 | | |
132 | | |
133 | | /** |
134 | | * first function called when building a binary packet |
135 | | * |
136 | | * @capability: capability string |
137 | | * @packet_type: capability specific identifier for this new packet |
138 | | * |
139 | | * @return: 0 on success |
140 | | */ |
141 | | int _bin_init(bin_packet_t *packet, str *capability, int packet_type, short version, |
142 | | int length, int use_sysmalloc); |
143 | | #define bin_init(_pk, _cap, _pt, _ver, _len) \ |
144 | | _bin_init(_pk, _cap, _pt, _ver, _len, 0) |
145 | | |
146 | | /** |
147 | | * function called to build a binary packet with a known buffer |
148 | | * |
149 | | * @packet: the packet that will be populated |
150 | | * @buffer: the buffer that will be attached to the packet |
151 | | * @length: the length of the buffer attached |
152 | | */ |
153 | | void bin_init_buffer(bin_packet_t *packet, char *buffer, int length); |
154 | | |
155 | | /* |
156 | | * appends a buffer to a binary packet |
157 | | * @buf: buffer to be appended |
158 | | * @len: length of @buf |
159 | | * |
160 | | * @return: |
161 | | * > 0: success, the size of the buffer |
162 | | * < 0: internal buffer limit reached |
163 | | */ |
164 | | int bin_append_buffer(bin_packet_t *packet, str *buf); |
165 | | |
166 | | /* |
167 | | * adds a new string value to the packet being currently built |
168 | | * @info: may also be NULL |
169 | | * |
170 | | * @return: |
171 | | * > 0: success, the size of the buffer |
172 | | * < 0: internal buffer limit reached |
173 | | */ |
174 | | int bin_push_str(bin_packet_t *packet, const str *info); |
175 | | |
176 | | /* |
177 | | * adds a new integer value to the packet being currently built |
178 | | * |
179 | | * @return: |
180 | | * > 0: success, the size of the buffer |
181 | | * < 0: internal buffer limit reached |
182 | | */ |
183 | | int bin_push_int(bin_packet_t *packet, int info); |
184 | | |
185 | | /* |
186 | | * removes an integer from the end of the packet |
187 | | * |
188 | | * @return: |
189 | | * 0: success |
190 | | * < 0: error, no more integers in buffer |
191 | | */ |
192 | | int bin_remove_int_buffer_end(bin_packet_t *packet, int count); |
193 | | |
194 | | /* |
195 | | * skips @count integers in the end of the packet |
196 | | * |
197 | | * @return: |
198 | | * 0: success |
199 | | * < 0: error, no more integers in buffer |
200 | | */ |
201 | | int bin_skip_int_packet_end(bin_packet_t *packet, int count); |
202 | | |
203 | | /* |
204 | | * pops a str structure from binary packet |
205 | | * @info: pointer to store the result |
206 | | * |
207 | | * @return: |
208 | | * 0 (success): info retrieved |
209 | | * 1 (success): nothing returned, all data has been consumed! |
210 | | * < 0: error |
211 | | * |
212 | | * Note: The pointer returned in @info is only valid for the duration of |
213 | | * the callback. Don't forget to copy the data into a safe buffer! |
214 | | * |
215 | | * Note2: Information is retrieved in the same order it was stored |
216 | | */ |
217 | | int bin_pop_str(bin_packet_t *packet, str *info); |
218 | | |
219 | | /* |
220 | | * pops an integer from the front of the packet |
221 | | * @info: pointer to store the result |
222 | | * |
223 | | * @return: |
224 | | * 0 (success): info retrieved |
225 | | * 1 (success): nothing returned, all data has been consumed! |
226 | | * < 0: error |
227 | | * |
228 | | * Note: Information is retrieved in the same order it was stored |
229 | | */ |
230 | | int bin_pop_int(bin_packet_t *packet, void *info); |
231 | | |
232 | | /* |
233 | | * pops an integer from the end of binary packet |
234 | | * @info: pointer to store the result |
235 | | * |
236 | | * @return: |
237 | | * 0 (success): info retrieved |
238 | | * 1 (success): nothing returned, all data has been consumed! |
239 | | * < 0: error |
240 | | */ |
241 | | int bin_pop_back_int(bin_packet_t *packet, void *info); |
242 | | |
243 | | /* |
244 | | * skips @count integers from a received binary packet |
245 | | * |
246 | | * @return: |
247 | | * >= 0: success, number of skipped bytes |
248 | | * < 0: error, buffer limit reached |
249 | | */ |
250 | | int bin_skip_int(bin_packet_t *packet, int count); |
251 | | |
252 | | /* |
253 | | * skips @count strings from a received binary packet |
254 | | * |
255 | | * @return: |
256 | | * >= 0: success, number of skipped bytes |
257 | | * < 0: error, buffer limit reached |
258 | | */ |
259 | | int bin_skip_str(bin_packet_t *packet, int count); |
260 | | |
261 | | /* |
262 | | * frees the memory used by the binary packet |
263 | | */ |
264 | | void bin_free_packet(bin_packet_t *packet); |
265 | | |
266 | | /* |
267 | | * resets the packet, equivalent to calling bin_free_packet, |
268 | | * then reinitializing the packet |
269 | | */ |
270 | | int bin_reset_back_pointer(bin_packet_t *packet); |
271 | | /* |
272 | | * returns the buffer with the data in the bin packet |
273 | | */ |
274 | | int bin_get_buffer(bin_packet_t *packet, str *buffer); |
275 | | |
276 | | /* |
277 | | * returns the bin packet's buffer from the position where |
278 | | * the serialized content actually starts |
279 | | */ |
280 | | int bin_get_content_start(bin_packet_t *packet, str *buf); |
281 | | |
282 | | /* |
283 | | * returns the bin packet's buffer from the position of the |
284 | | * next field to be consumed |
285 | | */ |
286 | | int bin_get_content_pos(bin_packet_t *packet, str *buf); |
287 | | |
288 | | #endif /* __BINARY_INTERFACE__ */ |
289 | | |