Coverage Report

Created: 2025-10-13 06:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opensips/bin_interface.h
Line
Count
Source
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
/* this padding helps us simply "cast" a received packet as a sending packet
33
 * with zero overhead; otherwise, we'd need to memcpy it from SHM->PKG */
34
#define BIN_CL_RSV_SZ ((1+3+1) * sizeof(int))
35
         // req_like + msg_add_trailer() + src_cluster (agg)
36
37
#define BIN_MAX_BUF_LEN (TCP_BUF_SIZE - BIN_CL_RSV_SZ)
38
#define BIN_PACKET_MARKER      "P4CK"
39
#define BIN_PACKET_MARKER_SIZE 4
40
#define PKG_LEN_FIELD_SIZE     4
41
#define VERSION_FIELD_SIZE     2
42
#define LEN_FIELD_SIZE         (sizeof(unsigned short))
43
#define CMD_FIELD_SIZE         sizeof(int)
44
#define HEADER_SIZE \
45
      (BIN_PACKET_MARKER_SIZE + PKG_LEN_FIELD_SIZE + VERSION_FIELD_SIZE)
46
#define MIN_BIN_PACKET_SIZE \
47
      (HEADER_SIZE + LEN_FIELD_SIZE + 1 + CMD_FIELD_SIZE)
48
                                         /* ^ capability */
49
50
#define is_valid_bin_packet(_p) \
51
  (memcmp(_p, BIN_PACKET_MARKER, BIN_PACKET_MARKER_SIZE) == 0)
52
53
/* make sure a BIN packet has an exact version or a range of versions */
54
#define ensure_bin_version(pkt, needed) _ensure_bin_version(pkt, needed, "")
55
#define ensure_bin_version2(pkt, v1, v2) _ensure_bin_version2(pkt, v1, v2, "")
56
#define _ensure_bin_version(pkt, needed, pkt_desc) \
57
  do { \
58
    if (get_bin_pkg_version(pkt) != (needed)) \
59
      _bin_version_error_return(pkt, pkt_desc, needed) \
60
  } while (0)
61
#define _ensure_bin_version2(pkt, vmin, vmax, pkt_desc) \
62
  do { \
63
    if (get_bin_pkg_version(pkt)<(vmin) || get_bin_pkg_version(pkt)>(vmax)) \
64
      _bin_version_error_return(pkt, pkt_desc, vmax) \
65
  } while (0)
66
#define _bin_version_error_return(pkt, pkt_desc, needed) \
67
  { \
68
    if (pkt_desc && *pkt_desc) \
69
      LM_INFO("discarding %s (%d), ver %d: need ver %d\n", \
70
              pkt_desc, pkt->type, get_bin_pkg_version(pkt), (needed)); \
71
    else \
72
      LM_INFO("discarding packet type %d, ver %d: need ver %d\n", \
73
              pkt->type, get_bin_pkg_version(pkt), (needed)); \
74
    return; \
75
  }
76
77
typedef unsigned bin_packet_flags_t;
78
#define BINFL_SYSMEM (1U<<0)
79
80
typedef struct bin_packet {
81
  str buffer;
82
  char *front_pointer;
83
  struct bin_packet *next;
84
  int size;
85
  int type;
86
  bin_packet_flags_t flags;
87
  /* not populated by bin_interface */
88
  int src_id;
89
} bin_packet_t;
90
91
struct packet_cb_list {
92
  str capability;                  /* registered capability */
93
  void (*cbf)(bin_packet_t *, int packet_type,   /* callback */
94
        struct receive_info *ri, void *att);
95
        void *att;
96
97
  struct packet_cb_list *next;
98
};
99
100
/* returns the version of the bin protocol from the given message */
101
static inline short get_bin_pkg_version(bin_packet_t *packet)
102
0
{
103
0
  short rval;
104
0
105
0
  memcpy(&rval, packet->buffer.s + BIN_PACKET_MARKER_SIZE
106
0
      + PKG_LEN_FIELD_SIZE, sizeof(rval));
107
0
  return rval;
108
0
}
Unexecuted instantiation: pt.c:get_bin_pkg_version
Unexecuted instantiation: cfg.tab.c:get_bin_pkg_version
109
110
/* overrides the version of the bin protocol from the given message */
111
static inline void set_bin_pkg_version(bin_packet_t *packet, short new_version)
112
0
{
113
0
  memcpy(packet->buffer.s + BIN_PACKET_MARKER_SIZE
114
0
             + PKG_LEN_FIELD_SIZE, &new_version, sizeof(new_version));
115
0
}
Unexecuted instantiation: pt.c:set_bin_pkg_version
Unexecuted instantiation: cfg.tab.c:set_bin_pkg_version
116
117
/*
118
 * returns the capability from the message
119
 */
120
void bin_get_capability(bin_packet_t *packet, str *capability);
121
void bin_set_packet_type(bin_packet_t *packet, int packet_type);
122
123
124
/**
125
  calls all the registered functions
126
127
  @buffer: buffer containing a complete bin message
128
  @rcv:    information about the sender of the message
129
 */
130
void call_callbacks(char* buffer, struct receive_info *rcv);
131
/*
132
 * registers a callback function to be triggered on a received
133
 * binary packet marked with the @cap capability
134
 */
