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
deleted file mode 100644
... ...
@@ -1,1186 +0,0 @@
1
-/*
2
- * resolver related functions
3
- *
4
- * Copyright (C) 2006 iptelorg GmbH
5
- *
6
- * This file is part of Kamailio, a free SIP server.
7
- *
8
- * Kamailio is free software; you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License as published by
10
- * the Free Software Foundation; either version 2 of the License, or
11
- * (at your option) any later version
12
- *
13
- * Kamailio is distributed in the hope that it will be useful,
14
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
- * GNU General Public License for more details.
17
- *
18
- * You should have received a copy of the GNU General Public License
19
- * along with this program; if not, write to the Free Software
20
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21
- */
22
-
23
-/*!
24
- * \file
25
- * \brief Kamailio core :: resolver related functions
26
- * \ingroup core
27
- * Module: \ref core
28
- */
29
-
30
-
31
-#ifdef USE_DST_BLACKLIST
32
-
33
-#include "dst_blacklist.h"
34
-#include "globals.h"
35
-#include "cfg_core.h"
36
-#include "mem/shm_mem.h"
37
-#include "hashes.h"
38
-#include "locking.h"
39
-#include "timer.h"
40
-#include "timer_ticks.h"
41
-#include "ip_addr.h"
42
-#include "error.h"
43
-#include "rpc.h"
44
-#include "compiler_opt.h"
45
-#include "resolve.h" /* for str2ip */
46
-#ifdef USE_DST_BLACKLIST_STATS
47
-#include "pt.h"
48
-#endif
49
-
50
-
51
-
52
-
53
-struct dst_blst_entry{
54
-	struct dst_blst_entry* next;
55
-	ticks_t expire;
56
-	unsigned short port;
57
-	unsigned char proto;
58
-	unsigned char flags; /* contains the address type + error flags */
59
-	unsigned char ip[4]; /* 4 for ipv4, 16 for ipv6 */
60
-};
61
-
62
-#define DST_BLST_ENTRY_SIZE(b) \
63
-		(sizeof(struct dst_blst_entry)+((b).flags&BLST_IS_IPV6)*12)
64
-
65
-
66
-#define DST_BLST_HASH_SIZE		1024
67
-#define DEFAULT_BLST_TIMER_INTERVAL		60 /* 1 min */
68
-
69
-
70
-/* lock method */
71
-#ifdef GEN_LOCK_T_UNLIMITED
72
-#define BLST_LOCK_PER_BUCKET
73
-#elif defined GEN_LOCK_SET_T_UNLIMITED
74
-#define BLST_LOCK_SET
75
-#else
76
-#define BLST_ONE_LOCK
77
-#endif
78
-
79
-
80
-#ifdef BLST_LOCK_PER_BUCKET
81
-/* lock included in the hash bucket */
82
-#define LOCK_BLST(h)		lock_get(&dst_blst_hash[(h)].lock)
83
-#define UNLOCK_BLST(h)		lock_release(&dst_blst_hash[(h)].lock)
84
-#elif defined BLST_LOCK_SET
85
-static gen_lock_set_t* blst_lock_set=0;
86
-#define LOCK_BLST(h)		lock_set_get(blst_lock_set, (h))
87
-#define UNLOCK_BLST(h)		lock_set_release(blst_lock_set, (h))
88
-#else
89
-/* use only one lock */
90
-static gen_lock_t* blst_lock=0;
91
-#define LOCK_BLST(h)		lock_get(blst_lock)
92
-#define UNLOCK_BLST(h)		lock_release(blst_lock)
93
-#endif
94
-
95
-
96
-
97
-
98
-#define BLST_HASH_STATS
99
-
100
-#ifdef BLST_HASH_STATS
101
-#define BLST_HASH_STATS_DEC(h) dst_blst_hash[(h)].entries--
102
-#define BLST_HASH_STATS_INC(h) dst_blst_hash[(h)].entries++
103
-#else
104
-#define BLST_HASH_STATS_DEC(h) do{}while(0)
105
-#define BLST_HASH_STATS_INC(h) do{}while(0)
106
-#endif
107
-
108
-struct dst_blst_lst_head{
109
-	struct dst_blst_entry* first;
110
-#ifdef BLST_LOCK_PER_BUCKET
111
-	gen_lock_t	lock;
112
-#endif
113
-#ifdef BLST_HASH_STATS
114
-	unsigned int entries;
115
-#endif
116
-};
117
-
118
-int dst_blacklist_init=1; /* if 0, the dst blacklist is not initialized at startup */
119
-static struct timer_ln* blst_timer_h=0;
120
-
121
-static volatile unsigned int* blst_mem_used=0;
122
-unsigned int blst_timer_interval=DEFAULT_BLST_TIMER_INTERVAL;
123
-struct dst_blst_lst_head* dst_blst_hash=0;
124
-
125
-#ifdef USE_DST_BLACKLIST_STATS
126
-struct t_dst_blacklist_stats* dst_blacklist_stats=0;
127
-#endif
128
-
129
-/* blacklist per protocol event ignore mask array */
130
-unsigned blst_proto_imask[PROTO_LAST+1];
131
-
132
-#ifdef DST_BLACKLIST_HOOKS
133
-
134
-/* there 2 types of callbacks supported: on add new entry to the blacklist
135
- *  (DST_BLACKLIST_ADD_CB) and on blacklist search (DST_BLACKLIST_SEARCH_CB).
136
- *  Both of them take a struct dest_info*, a flags pointer(unsigned char*),
137
- *  and a struct sip_msg* as parameters. The flags can be changed.
138
- *  A callback should return one of:
139
- *    DST_BLACKLIST_CONTINUE - do nothing, let other callbacks run
140
- *    DST_BLACKLIST_ACCEPT   - for blacklist add: force accept immediately,
141
- *                             for blacklist search: force match and use
142
- *                              the flags as the blacklist search return.
143
- *                              ( so the flags should be set to some valid
144
- *                                non zero BLST flags value )
145
- *   DST_BLACKLIST_DENY      - for blacklist add: don't allow adding the
146
- *                              destination to the blacklist.
147
- *                             for blacklist search: force return not found
148
- */
149
-
150
-#define MAX_BLST_HOOKS 1
151
-
152
-struct blst_callbacks_lst{
153
-	struct blacklist_hook* hooks;
154
-	unsigned int max_hooks;
155
-	int last_idx;
156
-};
157
-
158
-static struct blst_callbacks_lst blst_add_cb;
159
-static struct blst_callbacks_lst blst_search_cb;
160
-
161
-static int init_blst_callback_lst(struct blst_callbacks_lst*  cb_lst, int max)
162
-{
163
-
164
-	cb_lst->max_hooks=MAX_BLST_HOOKS;
165
-	cb_lst->last_idx=0;
166
-	cb_lst->hooks=pkg_malloc(cb_lst->max_hooks*sizeof(struct blacklist_hook));
167
-	if (cb_lst->hooks==0)
168
-		goto error;
169
-	memset(cb_lst->hooks, 0, cb_lst->max_hooks*sizeof(struct blacklist_hook));
170
-	return 0;
171
-error:
172
-	return -1;
173
-}
174
-
175
-
176
-static void destroy_blst_callback_lst(struct blst_callbacks_lst* cb_lst)
177
-{
178
-	int r;
179
-	if (cb_lst && cb_lst->hooks){
180
-		for (r=0; r<cb_lst->last_idx; r++){
181
-			if (cb_lst->hooks[r].destroy)
182
-				cb_lst->hooks[r].destroy();
183
-		}
184
-		pkg_free(cb_lst->hooks);
185
-		cb_lst->hooks=0;
186
-		cb_lst->last_idx=0;
187
-		cb_lst->max_hooks=0;
188
-	}
189
-}
190
-
191
-
192
-static void destroy_blacklist_hooks()
193
-{
194
-	destroy_blst_callback_lst(&blst_add_cb);
195
-	destroy_blst_callback_lst(&blst_search_cb);
196
-}
197
-
198
-
199
-static int init_blacklist_hooks()
200
-{
201
-
202
-	if (init_blst_callback_lst(&blst_add_cb, MAX_BLST_HOOKS)!=0)
203
-		goto error;
204
-	if (init_blst_callback_lst(&blst_search_cb, MAX_BLST_HOOKS)!=0)
205
-		goto error;
206
-	return 0;
207
-error:
208
-	LM_ERR("failure initializing internal lists\n");
209
-	destroy_blacklist_hooks();
210
-	return -1;
211
-}
212
-
213
-
214
-
215
-
216
-/* allocates a new hook
217
- * returns 0 on success and -1 on error
218
- * must be called from mod init (from the main process, before forking)*/
219
-int register_blacklist_hook(struct blacklist_hook *h, int type)
220
-{
221
-	struct blst_callbacks_lst* cb_lst;
222
-	struct blacklist_hook* tmp;
223
-	int new_max_hooks;
224
-
225
-	if (dst_blacklist_init==0) {
226
-		LM_ERR("blacklist is turned off, "
227
-			"the hook cannot be registered\n");
228
-		goto error;
229
-	}
230
-
231
-	switch(type){
232
-		case DST_BLACKLIST_ADD_CB:
233
-			cb_lst=&blst_add_cb;
234
-			break;
235
-		case DST_BLACKLIST_SEARCH_CB:
236
-			cb_lst=&blst_search_cb;
237
-			break;
238
-		default:
239
-			BUG("register_blacklist_hook: invalid type %d\n", type);
240
-			goto error;
241
-	}
242
-	if (cb_lst==0 || cb_lst->hooks==0 || cb_lst->max_hooks==0){
243
-		BUG("register_blacklist_hook: intialization error\n");
244
-		goto error;
245
-	}
246
-
247
-	if (cb_lst->last_idx >= cb_lst->max_hooks){
248
-		new_max_hooks=2*cb_lst->max_hooks;
249
-		tmp=pkg_realloc(cb_lst->hooks,
250
-				new_max_hooks*sizeof(struct blacklist_hook));
251
-		if (tmp==0){
252
-			goto error;
253
-		}
254
-		cb_lst->hooks=tmp;
255
-		/* init the new chunk (but not the current entry which is
256
-		 * overwritten anyway) */
257
-		memset(&cb_lst->hooks[cb_lst->max_hooks+1], 0,
258
-					(new_max_hooks-cb_lst->max_hooks-1)*
259
-						sizeof(struct blacklist_hook));
260
-		cb_lst->max_hooks=new_max_hooks;
261
-	}
262
-	cb_lst->hooks[cb_lst->last_idx]=*h;
263
-	cb_lst->last_idx++;
264
-	return 0;
265
-error:
266
-	return -1;
267
-}
268
-
269
-
270
-inline static int blacklist_run_hooks(struct blst_callbacks_lst *cb_lst,
271
-							struct dest_info* si, unsigned char* flags,
272
-							struct sip_msg* msg)
273
-{
274
-	int r;
275
-	int ret;
276
-
277
-	ret=DST_BLACKLIST_CONTINUE; /* default, if no hook installed accept
278
-								blacklist operation */
279
-	if (likely(cb_lst->last_idx==0))
280
-		return ret;
281
-	for (r=0; r<cb_lst->last_idx; r++){
282
-		ret=cb_lst->hooks[r].on_blst_action(si, flags, msg);
283
-		if (ret!=DST_BLACKLIST_CONTINUE) break;
284
-	}
285
-	return ret;
286
-}
287
-
288
-
289
-#endif /* DST_BLACKLIST_HOOKS */
290
-
291
-
292
-/** init per protocol blacklist event ignore masks.
293
- * @return 0 on success, < 0 on error.
294
- */
295
-int blst_init_ign_masks(void)
296
-{
297
-	if ((PROTO_UDP > PROTO_LAST) || (PROTO_TCP > PROTO_LAST) ||
298
-		(PROTO_TLS > PROTO_LAST) || (PROTO_SCTP > PROTO_LAST)){
299
-		BUG("protocol array too small\n");
300
-		return -1;
301
-	}
302
-	blst_proto_imask[PROTO_UDP]=cfg_get(core, core_cfg, blst_udp_imask);
303
-	blst_proto_imask[PROTO_TCP]=cfg_get(core, core_cfg, blst_tcp_imask);
304
-	blst_proto_imask[PROTO_TLS]=cfg_get(core, core_cfg, blst_tls_imask);
305
-	blst_proto_imask[PROTO_SCTP]=cfg_get(core, core_cfg, blst_sctp_imask);
306
-	blst_proto_imask[PROTO_NONE]=blst_proto_imask[PROTO_UDP];
307
-	return 0;
308
-}
309
-
310
-
311
-
312
-inline static void blst_destroy_entry(struct dst_blst_entry* e)
313
-{
314
-	shm_free(e);
315
-}
316
-
317
-
318
-static ticks_t blst_timer(ticks_t ticks, struct timer_ln* tl, void* data);
319
-
320
-
321
-inline static void dst_blst_entry2ip(struct ip_addr* ip,
322
-										struct dst_blst_entry* e)
323
-{
324
-	if (e->flags & BLST_IS_IPV6){
325
-		ip->af=AF_INET6;
326
-		ip->len=16;
327
-	}else
328
-	{
329
-		ip->af=AF_INET;
330
-		ip->len=4;
331
-	}
332
-	memcpy(ip->u.addr, e->ip, ip->len);
333
-}
334
-
335
-
336
-
337
-inline static unsigned short dst_blst_hash_no(unsigned char proto,
338
-											  struct ip_addr* ip,
339
-											  unsigned short port)
340
-{
341
-	str s1;
342
-	str s2;
343
-
344
-	s1.s=(char*)ip->u.addr;
345
-	s1.len=ip->len;
346
-	s2.s=(char*)&port;
347
-	s2.len=sizeof(unsigned short);
348
-	return get_hash2_raw(&s1, &s2)%DST_BLST_HASH_SIZE;
349
-}
350
-
351
-
352
-
353
-void destroy_dst_blacklist()
354
-{
355
-	int r;
356
-	struct dst_blst_entry** crt;
357
-	struct dst_blst_entry* e;
358
-
359
-	if (blst_timer_h){
360
-		timer_del(blst_timer_h);
361
-		timer_free(blst_timer_h);
362
-		blst_timer_h=0;
363
-	}
364
-#ifdef BLST_LOCK_PER_BUCKET
365
-	if (dst_blst_hash)
366
-		for(r=0; r<DST_BLST_HASH_SIZE; r++)
367
-			lock_destroy(&dst_blst_hash[r].lock);
368
-#elif defined BLST_LOCK_SET
369
-		if (blst_lock_set){
370
-			lock_set_destroy(blst_lock_set);
371
-			lock_set_dealloc(blst_lock_set);
372
-			blst_lock_set=0;
373
-		}
374
-#else
375
-	if (blst_lock){
376
-		lock_destroy(blst_lock);
377
-		lock_dealloc(blst_lock);
378
-		blst_lock=0;
379
-	}
380
-#endif
381
-
382
-	if (dst_blst_hash){
383
-		for(r=0; r<DST_BLST_HASH_SIZE; r++){
384
-			crt=&dst_blst_hash[r].first;
385
-			while(*crt){
386
-				e=*crt;
387
-				*crt=(*crt)->next;
388
-				blst_destroy_entry(e);
389
-			}
390
-		}
391
-		shm_free(dst_blst_hash);
392
-		dst_blst_hash=0;
393
-	}
394
-	if (blst_mem_used){
395
-		shm_free((void*)blst_mem_used);
396
-		blst_mem_used=0;
397
-	}
398
-#ifdef DST_BLACKLIST_HOOKS
399
-	destroy_blacklist_hooks();
400
-#endif
401
-
402
-#ifdef USE_DST_BLACKLIST_STATS
403
-	if (dst_blacklist_stats)
404
-		shm_free(dst_blacklist_stats);
405
-#endif
406
-}
407
-
408
-
409
-
410
-int init_dst_blacklist()
411
-{
412
-	int ret;
413
-#ifdef BLST_LOCK_PER_BUCKET
414
-	int r;
415
-#endif
416
-
417
-	if (dst_blacklist_init==0) {
418
-		/* the dst blacklist is turned off */
419
-		default_core_cfg.use_dst_blacklist=0;
420
-		return 0;
421
-	}
422
-
423
-	ret=-1;
424
-#ifdef DST_BLACKLIST_HOOKS
425
-	if (init_blacklist_hooks()!=0){
426
-		ret=E_OUT_OF_MEM;
427
-		goto error;
428
-	}
429
-#endif
430
-	blst_mem_used=shm_malloc(sizeof(*blst_mem_used));
431
-	if (blst_mem_used==0){
432
-		ret=E_OUT_OF_MEM;
433
-		goto error;
434
-	}
435
-	*blst_mem_used=0;
436
-	dst_blst_hash=shm_malloc(sizeof(struct dst_blst_lst_head) *
437
-											DST_BLST_HASH_SIZE);
438
-	if (dst_blst_hash==0){
439
-		ret=E_OUT_OF_MEM;
440
-		goto error;
441
-	}
442
-	memset(dst_blst_hash, 0, sizeof(struct dst_blst_lst_head) *
443
-								DST_BLST_HASH_SIZE);
444
-#ifdef BLST_LOCK_PER_BUCKET
445
-	for (r=0; r<DST_BLST_HASH_SIZE; r++){
446
-		if (lock_init(&dst_blst_hash[r].lock)==0){
447
-			ret=-1;
448
-			goto error;
449
-		}
450
-	}
451
-#elif defined BLST_LOCK_SET
452
-	blst_lock_set=lock_set_alloc(DST_BLST_HASH_SIZE);
453
-	if (blst_lock_set==0){
454
-		ret=E_OUT_OF_MEM;
455
-		goto error;
456
-	}
457
-	if (lock_set_init(blst_lock_set)==0){
458
-		lock_set_dealloc(blst_lock_set);
459
-		blst_lock_set=0;
460
-		ret=-1;
461
-		goto error;
462
-	}
463
-#else /* BLST_ONE_LOCK */
464
-	blst_lock=lock_alloc();
465
-	if (blst_lock==0){
466
-		ret=E_OUT_OF_MEM;
467
-		goto error;
468
-	}
469
-	if (lock_init(blst_lock)==0){
470
-		lock_dealloc(blst_lock);
471
-		blst_lock=0;
472
-		ret=-1;
473
-		goto error;
474
-	}
475
-#endif /* BLST*LOCK*/
476
-	blst_timer_h=timer_alloc();
477
-	if (blst_timer_h==0){
478
-		ret=E_OUT_OF_MEM;
479
-		goto error;
480
-	}
481
-	/* fix options */
482
-	default_core_cfg.blst_max_mem<<=10; /* in Kb */ /* TODO: test with 0 */
483
-	if (blst_timer_interval){
484
-		timer_init(blst_timer_h, blst_timer, 0 ,0); /* slow timer */
485
-		if (timer_add(blst_timer_h, S_TO_TICKS(blst_timer_interval))<0){
486
-			LM_CRIT("failed to add the timer\n");
487
-			timer_free(blst_timer_h);
488
-			blst_timer_h=0;
489
-			goto error;
490
-		}
491
-	}
492
-	if (blst_init_ign_masks() < 0){
493
-		ret=E_BUG;
494
-		goto error;
495
-	}
496
-	return 0;
497
-error:
498
-	destroy_dst_blacklist();
499
-	return ret;
500
-}
501
-
502
-#ifdef USE_DST_BLACKLIST_STATS
503
-int init_dst_blacklist_stats(int iproc_num)
504
-{
505
-	/* do not initialize the stats array if the dst blacklist will not be used */
506
-	if (dst_blacklist_init==0) return 0;
507
-
508
-	/* if it is already initialized */
509
-	if (dst_blacklist_stats)
510
-		shm_free(dst_blacklist_stats);
511
-
512
-	dst_blacklist_stats=shm_malloc(sizeof(*dst_blacklist_stats) * iproc_num);
513
-	if (dst_blacklist_stats==0){
514
-		return E_OUT_OF_MEM;
515
-	}
516
-	memset(dst_blacklist_stats, 0, sizeof(*dst_blacklist_stats) * iproc_num);
517
-
518
-	return 0;
519
-}
520
-#endif
521
-
522
-/* must be called with the lock held
523
- * struct dst_blst_entry** head, struct dst_blst_entry* e */
524
-#define dst_blacklist_lst_add(head, e)\
525
-do{ \
526
-	(e)->next=*(head); \
527
-	*(head)=(e); \
528
-}while(0)
529
-
530
-
531
-
532
-/* must be called with the lock held
533
- * returns a pointer to the blacklist entry if found, 0 otherwise
534
- * it also deletes expired elements (expire<=now) as it searches
535
- * proto==PROTO_NONE = wildcard */
536
-inline static struct dst_blst_entry* _dst_blacklist_lst_find(
537
-												unsigned short hash,
538
-												struct ip_addr* ip,
539
-												unsigned char proto,
540
-												unsigned short port,
541
-												ticks_t now)
542
-{
543
-	struct dst_blst_entry** crt;
544
-	struct dst_blst_entry** tmp;
545
-	struct dst_blst_entry* e;
546
-	struct dst_blst_entry** head;
547
-	unsigned char type;
548
-
549
-	head=&dst_blst_hash[hash].first;
550
-	type=(ip->af==AF_INET6)*BLST_IS_IPV6;
551
-	for (crt=head, tmp=&(*head)->next; *crt; crt=tmp, tmp=&(*crt)->next){
552
-		e=*crt;
553
-		prefetch_loc_r((*crt)->next, 1);
554
-		/* remove old expired entries */
555
-		if ((s_ticks_t)(now-(*crt)->expire)>=0){
556
-			*crt=(*crt)->next;
557
-			tmp=crt;
558
-			*blst_mem_used-=DST_BLST_ENTRY_SIZE(*e);
559
-			BLST_HASH_STATS_DEC(hash);
560
-			blst_destroy_entry(e);
561
-		}else if ((e->port==port) && ((e->flags & BLST_IS_IPV6)==type) &&
562
-				((e->proto==PROTO_NONE) || (proto==PROTO_NONE) ||
563
-					(e->proto==proto)) &&
564
-					(memcmp(ip->u.addr, e->ip, ip->len)==0)){
565
-			return e;
566
-		}
567
-	}
568
-	return 0;
569
-}
570
-
571
-
572
-
573
-/* must be called with the lock held
574
- * returns 1 if a matching entry was deleted, 0 otherwise
575
- * it also deletes expired elements (expire<=now) as it searches
576
- * proto==PROTO_NONE = wildcard */
577
-inline static int _dst_blacklist_del(
578
-												unsigned short hash,
579
-												struct ip_addr* ip,
580
-												unsigned char proto,
581
-												unsigned short port,
582
-												ticks_t now)
583
-{
584
-	struct dst_blst_entry** crt;
585
-	struct dst_blst_entry** tmp;
586
-	struct dst_blst_entry* e;
587
-	struct dst_blst_entry** head;
588
-	unsigned char type;
589
-	
590
-	head=&dst_blst_hash[hash].first;
591
-	type=(ip->af==AF_INET6)*BLST_IS_IPV6;
592
-	for (crt=head, tmp=&(*head)->next; *crt; crt=tmp, tmp=&(*crt)->next){
593
-		e=*crt;
594
-		prefetch_loc_r((*crt)->next, 1);
595
-		/* remove old expired entries */
596
-		if ((s_ticks_t)(now-(*crt)->expire)>=0){
597
-			*crt=(*crt)->next;
598
-			tmp=crt;
599
-			*blst_mem_used-=DST_BLST_ENTRY_SIZE(*e);
600
-			BLST_HASH_STATS_DEC(hash);
601
-			blst_destroy_entry(e);
602
-		}else if ((e->port==port) && ((e->flags & BLST_IS_IPV6)==type) &&
603
-				((e->proto==PROTO_NONE) || (proto==PROTO_NONE) ||
604
-					(e->proto==proto)) && 
605
-					(memcmp(ip->u.addr, e->ip, ip->len)==0)){
606
-			*crt=(*crt)->next;
607
-			tmp=crt;
608
-			*blst_mem_used-=DST_BLST_ENTRY_SIZE(*e);
609
-			BLST_HASH_STATS_DEC(hash);
610
-			blst_destroy_entry(e);
611
-			return 1;
612
-		}
613
-	}
614
-	return 0;
615
-}
616
-
617
-
618
-
619
-/* frees all the expired entries until either there are no more of them
620
- *  or the total memory used is <= target (to free all of them use -1 for
621
- *  targer)
622
- *  params:   target  - free expired entries until no more then taget memory
623
- *                      is used  (use 0 to free all of them)
624
- *            delta   - consider an entry expired if it expires after delta
625
- *                      ticks from now
626
- *            timeout - exit after timeout ticks
627
- *
628
- *  returns: number of deleted entries
629
- *  This function should be called periodically from a timer
630
- */
631
-inline static int dst_blacklist_clean_expired(unsigned int target,
632
-									  ticks_t delta,
633
-									  ticks_t timeout)
634
-{
635
-	static unsigned int start=0;
636
-	unsigned int h;
637
-	struct dst_blst_entry** crt;
638
-	struct dst_blst_entry** tmp;
639
-	struct dst_blst_entry* e;
640
-	ticks_t start_time;
641
-	ticks_t now;
642
-	int no=0;
643
-	int i;
644
-
645
-	now=start_time=get_ticks_raw();
646
-	for(h=start; h!=(start+DST_BLST_HASH_SIZE); h++){
647
-		i=h%DST_BLST_HASH_SIZE;
648
-		if (dst_blst_hash[i].first){
649
-			LOCK_BLST(i);
650
-			for (crt=&dst_blst_hash[i].first, tmp=&(*crt)->next;
651
-					*crt; crt=tmp, tmp=&(*crt)->next){
652
-				e=*crt;
653
-				prefetch_loc_r((*crt)->next, 1);
654
-				if ((s_ticks_t)(now+delta-(*crt)->expire)>=0){
655
-					*crt=(*crt)->next;
656
-					tmp=crt;
657
-					*blst_mem_used-=DST_BLST_ENTRY_SIZE(*e);
658
-					blst_destroy_entry(e);
659
-					BLST_HASH_STATS_DEC(i);
660
-					no++;
661
-					if (*blst_mem_used<=target){
662
-						UNLOCK_BLST(i);
663
-						goto skip;
664
-					}
665
-				}
666
-			}
667
-			UNLOCK_BLST(i);
668
-			/* check for timeout only "between" hash cells */
669
-			now=get_ticks_raw();
670
-			if ((now-start_time)>=timeout){
671
-				LM_DBG("timeout: %d > %d\n",
672
-						TICKS_TO_MS(now-start_time), TICKS_TO_MS(timeout));
673
-				goto skip;
674
-			}
675
-		}
676
-	}
677
-skip:
678
-	start=h; /* next time we start where we left */
679
-	if (no){
680
-		LM_DBG("%d entries removed\n", no);
681
-	}
682
-	return no;
683
-}
684
-
685
-
686
-
687
-/* timer */
688
-static ticks_t blst_timer(ticks_t ticks, struct timer_ln* tl, void* data)
689
-{
690
-	dst_blacklist_clean_expired(0, 0, 2); /*spend max. 2 ticks*/
691
-	return (ticks_t)(-1);
692
-}
693
-
694
-
695
-
696
-/* adds a proto ip:port combination to the blacklist
697
- * returns 0 on success, -1 on error (blacklist full -- would use more then
698
- *  blst:_max_mem, or out of shm. mem.)
699
- */
700
-inline static int dst_blacklist_add_ip(unsigned char err_flags,
701
-									unsigned char proto,
702
-									struct ip_addr* ip, unsigned short port,
703
-									ticks_t timeout)
704
-{
705
-	int size;
706
-	struct dst_blst_entry* e;
707
-	unsigned short hash;
708
-	ticks_t now;
709
-	int ret;
710
-
711
-	ret=0;
712
-	if (ip->af==AF_INET){
713
-		err_flags&=~BLST_IS_IPV6; /* make sure the ipv6 flag is reset */
714
-		size=sizeof(struct dst_blst_entry);
715
-	}else{
716
-		err_flags|=BLST_IS_IPV6;
717
-		size=sizeof(struct dst_blst_entry)+12 /* ipv6 addr - 4 */;
718
-	}
719
-	now=get_ticks_raw();
720
-	hash=dst_blst_hash_no(proto, ip, port);
721
-	/* check if the entry already exists */
722
-	LOCK_BLST(hash);
723
-		e=_dst_blacklist_lst_find(hash, ip, proto, port, now);
724
-		if (e){
725
-			e->flags|=err_flags;
726
-			e->expire=now+timeout; /* update the timeout */
727
-		}else{
728
-			if (unlikely((*blst_mem_used+size) >=
729
-					cfg_get(core, core_cfg, blst_max_mem))){
730
-#ifdef USE_DST_BLACKLIST_STATS
731
-				dst_blacklist_stats[process_no].bkl_lru_cnt++;
732
-#endif
733
-				UNLOCK_BLST(hash);
734
-				/* first try to free some memory  (~ 12%), but don't
735
-				 * spend more then 250 ms*/
736
-				dst_blacklist_clean_expired(*blst_mem_used/16*14, 0,
737
-															MS_TO_TICKS(250));
738
-				if (unlikely(*blst_mem_used+size >=
739
-						cfg_get(core, core_cfg, blst_max_mem))){
740
-					ret=-1;
741
-					goto error;
742
-				}
743
-				LOCK_BLST(hash);
744
-			}
745
-			e=shm_malloc(size);
746
-			if (e==0){
747
-				UNLOCK_BLST(hash);
748
-				ret=E_OUT_OF_MEM;
749
-				goto error;
750
-			}
751
-			*blst_mem_used+=size;
752
-			e->flags=err_flags;
753
-			e->proto=proto;
754
-			e->port=port;
755
-			memcpy(e->ip, ip->u.addr, ip->len);
756
-			e->expire=now+timeout; /* update the timeout */
757
-			e->next=0;
758
-			dst_blacklist_lst_add(&dst_blst_hash[hash].first, e);
759
-			BLST_HASH_STATS_INC(hash);
760
-		}
761
-	UNLOCK_BLST(hash);
762
-error:
763
-	return ret;
764
-}
765
-
766
-
767
-
768
-/* if no blacklisted returns 0, else returns the blacklist flags */
769
-inline static int dst_is_blacklisted_ip(unsigned char proto,
770
-										struct ip_addr* ip,
771
-										unsigned short port)
772
-{
773
-	struct dst_blst_entry* e;
774
-	unsigned short hash;
775
-	ticks_t now;
776
-	int ret;
777
-
778
-	ret=0;
779
-	now=get_ticks_raw();
780
-	hash=dst_blst_hash_no(proto, ip, port);
781
-	if (unlikely(dst_blst_hash[hash].first)){
782
-		LOCK_BLST(hash);
783
-			e=_dst_blacklist_lst_find(hash, ip, proto, port, now);
784
-			if (e){
785
-				ret=e->flags;
786
-			}
787
-		UNLOCK_BLST(hash);
788
-	}
789
-	return ret;
790
-}
791
-
792
-
793
-
794
-/** add dst to the blacklist, specifying the timeout.
795
- * @param err_flags - reason (bitmap)
796
- * @param si - destination (protocol, ip and port)
797
- * @param msg - sip message that triggered the blacklisting (can be 0 if 
798
- *               not known)
799
- * @param timeout - timeout in ticks
800
- * @return 0 on success, -1 on error
801
- */
802
-int dst_blacklist_force_add_to(unsigned char err_flags,  struct dest_info* si,
803
-								struct sip_msg* msg, ticks_t timeout)
804
-{
805
-	struct ip_addr ip;
806
-
807
-#ifdef DST_BLACKLIST_HOOKS
808
-	if (unlikely (blacklist_run_hooks(&blst_add_cb, si, &err_flags, msg) ==
809
-					DST_BLACKLIST_DENY))
810
-		return 0;
811
-#endif
812
-	su2ip_addr(&ip, &si->to);
813
-	return dst_blacklist_add_ip(err_flags, si->proto, &ip,
814
-								su_getport(&si->to), timeout);
815
-}
816
-
817
-
818
-
819
-/** add dst to the blacklist, specifying the timeout.
820
- * (like @function dst_blacklist_force_add_to)= above, but uses 
821
- * (proto, sockaddr_union) instead of struct dest_info)
822
- */
823
-int dst_blacklist_force_su_to(unsigned char err_flags, unsigned char proto,
824
-								union sockaddr_union* dst,
825
-								struct sip_msg* msg, ticks_t timeout)
826
-{
827
-	struct ip_addr ip;
828
-#ifdef DST_BLACKLIST_HOOKS
829
-	struct dest_info si;
830
-	
831
-	init_dest_info(&si);
832
-	si.to=*dst;
833
-	si.proto=proto;
834
-	if (unlikely (blacklist_run_hooks(&blst_add_cb, &si, &err_flags, msg) ==
835
-					DST_BLACKLIST_DENY))
836
-		return 0;
837
-#endif
838
-	su2ip_addr(&ip, dst);
839
-	return dst_blacklist_add_ip(err_flags, proto, &ip,
840
-								su_getport(dst), timeout);
841
-}
842
-
843
-
844
-
845
-int dst_is_blacklisted(struct dest_info* si, struct sip_msg* msg)
846
-{
847
-	int ires;
848
-	struct ip_addr ip;
849
-#ifdef DST_BLACKLIST_HOOKS
850
-	unsigned char err_flags;
851
-	int action;
852
-#endif
853
-	su2ip_addr(&ip, &si->to);
854
-
855
-#ifdef DST_BLACKLIST_HOOKS
856
-	err_flags=0;
857
-	if (unlikely((action=(blacklist_run_hooks(&blst_search_cb, si, &err_flags, msg))
858
-					) != DST_BLACKLIST_CONTINUE)){
859
-		if (action==DST_BLACKLIST_DENY)
860
-			return 0;
861
-		else  /* if (action==DST_BLACKLIST_ACCEPT) */
862
-			return err_flags;
863
-	}
864
-#endif
865
-	ires=dst_is_blacklisted_ip(si->proto, &ip, su_getport(&si->to));
866
-#ifdef USE_DST_BLACKLIST_STATS
867
-	if (ires)
868
-		dst_blacklist_stats[process_no].bkl_hit_cnt++;
869
-#endif
870
-	return ires;
871
-}
872
-
873
-
874
-
875
-/* returns 1 if the entry was deleted, 0 if not found */
876
-int dst_blacklist_del(struct dest_info* si, struct sip_msg* msg)
877
-{
878
-	unsigned short hash;
879
-	struct ip_addr ip;
880
-	ticks_t now;
881
-	int ret;
882
-	unsigned short port;
883
-	
884
-	ret=0;
885
-	su2ip_addr(&ip, &si->to);
886
-	port=su_getport(&si->to);
887
-	now=get_ticks_raw();
888
-	hash=dst_blst_hash_no(si->proto, &ip, port);
889
-	if (unlikely(dst_blst_hash[hash].first)){
890
-		LOCK_BLST(hash);
891
-			ret=_dst_blacklist_del(hash, &ip, si->proto, port, now);
892
-		UNLOCK_BLST(hash);
893
-	}
894
-	return ret;
895
-}
896
-
897
-
898
-
899
-/* rpc functions */
900
-void dst_blst_mem_info(rpc_t* rpc, void* ctx)
901
-{
902
-	if (!cfg_get(core, core_cfg, use_dst_blacklist)){
903
-		rpc->fault(ctx, 500, "dst blacklist support disabled");
904
-		return;
905
-	}
906
-	rpc->add(ctx, "dd",  *blst_mem_used, cfg_get(core, core_cfg, blst_max_mem));