Browse code

utils: fix format truncation warning

> conf.c: In function 'update_filter':
> conf.c:211:31: warning: ':' directive output may be truncated writing 1 byte into a region of size between 0 and 1000 [-Wformat-truncation=]
> snprintf(buf, BUFSIZE, "%s:%s", tmp, token);
> ^
> conf.c:211:5: note: 'snprintf' output 2 or more bytes (assuming 1002) into a destination of size 1000
> snprintf(buf, BUFSIZE, "%s:%s", tmp, token);
> ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Victor Seva authored on 27/09/2018 13:32:31
Showing 1 changed files
... ...
@@ -208,7 +208,9 @@ static int update_filter(int id, char *flist)
208 208
 		/* no special filter! */
209 209
 			if (buf[0]) {
210 210
 				strcpy(tmp, buf);
211
-				snprintf(buf, BUFSIZE, "%s:%s", tmp, token);
211
+				if(snprintf(buf, BUFSIZE, "%s:%s", tmp, token)>BUFSIZE) {
212
+					LM_BUG("output was truncated\n");
213
+				}
212 214
 				buf[BUFSIZE]='\0';
213 215
 			} else {
214 216
 				snprintf(buf, BUFSIZE, "%s", token);
Browse code

utils: mi commands disabled

Daniel-Constantin Mierla authored on 04/01/2017 14:18:38
Showing 1 changed files
... ...
@@ -13,14 +13,14 @@
13 13
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 14
  * GNU General Public License for more details.
15 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 
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 18
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19 19
  */
20 20
 
21 21
 /*!
22 22
  * \file
23
- * \brief Kamailio utils :: 
23
+ * \brief Kamailio utils ::
24 24
  * \ingroup utils
25 25
  * Module: \ref utils
26 26
  */
... ...
@@ -335,6 +335,7 @@ int conf_parse_switch(char *settings)
335 335
 }
336 336
 
337 337
 
338
+#ifdef MI_REMOVED
338 339
 /*!
339 340
  * \brief Output configuration in FIFO format
340 341
  * \param rpl_tree FIFO root
... ...
@@ -388,7 +389,7 @@ int conf_show(struct mi_root* rpl_tree)
388 389
 error:
389 390
 	return -1;
390 391
 }
391
-
392
+#endif
392 393
 
393 394
 /*!
394 395
  * \brief Parses a configuration string for the filter
Browse code

core, lib, modules: updated include paths for header files

Daniel-Constantin Mierla authored on 07/12/2016 11:07:22
Showing 1 changed files
... ...
@@ -26,10 +26,10 @@
26 26
  */
27 27
 
28 28
 #include "conf.h"
29
-#include "../../mem/mem.h"
30
-#include "../../mem/shm_mem.h"
31
-#include "../../sr_module.h"
32
-#include "../../proxy.h"
29
+#include "../../core/mem/mem.h"
30
+#include "../../core/mem/shm_mem.h"
31
+#include "../../core/sr_module.h"
32
+#include "../../core/proxy.h"
33 33
 #include <ctype.h>
34 34
 #include <errno.h>
35 35
 #include <limits.h>
Browse code

core, lib, modules: restructured source code tree

- new folder src/ to hold the source code for main project applications
- main.c is in src/
- all core files are subfolder are in src/core/
- modules are in src/modules/
- libs are in src/lib/
- application Makefiles are in src/
- application binary is built in src/ (src/kamailio)

