blst: comment updated to reflect blocklist api
[sip-router] / src / modules / sipcapture / hash_mode.c
1 /*
2  * sipcapture module - helper module to capture sip messages
3  *
4  * Copyright (C) 2011-2015 Alexandr Dubovikov (alexandr.dubovikov@gmail.com)
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 #include "../../core/sr_module.h"
25 #include "../../core/crc.h"
26
27 #include <ctype.h>
28
29 #include "sipcapture.h"
30 #include "hash_mode.h"
31
32 static int get_source(struct _sipcapture_object *sco, enum hash_source source,
33                 str *source_string);
34 static int get_call_id(struct _sipcapture_object *sco, str *source_string);
35 static int get_from_user(struct _sipcapture_object *sco, str *source_string);
36 static int get_to_user(struct _sipcapture_object *sco, str *source_string);
37
38
39 static int first_token(str *source_string);
40
41
42 int hash_func(struct _sipcapture_object *sco, enum hash_source source,
43                 int denominator)
44 {
45         int ret;
46         unsigned int hash;
47         str source_string;
48
49         if(get_source(sco, source, &source_string) == -1) {
50                 return -1;
51         }
52
53         LM_DBG("source string: [%.*s]\n", source_string.len, source_string.s);
54         crc32_uint(&source_string, &hash);
55
56         ret = hash % denominator;
57         return ret;
58 }
59
60 static int get_source(struct _sipcapture_object *sco, enum hash_source source,
61                 str *source_string)
62 {
63         source_string->s = NULL;
64         source_string->len = 0;
65
66         switch(source) {
67                 case hs_call_id:
68                         return get_call_id(sco, source_string);
69                 case hs_from_user:
70                         return get_from_user(sco, source_string);
71                 case hs_to_user:
72                         return get_to_user(sco, source_string);
73                 default:
74                         LM_ERR("unknown hash source %i.\n", (int)source);
75                         return -1;
76         }
77 }
78
79 static int get_call_id(struct _sipcapture_object *sco, str *source_string)
80 {
81
82         if(!sco->callid.s || !sco->callid.len) {
83                 return -1;
84         }
85         source_string->s = sco->callid.s;
86         source_string->len = sco->callid.len;
87         first_token(source_string);
88         return 0;
89 }
90
91 static int get_from_user(struct _sipcapture_object *sco, str *source_string)
92 {
93
94         if(!sco->from_user.s || !sco->from_user.len) {
95                 return -1;
96         }
97         source_string->s = sco->from_user.s;
98         source_string->len = sco->from_user.len;
99         return 0;
100 }
101
102
103 static int get_to_user(struct _sipcapture_object *sco, str *source_string)
104 {
105
106         if(!sco->to_user.s || !sco->to_user.len) {
107                 return -1;
108         }
109         source_string->s = sco->to_user.s;
110         source_string->len = sco->to_user.len;
111         return 0;
112 }
113
114
115 static int first_token(str *source_string)
116 {
117         size_t len;
118
119         if(source_string->s == NULL || source_string->len == 0) {
120                 return 0;
121         }
122
123         while(source_string->len > 0 && isspace(*source_string->s)) {
124                 ++source_string->s;
125                 --source_string->len;
126         }
127         for(len = 0; len < source_string->len; ++len) {
128                 if(isspace(source_string->s[len])) {
129                         source_string->len = len;
130                         break;
131                 }
132         }
133         return 0;
134 }
135
136
137 enum hash_source get_hash_source(const char *hash_source)
138 {
139
140         if(strcasecmp("call_id", hash_source) == 0) {
141                 return hs_call_id;
142         } else if(strcasecmp("from_user", hash_source) == 0) {
143                 return hs_from_user;
144         } else if(strcasecmp("to_user", hash_source) == 0) {
145                 return hs_to_user;
146         } else {
147                 return hs_error;
148         }
149 }