Coverage Report

Created: 2025-07-11 06:28

/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