sca: end of line normalization to linux line ending format
[sip-router] / src / modules / sca / sca_util.c
1 /*
2  * Copyright (C) 2012 Andrew Mortensen
3  *
4  * This file is part of the sca module for Kamailio, a free SIP server.
5  *
6  * The sca module 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  * The sca module 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 #include "sca_common.h"
21 #include "sca.h"
22 #include <assert.h>
23
24 #include "sca_util.h"
25 #include "../../core/dset.h"
26 #include "../../core/parser/sdp/sdp.h"
27
28 int sca_get_msg_method(sip_msg_t *msg)
29 {
30         assert(msg != NULL);
31
32         if (msg->first_line.type == SIP_REQUEST) {
33                 return (msg->REQ_METHOD);
34         }
35
36         return (sca_get_msg_cseq_method(msg));
37 }
38
39 int sca_get_msg_contact_uri(sip_msg_t *msg, str *contact_uri)
40 {
41         contact_body_t *contact_body;
42
43         assert(msg != NULL);
44         assert(contact_uri != NULL);
45
46         if (SCA_HEADER_EMPTY(msg->contact)) {
47                 LM_DBG("Empty Contact header\n");
48                 contact_uri->s = NULL;
49                 contact_uri->len = 0;
50
51                 return (0);
52         }
53
54         if (parse_contact(msg->contact) < 0) {
55                 LM_ERR("Failed to parse Contact header: %.*s\n",
56                                 STR_FMT(&msg->contact->body));
57                 return (-1);
58         }
59         if ((contact_body = (contact_body_t *) msg->contact->parsed) == NULL) {
60                 LM_ERR("Invalid Contact header: %.*s\n", STR_FMT(&msg->contact->body));
61                 return (-1);
62         }
63         if (contact_body->star) {
64                 LM_ERR("Invalid Contact header: SCA Contact must not be \"*\"\n");
65                 return (-1);
66         }
67         if (contact_body->contacts == NULL) {
68                 LM_ERR("Invalid Contact header: parser found no contacts\n");
69                 return (-1);
70         }
71         if (contact_body->contacts->next) {
72                 LM_ERR("Invalid Contact header: Contact may only contain one URI\n");
73                 return (-1);
74         }
75
76         contact_uri->s = contact_body->contacts->uri.s;
77         contact_uri->len = contact_body->contacts->uri.len;
78
79         return (1);
80 }
81
82 int sca_get_msg_cseq_number(sip_msg_t *msg)
83 {
84         int cseq;
85
86         assert(msg != NULL);
87
88         if (SCA_HEADER_EMPTY(msg->cseq)) {
89                 LM_ERR("Empty Cseq header\n");
90                 return (-1);
91         }
92         if (str2int(&(get_cseq(msg)->number), (unsigned int *) &cseq) != 0) {
93                 LM_ERR("Bad Cseq header: %.*s\n", STR_FMT(&msg->cseq->body));
94                 return (-1);
95         }
96
97         return (cseq);
98 }
99
100 /*
101  *  assumes cseq header in msg is already parsed
102  */
103 int sca_get_msg_cseq_method(sip_msg_t *msg)
104 {
105         assert(msg != NULL);
106
107         if (SCA_HEADER_EMPTY(msg->cseq)) {
108                 LM_ERR("Empty Cseq header\n");
109                 return (-1);
110         }
111
112         return (get_cseq(msg)->method_id);
113 }
114
115 int sca_get_msg_from_header(sip_msg_t *msg, struct to_body **from)
116 {
117         struct to_body *f;
118
119         assert(msg != NULL);
120         assert(from != NULL);
121
122         if (SCA_HEADER_EMPTY(msg->from)) {
123                 LM_ERR("Empty From header\n");
124                 return (-1);
125         }
126         if (parse_from_header(msg) < 0) {
127                 LM_ERR("Bad From header\n");
128                 return (-1);
129         }
130         f = get_from(msg);
131         if (SCA_STR_EMPTY(&f->tag_value)) {
132                 LM_ERR("Bad From header: no tag parameter\n");
133                 return (-1);
134         }
135
136         // ensure the URI is parsed for future use
137         if (parse_uri(f->uri.s, f->uri.len, GET_FROM_PURI(msg)) < 0) {
138                 LM_ERR("Failed to parse From URI %.*s\n", STR_FMT(&f->uri));
139                 return (-1);
140         }
141
142         *from = f;
143
144         return (0);
145 }
146
147 int sca_get_msg_to_header(sip_msg_t *msg, struct to_body **to)
148 {
149         struct to_body parsed_to;
150         struct to_body *t = NULL;
151
152         assert(msg != NULL);
153         assert(to != NULL);
154
155         if (SCA_HEADER_EMPTY(msg->to)) {
156                 LM_ERR("Empty To header\n");
157                 return (-1);
158         }
159         t = get_to(msg);
160         if (t == NULL) {
161                 parse_to(msg->to->body.s, msg->to->body.s + msg->to->body.len + 1, // end of buffer
162                 &parsed_to);
163                 if (parsed_to.error != PARSE_OK) {
164                         LM_ERR("Bad To header\n");
165                         return (-1);
166                 }
167                 t = &parsed_to;
168         }
169
170         // ensure the URI is parsed for future use
171         if (parse_uri(t->uri.s, t->uri.len, GET_TO_PURI(msg)) < 0) {
172                 LM_ERR("Failed to parse To URI %.*s\n", STR_FMT(&t->uri));
173                 return (-1);
174         }
175
176         *to = t;
177
178         return (0);
179 }
180
181 /*
182  * caller needs to call free_to for *body
183  */
184 int sca_build_to_body_from_uri(sip_msg_t *msg, struct to_body **body, str *uri)
185 {
186         assert(msg != NULL);
187         assert(body != NULL);
188         assert(uri != NULL);
189
190         *body = pkg_malloc(sizeof(struct to_body));
191         if(*body == NULL) {
192                 LM_ERR("cannot allocate pkg memory\n");
193                 return(-1);
194         }
195
196         parse_to(uri->s, uri->s + uri->len + 1, *body);
197         if ((*body)->error != PARSE_OK) {
198                 LM_ERR("Bad uri value[%.*s]\n", STR_FMT(uri));
199                 free_to(*body);
200                 return(-1);
201         }
202         return (0);
203 }
204
205 /*
206  *  count characters requiring escape as defined by escape_common
207  */
208 int sca_uri_display_escapes_count(str *display) {
209         int c = 0;
210         int i;
211
212         if (SCA_STR_EMPTY(display)) {
213                 return (0);
214         }
215
216         for (i = 0; i < display->len; i++) {
217                 switch (display->s[i]) {
218                 case '\'':
219                 case '"':
220                 case '\\':
221                 case '\0':
222                         c++;
223
224                 default:
225                         break;
226                 }
227         }
228
229         return (c);
230 }
231
232 int sca_uri_extract_aor(str *uri, str *aor)
233 {
234         char *semi;
235
236         assert(aor != NULL);
237
238         if (uri == NULL) {
239                 aor->s = NULL;
240                 aor->len = 0;
241                 return (-1);
242         }
243
244         aor->s = uri->s;
245         semi = memchr(uri->s, ';', uri->len);
246         if (semi != NULL) {
247                 aor->len = semi - uri->s;
248         } else {
249                 aor->len = uri->len;
250         }
251
252         return (0);
253 }
254
255 int sca_uri_build_aor(str *aor, int maxlen, str *contact_uri, str *domain_uri)
256 {
257         char *p;
258         char *dp;
259         int len;
260
261         assert(aor != NULL);
262         assert(contact_uri != NULL);
263         assert(domain_uri != NULL);
264
265         if (contact_uri->len + domain_uri->len >= maxlen) {
266                 return (-1);
267         }
268
269         p = memchr(contact_uri->s, '@', contact_uri->len);
270         if (p == NULL) {
271                 // no username, by definition can't be an SCA line
272                 aor->s = NULL;
273                 aor->len = 0;
274
275                 return (0);
276         }
277         dp = memchr(domain_uri->s, '@', domain_uri->len);
278         if (dp == NULL) {
279                 // may be nameless URI
280                 dp = memchr(domain_uri->s, ':', domain_uri->len);
281                 if (dp == NULL) {
282                         // bad domain URI
283                         return (-1);
284                 }
285         }
286         dp++;
287
288         len = p - contact_uri->s;
289         memcpy(aor->s, contact_uri->s, len);
290         aor->s[len] = '@';
291         len += 1;
292         aor->len = len;
293
294         len = domain_uri->len - (dp - domain_uri->s);
295         memcpy(aor->s + aor->len, dp, len);
296         aor->len += len;
297
298         return (aor->len);
299 }
300
301 int sca_aor_create_from_info(str *aor, uri_type type, str *user, str *domain,
302                 str *port)
303 {
304         str scheme = STR_NULL;
305         int len = 0;
306
307         assert(aor != NULL);
308
309         uri_type_to_str(type, &scheme);
310
311         // +1 for ':', +1 for '@'
312         len = scheme.len + 1 + user->len + 1 + domain->len;
313         if (!SCA_STR_EMPTY(port)) {
314                 // +1 for ':'
315                 len += 1 + port->len;
316         }
317
318         aor->s = (char *) pkg_malloc(len);
319         if (aor->s == NULL) {
320                 LM_ERR("sca_aor_create_from_info: pkg_malloc %d bytes failed\n", len);
321                 return (-1);
322         }
323
324         len = 0;
325         SCA_STR_COPY(aor, &scheme);
326         len += scheme.len;
327
328         *(aor->s + len) = ':';
329         aor->len++;
330         len++;
331
332         SCA_STR_APPEND(aor, user);
333         len += user->len;
334
335         *(aor->s + len) = '@';
336         aor->len++;
337         len++;
338
339         SCA_STR_APPEND(aor, domain);
340         len += domain->len;
341
342         if (!SCA_STR_EMPTY(port)) {
343                 *(aor->s + len) = ':';
344                 len += 1;
345
346                 SCA_STR_APPEND(aor, port);
347                 len += port->len;
348         }
349
350         return (aor->len);
351 }
352
353 int sca_create_canonical_aor_for_ua(sip_msg_t *msg, str *c_aor, int ua_opts)
354 {
355         struct to_body *tf = NULL;
356         sip_uri_t c_uri;
357         str tf_aor = STR_NULL;
358         str contact_uri = STR_NULL;
359         int rc = -1;
360
361         assert(msg != NULL);
362         assert(c_aor != NULL);
363
364         memset(c_aor, 0, sizeof(str));
365
366         if ((ua_opts & SCA_AOR_TYPE_AUTO)) {
367                 if (msg->first_line.type == SIP_REQUEST) {
368                         ua_opts = SCA_AOR_TYPE_UAC;
369                 } else {
370                         ua_opts = SCA_AOR_TYPE_UAS;
371                 }
372         }
373
374         if ((ua_opts & SCA_AOR_TYPE_UAC)) {
375                 if (sca_get_msg_from_header(msg, &tf) < 0) {
376                         LM_ERR("sca_create_canonical_aor: failed to get From header\n");
377                         goto done;
378                 }
379         } else {
380                 if (sca_get_msg_to_header(msg, &tf) < 0) {
381                         LM_ERR("sca_create_canonical_aor: failed to get To header\n");
382                         goto done;
383                 }
384         }
385
386         if (sca_uri_extract_aor(&tf->uri, &tf_aor) < 0) {
387                 LM_ERR("sca_create_canonical_aor: failed to extract AoR from "
388                                 "URI <%.*s>\n", STR_FMT(&tf->uri));
389                 goto done;
390         }
391
392         memset(&c_uri, 0, sizeof(sip_uri_t));
393         if ((rc = sca_get_msg_contact_uri(msg, &contact_uri)) < 0) {
394                 LM_ERR("sca_create_canonical_aor: failed to get contact URI from "
395                                 "Contact <%.*s>\n", STR_FMT(&msg->contact->body));
396                 goto done;
397         }
398         if (rc > 0) {
399                 if (parse_uri(contact_uri.s, contact_uri.len, &c_uri) < 0) {
400                         LM_ERR("sca_create_canonical_aor: failed to parse Contact URI "
401                                         "<%.*s>\n", STR_FMT(&contact_uri));
402                         rc = -1;
403                         goto done;
404                 }
405         }
406
407         if (SCA_STR_EMPTY(&c_uri.user) ||
408         SCA_STR_EQ(&c_uri.user, &tf->parsed_uri.user)) {
409                 // empty contact header or Contact user matches To/From AoR
410                 c_aor->s = (char *) pkg_malloc(tf_aor.len);
411                 c_aor->len = tf_aor.len;
412                 memcpy(c_aor->s, tf_aor.s, tf_aor.len);
413         } else {
414                 // Contact user and To/From user mismatch
415                 if (sca_aor_create_from_info(c_aor, c_uri.type, &c_uri.user,
416                                 &tf->parsed_uri.host, &tf->parsed_uri.port) < 0) {
417                         LM_ERR("sca_create_canonical_aor: failed to create AoR from "
418                                         "Contact <%.*s> and URI <%.*s>\n",
419                                         STR_FMT(&contact_uri), STR_FMT(&tf_aor));
420                         goto done;
421                 }
422         }
423
424         rc = 1;
425
426         done: return (rc);
427 }
428
429 int sca_create_canonical_aor(sip_msg_t *msg, str *c_aor)
430 {
431         return (sca_create_canonical_aor_for_ua(msg, c_aor, SCA_AOR_TYPE_AUTO));
432 }
433
434 /*
435  * XXX this considers any held stream to mean the call is on hold. correct?
436  */
437 int sca_call_is_held(sip_msg_t *msg)
438 {
439         sdp_session_cell_t *session;
440         sdp_stream_cell_t *stream;
441         int n_sess;
442         int n_str;
443         int is_held = 0;
444         int rc;
445
446         if(sca->cfg->onhold_bflag >= 0) {
447                 if (isbflagset(0, (flag_t)sca->cfg->onhold_bflag)==1) {
448                         LM_DBG("onhold_bflag set, skip parse_sdp and set held\n");
449                         return ( 1 );
450                 }
451         }
452         rc = parse_sdp(msg);
453         if (rc < 0) {
454                 LM_ERR("sca_call_is_held: parse_sdp body failed\n");
455                 return (0);
456         } else if (rc > 0) {
457                 LM_DBG("sca_call_is_held: parse_sdp returned %d, no SDP body\n", rc);
458                 return (0);
459         }
460
461         // Cf. modules_k/textops's exported is_audio_on_hold
462         for (n_sess = 0, session = get_sdp_session(msg, n_sess); session != NULL;
463                         n_sess++, session = get_sdp_session(msg, n_sess)) {
464
465                 for (n_str = 0, stream = get_sdp_stream(msg, n_sess, n_str);
466                                 stream != NULL;
467                                 n_str++, stream = get_sdp_stream(msg, n_sess, n_str)) {
468                         if (stream->is_on_hold) {
469                                 LM_DBG("sca_call_is_held: parse_sdp detected stream is on hold\n");
470                                 is_held = 1;
471                                 goto done;
472                         }
473                 }
474         }
475
476         done: return (is_held);
477 }