Daniel-Constantin Mierla authored on 07/12/2016 11:03:51
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,580 @@
1
+/*
2
+ * Copyright (C) 2009 1&1 Internet AG
3
+ *
4
+ * This file is part of Kamailio, a free SIP server.
5
+ *
6
+ * Kamailio 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
+ * Kamailio 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
+
21
+/*!
22
+ * \file
23
+ * \brief Kamailio utils :: 
24
+ * \ingroup utils
25
+ * Module: \ref utils
26
+ */
27
+
28
+#include "conf.h"
29
+#include "../../mem/mem.h"
30
+#include "../../mem/shm_mem.h"
31
+#include "../../sr_module.h"
32
+#include "../../proxy.h"
33
+#include <ctype.h>
34
+#include <errno.h>
35
+#include <limits.h>
36
+#include <string.h>
37
+#include <stdlib.h>
38
+#include <stdio.h>
39
+
40
+#define BUFSIZE 1000
41
+
42
+/*! \brief special filter indices */
43
+enum {
44
+	sfidx_request = 0,
45
+	sfidx_reply,
46
+	sfilter_cnt
47
+};
48
+
49
+/*! special filter masks */
50
+static int sfilter_mask[sfilter_cnt] = { 1, 2 };
51
+
52
+/*! special filter names */
53
+static char *sfilter_str[sfilter_cnt] = {
54
+	"REQUEST",
55
+	"REPLY"
56
+};
57
+
58
+
59
+struct fwd_setting {
60
+	int active;
61
+	int sfilter;
62
+	char *filter_methods;
63
+	struct proxy_l* proxy;
64
+};
65
+
66
+
67
+static struct fwd_setting *fwd_settings = NULL;
68
+static int fwd_max_id = 0;
69
+
70
+
71
+/*!
72
+ * \brief Removes white spaces and new lines from s
73
+ * \todo check if we can use the functions from ut.h
74
+ * Removes white spaces and new lines from s, the contents of s are modified.
75
+ * \param s the string.
76
+ */
77
+static void remove_spaces(char *s)
78
+{
79
+	char *p, *dst;
80
+	for (p = s, dst = s; *p != '\0'; ++p) {
81
+		if (!isspace(*p)) *dst++ = *p;
82
+	}
83
+	*dst = '\0';
84
+
85
+}
86
+
87
+
88
+/*!
89
+ * \brief Converts a string to integer.
90
+ * \todo check if we can use the functions from ut.h
91
+ *  params:
92
+ *    s: The string to be converted to int.
93
+ *  returns:
94
+ *    >=0 on success
95
+ *     -1 otherwise
96
+ */
97
+static int conf_str2int(char *s)
98
+{
99
+	if (s == NULL) return -1;
100
+
101
+	errno = 0;
102
+	char *end = NULL;
103
+	long int i = strtol(s, &end, 10);
104
+	if ((errno != 0) || (i == LONG_MIN) || (i == LONG_MAX) || (end == s)) {
105
+		LM_ERR("invalid string '%s'.\n", s);
106
+		return -1;
107
+	}
108
+
109
+	return i;
110
+}
111
+
112
+
113
+/*!
114
+ * \brief Converts string to integer and checks for validity.
115
+ * \todo check if we can use the functions from ut.h
116
+ *  params:
117
+ *    id_str: ID as string to be converted to int.
118
+ *  returns:
119
+ *    >=0 on success
120
+ *     -1 otherwise
121
+ */
122
+int conf_str2id(char *id_str)
123
+{
124
+	int id = conf_str2int(id_str);
125
+
126
+	if ((id<0) || (id > fwd_max_id)) {
127
+	LM_ERR("id %d is out of range.\n", id);
128
+	return -1;
129
+	}
130
+
131
+	return id;
132
+}
133
+
134
+
135
+/*!
136
+ * \brief Updates switch configuration
137
+ * \param id Update the configuration with this ID.
138
+ * \param param_str can be either "off" or "on".
139
+ * \return 0 on success, -1 otherwise
140
+ */
141
+static int update_switch(int id, char* param_str)
142
+{
143
+	if (param_str == NULL) {
144
+		LM_ERR("param_str is NULL.\n");
145
+		return -1;
146
+	}
147
+
148
+	if (strcmp(param_str, "on") == 0) {
149
+		fwd_settings[id].active = 1;
150
+		return 0;
151
+	} else if (strcmp(param_str, "off") == 0) {
152
+		fwd_settings[id].active = 0;
153
+		return 0;
154
+	}
155
+
156
+	LM_ERR("invalid switch '%s'.\n", param_str);
157
+	return -1;
158
+}
159
+
160
+
161
+/*!
162
+ * \brief Updates filter configuration.
163
+ * Updates filter configuration.
164
+ * If filter_methods is not NULL, memory is freed.
165
+ * If filter methods are found, memory for the string is allocated,
166
+ * otherwise filter_methods is set to NULL.
167
+ * \param id update the configuration with this ID.
168
+ * \param flist a list of filter names.
169
+ * \return 0 on success, -1 otherwise
170
+ */
171
+static int update_filter(int id, char *flist)
172
+{
173
+	if (flist == NULL) {
174
+		LM_ERR("flist is NULL.\n");
175
+		return -1;
176
+	}
177
+
178
+	/* reset special filter mask and filter methods*/
179
+	fwd_settings[id].sfilter = 0;
180
+	if (fwd_settings[id].filter_methods != NULL) {
181
+		shm_free(fwd_settings[id].filter_methods);
182
+		fwd_settings[id].filter_methods = NULL;
183
+	}
184
+
185
+	int i;
186
+	for (i=0; i<sfilter_cnt; i++) {
187
+		if (strstr(flist, sfilter_str[i]) != NULL) {
188
+			/* special filter name is found in flist -> add to special filter mask */
189
+			fwd_settings[id].sfilter |= sfilter_mask[i];
190
+		}
191
+	}
192
+
193
+	char buf[BUFSIZE+1], tmp[BUFSIZE+1];
194
+	buf[0] = '\0';
195
+	char *set_p = flist;
196
+	char *token = NULL;
197
+	while ((token = strsep(&set_p, ":"))) {  /* iterate through list of filters */
198
+		int found  = 0;
199
+		/* is it a special filter? */
200
+		for (i=0; i<sfilter_cnt; i++) {
201
+			if (strcmp(token, sfilter_str[i]) == 0) {
202
+				found = 1;
203
+				break;
204
+			}
205
+		}
206
+
207
+		if (found == 0) {
208
+		/* no special filter! */
209
+			if (buf[0]) {
210
+				strcpy(tmp, buf);
211
+				snprintf(buf, BUFSIZE, "%s:%s", tmp, token);
212
+				buf[BUFSIZE]='\0';
213
+			} else {
214
+				snprintf(buf, BUFSIZE, "%s", token);
215
+				buf[BUFSIZE]='\0';
216
+			}
217
+		}
218
+	}
219
+
220
+	int len = strlen(buf);
221
+	if (len > 0) {
222
+		char *flc = shm_malloc(len+1);
223
+		if (flc == NULL) {
224
+			SHM_MEM_ERROR;
225
+			return -1;
226
+		}
227
+		memcpy(flc, buf, len+1);
228
+		fwd_settings[id].filter_methods = flc;
229
+	}
230
+	return 0;
231
+}
232
+
233
+
234
+/*!
235
+ * Updates proxy configuration
236
+ * \param id update the configuration with this ID.
237
+ * \param host_str the destination host.
238
+ * \param port_str the port number as string.
239
+ * \return 0 on success, -1 otherwise
240
+ */
241
+static int update_proxy(int id, char *host_str, char *port_str)
242
+{
243
+	if (host_str == NULL) {
244
+		LM_ERR("host_str is NULL.\n");
245
+		return -1;
246
+	}
247
+	if (port_str == NULL) {
248
+		LM_ERR("port_str is NULL.\n");
249
+		return -1;
250
+	}
251
+
252
+	int port = conf_str2int(port_str);
253
+	if (port < 0) {
254
+		LM_ERR("invalid port '%s'.\n", port_str);
255
+		return -1;
256
+	}
257
+
258
+	/* make copy of host string since mk_proxy does not */
259
+	str host;
260
+	host.len = strlen(host_str);
261
+	host.s = shm_malloc(host.len+1);
262
+	if (host.s == NULL) {
263
+		SHM_MEM_ERROR;
264
+		return -1;
265
+	}
266
+	strcpy(host.s, host_str);
267
+
268
+	/* make proxy in shared memory */
269
+	struct proxy_l* proxy;
270
+	proxy = mk_shm_proxy(&host, port, PROTO_UDP);
271
+	if (proxy == NULL) {
272
+		LM_ERR("cannot make proxy (host='%s', port=%d).\n", host_str, port);
273
+		shm_free(host.s);
274
+		return -1;
275
+	}
276
+
277
+	if (fwd_settings[id].proxy) {
278
+		/* cleaning up old proxy */
279
+		if (fwd_settings[id].proxy->name.s) {
280
+			shm_free(fwd_settings[id].proxy->name.s);
281
+		}
282
+		free_shm_proxy(fwd_settings[id].proxy);
283
+		shm_free(fwd_settings[id].proxy);
284
+	}
285
+	fwd_settings[id].proxy = proxy;  /* new proxy is now acitvated */
286
+
287
+	return 0;
288
+}
289
+
290
+
291
+/*!
292
+ * \brief Parses configuration string for the switch
293
+ * Parses a configuration string for switch settings and updates
294
+ * the configuration structure.
295
+ * \param settings the configuration string in the following form:
296
+\verbatim
297
+ *              <id>=<switch>[,<id>=<switch>]...
298
+\endverbatim
299
+ * \return 1 on success, -1 otherwise
300
+ */
301
+int conf_parse_switch(char *settings)
302
+{
303
+	/* make a copy since we are modifying it */
304
+	int len = strlen(settings);
305
+	if (len==0) return 1;
306
+	char *strc = (char *)pkg_malloc(len+1);
307
+	if (strc == NULL) {
308
+		PKG_MEM_ERROR;
309
+		return -1;
310
+	}
311
+	memcpy(strc, settings, len+1);
312
+	remove_spaces(strc);
313
+
314
+	char *set_p = strc;
315
+	char *token = NULL;
316
+	while ((token = strsep(&set_p, ","))) {  /* iterate through list of settings */
317
+		char *id_str = strsep(&token, "=");
318
+		int id = conf_str2id(id_str);
319
+		if (id < 0) {
320
+			LM_ERR("cannot parse id '%s'.\n", id_str);
321
+			pkg_free(strc);
322
+			return -1;
323
+		}
324
+
325
+		/* got all data for one setting -> update configuration now */
326
+		if (update_switch(id, token) < 0) {
327
+			LM_ERR("cannot update switch.\n");
328
+			pkg_free(strc);
329
+			return -1;
330
+		}
331
+	}
332
+
333
+	pkg_free(strc);
334
+	return 1;
335
+}
336
+
337
+
338
+/*!
339
+ * \brief Output configuration in FIFO format
340
+ * \param rpl_tree FIFO root
341
+ * \return 0 on success, -1 on failure
342
+ */
343
+int conf_show(struct mi_root* rpl_tree)
344
+{
345
+	int id, sfilter;
346
+	struct mi_node * node = NULL;
347
+
348
+	node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "id switch %30s proxy\n", "filter");
349
+	if(node == NULL)
350
+		goto error;
351
+
352
+	for (id=0; id<=fwd_max_id; id++) {
353
+		char buf[BUFSIZE+1];
354
+		char tmp[BUFSIZE+1];
355
+		buf[0]='\0';
356
+		for (sfilter=0; sfilter<sfilter_cnt; sfilter++) {
357
+			if (fwd_settings[id].sfilter&sfilter_mask[sfilter]) {
358
+				if (buf[0]) {
359
+					strcpy(tmp, buf);
360
+					snprintf(buf, BUFSIZE, "%s:%s", tmp, sfilter_str[sfilter]);
361
+					buf[BUFSIZE]='\0';
362
+				} else {
363
+					snprintf(buf, BUFSIZE, "%s", sfilter_str[sfilter]);
364
+					buf[BUFSIZE]='\0';
365
+				}
366
+			}
367
+		}
368
+		if (fwd_settings[id].filter_methods) {
369
+			if (buf[0]) {
370
+				strcpy(tmp, buf);
371
+				snprintf(buf, BUFSIZE, "%s:%s", tmp, fwd_settings[id].filter_methods);
372
+				buf[BUFSIZE]='\0';
373
+			} else {
374
+				snprintf(buf, BUFSIZE, "%s", fwd_settings[id].filter_methods);
375
+				buf[BUFSIZE]='\0';
376
+			}
377
+		}
378
+		node = addf_mi_node_child( &rpl_tree->node, 0, 0, 0, "%2d %s %33s %s:%d\n", id,
379
+			fwd_settings[id].active ? "on " : "off", buf,
380
+			fwd_settings[id].proxy ? fwd_settings[id].proxy->name.s : "",
381
+			fwd_settings[id].proxy ? fwd_settings[id].proxy->port : 0);
382
+		if(node == NULL)
383
+			goto error;
384
+
385
+	}
386
+	return 0;
387
+
388
+error:
389
+	return -1;
390
+}
391
+
392
+
393
+/*!
394
+ * \brief Parses a configuration string for the filter
395
+ * Parses a configuration string for switch settings and
396
+ * updates the configuration structure.
397
+ * \param settings The configuration string in the following form:
398
+\verbatim
399
+ *              <id>=<filter>[:<filter>]...[,<id>=<filter>[:<filter>]...]...
400
+\endverbatim
401
+ * \return 1 on success, -1 otherwise
402
+ */
403
+int conf_parse_filter(char *settings)
404
+{
405
+	/* make a copy since we are modifying it */
406
+	int len = strlen(settings);
407
+	if (len==0) return 1;
408
+	char *strc = (char *)pkg_malloc(len+1);
409
+	if (strc == NULL) {
410
+		PKG_MEM_ERROR;
411
+		return -1;
412
+	}
413
+	memcpy(strc, settings, len+1);
414
+	remove_spaces(strc);
415
+
416
+	char *set_p = strc;
417
+	char *token = NULL;
418
+	while ((token = strsep(&set_p, ","))) {  /* iterate through list of settings */
419
+		char *id_str = strsep(&token, "=");
420
+		int id = conf_str2id(id_str);
421
+		if (id<0) {
422
+			LM_ERR("cannot parse id '%s'.\n", id_str);
423
+			pkg_free(strc);
424
+			return -1;
425
+		}
426
+		if (update_filter(id, token) < 0) {
427
+			LM_ERR("cannot extract filters.\n");
428
+			pkg_free(strc);
429
+			return -1;
430
+		}
431
+	}
432
+
433
+	pkg_free(strc);
434
+	return 1;
435
+}
436
+
437
+
438
+/*!
439
+ * \brief Parses a configuration string for proxy settings
440
+ * Parses a configuration string for proxy settings and
441
+ * updates the configuration structure.
442
+ * \param settings: The configuration string in the following form:
443
+\verbatim
444
+ *              <id>=<host>:<port>[,<id>=<host>:<port>]...
445
+\endverbatim
446
+ * \return: 1 on success, -1 otherwise
447
+ */
448
+int conf_parse_proxy(char *settings)
449
+{
450
+	/* make a copy since we are modifying it */
451
+	int len = strlen(settings);
452
+	if (len==0) return 1;
453
+	char *strc = (char *)pkg_malloc(len+1);
454
+	if (strc == NULL) {
455
+		PKG_MEM_ERROR;
456
+		return -1;
457
+	}
458
+	memcpy(strc, settings, len+1);
459
+	remove_spaces(strc);
460
+
461
+	char *set_p = strc;
462
+	char *token = NULL;
463
+	while ((token = strsep(&set_p, ","))) {  /* iterate through list of settings */
464
+		char *id_str = strsep(&token, "=");
465
+		int id = conf_str2id(id_str);
466
+		if (id<0) {
467
+			LM_ERR("cannot parse id '%s'.\n", id_str);
468
+			pkg_free(strc);
469
+			return -1;
470
+		}
471
+		char *host = strsep(&token, ":");
472
+
473
+		/* got all data for one setting -> update configuration now */
474
+		if (update_proxy(id, host, token) < 0) {
475
+			LM_ERR("cannot update proxy.\n");
476
+			pkg_free(strc);
477
+			return -1;
478
+		}
479
+	}
480
+
481
+	pkg_free(strc);
482
+	return 1;
483
+}
484
+
485
+
486
+/*!
487
+ * \brief Checks if method string is in filter_methods
488
+ * \param id use configuration with this ID when checking
489
+ * \param method method string to be searched for
490
+ * \param method_len length of method string
491
+ * \return 1 if method is found in filter_methods, 0 otherwise
492
+ */
493
+static int filter_methods_contains_request(int id, char *method, int method_len)
494
+{
495
+	char *p = fwd_settings[id].filter_methods;
496
+
497
+	while (p != NULL) {
498
+		if (strncmp(p, method, method_len) == 0) {
499
+			return 1;
500
+		}
501
+		p = strchr(p, ':');
502
+		if (p != NULL) p++;
503
+	}
504
+
505
+	return 0;
506
+}
507
+
508
+
509
+/*!
510
+ * \brief Checks forwarding is needed
511
+ * \param msg the SIP message to be forwarded
512
+ * \param id use configuration with this ID when checking
513
+ * \return pointer to proxy structure of destination if forwarding is needed, NULL otherwise
514
+ */
515
+struct proxy_l *conf_needs_forward(struct sip_msg *msg, int id)
516
+{
517
+	if ((msg == NULL) || (fwd_settings[id].active == 0)) {
518
+		return NULL;
519
+	}
520
+
521
+	if (msg->first_line.type == SIP_REPLY) {
522
+		if (fwd_settings[id].sfilter&sfilter_mask[sfidx_reply]) {
523
+			return fwd_settings[id].proxy;
524
+		}
525
+	}
526
+
527
+	if (msg->first_line.type == SIP_REQUEST) {
528
+		if (fwd_settings[id].sfilter&sfilter_mask[sfidx_request]) {
529
+			return fwd_settings[id].proxy;
530
+		}
531
+
532
+		if (filter_methods_contains_request(id, msg->first_line.u.request.method.s, msg->first_line.u.request.method.len) > 0) {
533
+			return fwd_settings[id].proxy;
534
+		}
535
+	}
536
+
537
+	return NULL;
538
+}
539
+
540
+
541
+/*!
542
+ * \brief Initialize configuration
543
+ * \param max_id number of configuration statements
544
+ * \return 0 on success, -1 on failure
545
+ */
546
+int conf_init(int max_id)
547
+{
548
+	/* allocate and initialize memory for configuration */
549
+	fwd_settings = shm_malloc(sizeof(struct fwd_setting)*(max_id+1));
550
+	if (fwd_settings == NULL) {
551
+		SHM_MEM_ERROR;
552
+		return -1;
553
+	}
554
+	memset(fwd_settings, 0, sizeof(struct fwd_setting)*(max_id+1));
555
+	fwd_max_id = max_id;
556
+	return 0;
557
+}
558
+
559
+
560
+/*!
561
+ * \brief Destroy configuration
562
+ */
563
+void conf_destroy(void)
564
+{
565
+	int id;
566
+
567
+	if (fwd_settings) {
568
+		for (id=0; id<=fwd_max_id; id++) {
569
+			fwd_settings[id].active = 0;
570
+			if (fwd_settings[id].proxy) {
571
+				if (fwd_settings[id].proxy->name.s) {
572
+					shm_free(fwd_settings[id].proxy->name.s);
573
+				}
574
+				free_shm_proxy(fwd_settings[id].proxy);
575
+				shm_free(fwd_settings[id].proxy);
576
+			}
577
+		}
578
+		shm_free(fwd_settings);
579
+	}
580
+}