135
int bin_register_cb(str *cap, void (*cb)(bin_packet_t *, int,
136
        struct receive_info *, void * atr), void *att, int att_len);
137
138
139
/**
140
 * first function called when building a binary packet
141
 *
142
 * @capability:   capability string
143
 * @packet_type:  capability specific identifier for this new packet
144
 *
145
 * @return: 0 on success
146
 */
147
int _bin_init(bin_packet_t *packet, str *capability, int packet_type, short version,
148
        int length, int use_sysmalloc);
149
#define bin_init(_pk, _cap, _pt, _ver, _len) \
150
  _bin_init(_pk, _cap, _pt, _ver, _len, 0)
151
152
/**
153
 * function called to build a binary packet with a known buffer
154
 *
155
 * @packet: the packet that will be populated
156
 * @buffer: the buffer that will be attached to the packet
157
 * @length: the length of the buffer attached
158
 */
159
void bin_init_buffer(bin_packet_t *packet, char *buffer, int length);
160
161
/*
162
 * appends a buffer to a binary packet
163
 * @buf: buffer to be appended
164
 * @len: length of @buf
165
 *
166
 * @return:
167
 *    > 0: success, the size of the buffer
168
 *    < 0: internal buffer limit reached
169
 */
170
int bin_append_buffer(bin_packet_t *packet, str *buf);
171
172
/*
173
 * adds a new string value to the packet being currently built
174
 * @info: may also be NULL
175
 *
176
 * @return:
177
 *    > 0: success, the size of the buffer
178
 *    < 0: internal buffer limit reached
179
 */
180
int bin_push_str(bin_packet_t *packet, const str *info);
181
182
/*
183
 * adds a new integer value to the packet being currently built
184
 *
185
 * @return:
186
 *    > 0: success, the size of the buffer
187
 *    < 0: internal buffer limit reached
188
 */
189
int bin_push_int(bin_packet_t *packet, int info);
190
191
/*
192
 * removes an integer from the end of the packet
193
 *
194
 * @return:
195
 *    0: success
196
 *    < 0: error, no more integers in buffer
197
 */
198
int bin_remove_int_buffer_end(bin_packet_t *packet, int count);
199
200
/*
201
 * skips @count integers in the end of the packet
202
 *
203
 * @return:
204
 *    0: success
205
 *    < 0: error, no more integers in buffer
206
 */
207
int bin_skip_int_packet_end(bin_packet_t *packet, int count);
208
209
/*
210
 * pops a str structure from binary packet
211
 * @info:   pointer to store the result
212
 *
213
 * @return:
214
 *    0 (success): info retrieved
215
 *    1 (success): nothing returned, all data has been consumed!
216
 *    < 0: error
217
 *
218
 * Note: The pointer returned in @info is only valid for the duration of
219
 *       the callback. Don't forget to copy the data into a safe buffer!
220
 *
221
 * Note2: Information is retrieved in the same order it was stored
222
 */
223
int bin_pop_str(bin_packet_t *packet, str *info);
224
225
/*
226
 * pops an integer from the front of the packet
227
 * @info:   pointer to store the result
228
 *
229
 * @return:
230
 *    0 (success): info retrieved
231
 *    1 (success): nothing returned, all data has been consumed!
232
 *    < 0: error
233
 *
234
 * Note: Information is retrieved in the same order it was stored
235
 */
236
int bin_pop_int(bin_packet_t *packet, void *info);
237
238
/*
239
 * pops an integer from the end of binary packet
240
 * @info:   pointer to store the result
241
 *
242
 * @return:
243
 *    0 (success): info retrieved
244
 *    1 (success): nothing returned, all data has been consumed!
245
 *    < 0: error
246
 */
247
int bin_pop_back_int(bin_packet_t *packet, void *info);
248
249
/*
250
 * skips @count integers from a received binary packet
251
 *
252
 * @return:
253
 *    >= 0: success, number of skipped bytes
254
 *    <  0: error, buffer limit reached
255
 */
256
int bin_skip_int(bin_packet_t *packet, int count);
257
258
/*
259
 * skips @count strings from a received binary packet
260
 *
261
 * @return:
262
 *    >= 0: success, number of skipped bytes
263
 *    <  0: error, buffer limit reached
264
 */
265
int bin_skip_str(bin_packet_t *packet, int count);
266
267
/*
268
 * frees the memory used by the binary packet
269
 */
270
void bin_free_packet(bin_packet_t *packet);
271
272
/*
273
 * resets the packet, equivalent to calling bin_free_packet,
274
 * then reinitializing the packet
275
 */
276
int bin_reset_back_pointer(bin_packet_t *packet);
277
/*
278
 * returns the buffer with the data in the bin packet
279
*/
280
int bin_get_buffer(bin_packet_t *packet, str *buffer);
281
282
/*
283
 * returns the bin packet's buffer from the position where
284
 * the serialized content actually starts
285
*/
286
int bin_get_content_start(bin_packet_t *packet, str *buf);
287
288
/*
289
 * returns the bin packet's buffer from the position of the
290
 * next field to be consumed
291
*/
292
int bin_get_content_pos(bin_packet_t *packet, str *buf);
293
294
#endif /* __BINARY_INTERFACE__ */
295