app_lua: added internal alternative to luaL_openlib()
[sip-router] / src / modules / lrkproxy / lrkproxy_funcs.c
1 /*
2  * Copyright (C) 2001-2003 FhG Fokus
3  * Copyright (C) 2014-2015 Sipwise GmbH, http://www.sipwise.com
4  * Copyright (C) 2020 Mojtaba Esfandiari.S, Nasim-Telecom
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 #include <stdio.h>
24 #include <stdlib.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27 #include "lrkproxy_funcs.h"
28 #include "../../core/dprint.h"
29 #include "../../core/config.h"
30 #include "../../core/ut.h"
31 #include "../../core/forward.h"
32 #include "../../core/resolve.h"
33 #include "../../core/globals.h"
34 #include "../../core/udp_server.h"
35 #include "../../core/pt.h"
36 #include "../../core/parser/msg_parser.h"
37 #include "../../core/trim.h"
38 #include "../../core/parser/parse_from.h"
39 #include "../../core/parser/contact/parse_contact.h"
40 #include "../../core/parser/parse_uri.h"
41 #include "../../core/parser/parse_content.h"
42 #include "../../core/parser/parser_f.h"
43 #include "../../core/parser/sdp/sdp_helpr_funcs.h"
44
45 static pv_spec_t *custom_sdp_ip_avp;            /*!< AVP for custom_sdp_ip setting */
46
47
48 #define READ(val) \
49         (*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))
50 #define advance(_ptr,_n,_str,_error) \
51         do{\
52                 if ((_ptr)+(_n)>(_str).s+(_str).len)\
53                         goto _error;\
54                 (_ptr) = (_ptr) + (_n);\
55         }while(0);
56 #define one_of_16( _x , _t ) \
57         (_x==_t[0]||_x==_t[15]||_x==_t[8]||_x==_t[2]||_x==_t[3]||_x==_t[4]\
58         ||_x==_t[5]||_x==_t[6]||_x==_t[7]||_x==_t[1]||_x==_t[9]||_x==_t[10]\
59         ||_x==_t[11]||_x==_t[12]||_x==_t[13]||_x==_t[14])
60 #define one_of_8( _x , _t ) \
61         (_x==_t[0]||_x==_t[7]||_x==_t[1]||_x==_t[2]||_x==_t[3]||_x==_t[4]\
62         ||_x==_t[5]||_x==_t[6])
63
64
65
66 /**
67  * return:
68  * -1: error
69  *  1: text or sdp
70  *  2: multipart
71  *  3: trickle ice sdp fragment
72  */
73 int check_content_type(struct sip_msg *msg)
74 {
75     static unsigned int appl[16] = {
76             0x6c707061/*appl*/,0x6c707041/*Appl*/,0x6c705061/*aPpl*/,
77             0x6c705041/*APpl*/,0x6c507061/*apPl*/,0x6c507041/*ApPl*/,
78             0x6c505061/*aPPl*/,0x6c505041/*APPl*/,0x4c707061/*appL*/,
79             0x4c707041/*AppL*/,0x4c705061/*aPpL*/,0x4c705041/*APpL*/,
80             0x4c507061/*apPL*/,0x4c507041/*ApPL*/,0x4c505061/*aPPL*/,
81             0x4c505041/*APPL*/};
82     static unsigned int icat[16] = {
83             0x74616369/*icat*/,0x74616349/*Icat*/,0x74614369/*iCat*/,
84             0x74614349/*ICat*/,0x74416369/*icAt*/,0x74416349/*IcAt*/,
85             0x74414369/*iCAt*/,0x74414349/*ICAt*/,0x54616369/*icaT*/,
86             0x54616349/*IcaT*/,0x54614369/*iCaT*/,0x54614349/*ICaT*/,
87             0x54416369/*icAT*/,0x54416349/*IcAT*/,0x54414369/*iCAT*/,
88             0x54414349/*ICAT*/};
89     static unsigned int ion_[8] = {
90             0x006e6f69/*ion_*/,0x006e6f49/*Ion_*/,0x006e4f69/*iOn_*/,
91             0x006e4f49/*IOn_*/,0x004e6f69/*ioN_*/,0x004e6f49/*IoN_*/,
92             0x004e4f69/*iON_*/,0x004e4f49/*ION_*/};
93     static unsigned int sdp_[8] = {
94             0x00706473/*sdp_*/,0x00706453/*Sdp_*/,0x00704473/*sDp_*/,
95             0x00704453/*SDp_*/,0x00506473/*sdP_*/,0x00506453/*SdP_*/,
96             0x00504473/*sDP_*/,0x00504453/*SDP_*/};
97     str           str_type;
98     unsigned int  x;
99     char          *p;
100
101     if (!msg->content_type)
102     {
103                 LM_WARN("the header Content-TYPE is absent!"
104                                 "let's assume the content is text/plain ;-)\n");
105         return 1;
106     }
107
108     trim_len(str_type.len,str_type.s,msg->content_type->body);
109     if (str_type.len>=15 && (*str_type.s=='m' || *str_type.s=='M')
110         && strncasecmp(str_type.s, "multipart/mixed", 15) == 0) {
111         return 2;
112     }
113     p = str_type.s;
114     advance(p,4,str_type,error_1);
115     x = READ(p-4);
116     if (!one_of_16(x,appl))
117         goto other;
118     advance(p,4,str_type,error_1);
119     x = READ(p-4);
120     if (!one_of_16(x,icat))
121         goto other;
122     advance(p,3,str_type,error_1);
123     x = READ(p-3) & 0x00ffffff;
124     if (!one_of_8(x,ion_))
125         goto other;
126
127     /* skip spaces and tabs if any */
128     while (*p==' ' || *p=='\t')
129         advance(p,1,str_type,error_1);
130     if (*p!='/')
131     {
132                 LM_ERR("no / found after primary type\n");
133         goto error;
134     }
135     advance(p,1,str_type,error_1);
136     while ((*p==' ' || *p=='\t') && p+1<str_type.s+str_type.len)
137         advance(p,1,str_type,error_1);
138
139     advance(p,3,str_type,error_1);
140     x = READ(p-3) & 0x00ffffff;
141     if (!one_of_8(x,sdp_)) {
142         if (strncasecmp(p-3, "trickle-ice-sdpfrag", 19) == 0)
143             return 3;
144         goto other;
145     }
146
147     if (*p==';'||*p==' '||*p=='\t'||*p=='\n'||*p=='\r'||*p==0) {
148                 LM_DBG("type <%.*s> found valid\n", (int)(p-str_type.s), str_type.s);
149         return 1;
150     } else {
151                 LM_ERR("bad end for type!\n");
152         return -1;
153     }
154
155     error_1:
156             LM_ERR("body ended :-(!\n");
157     error:
158     return -1;
159     other:
160             LM_ERR("invalid type for a message\n");
161     return -1;
162 }
163
164
165 /*
166  * Get message body and check Content-Type header field
167  */
168 int extract_body(struct sip_msg *msg, str *body )
169 {
170     char c;
171     int ret;
172     str mpdel;
173     char *rest, *p1, *p2;
174     struct hdr_field hf;
175     unsigned int mime;
176
177     body->s = get_body(msg);
178     if (body->s==0) {
179                 LM_ERR("failed to get the message body\n");
180         goto error;
181     }
182
183     /*
184      * Better use the content-len value - no need of any explicit
185      * parcing as get_body() parsed all headers and Conten-Length
186      * body header is automaticaly parsed when found.
187      */
188     if (msg->content_length==0) {
189                 LM_ERR("failed to get the content length in message\n");
190         goto error;
191     }
192
193     body->len = get_content_length(msg);
194     if (body->len==0) {
195                 LM_ERR("message body has length zero\n");
196         goto error;
197     }
198
199     if (body->len + body->s > msg->buf + msg->len) {
200                 LM_ERR("content-length exceeds packet-length by %d\n",
201                        (int)((body->len + body->s) - (msg->buf + msg->len)));
202         goto error;
203     }
204
205     /* no need for parse_headers(msg, EOH), get_body will
206      * parse everything */
207     /*is the content type correct?*/
208     if((ret = check_content_type(msg))==-1)
209     {
210                 LM_ERR("content type mismatching\n");
211         goto error;
212     }
213
214     if(ret!=2)
215         goto done;
216
217     /* multipart body */
218     if(get_mixed_part_delimiter(&msg->content_type->body,&mpdel) < 0) {
219         goto error;
220     }
221     p1 = find_sdp_line_delimiter(body->s, body->s+body->len, mpdel);
222     if (p1 == NULL) {
223                 LM_ERR("empty multipart content\n");
224         return -1;
225     }
226     p2=p1;
227     c = 0;
228     for(;;)
229     {
230         p1 = p2;
231         if (p1 == NULL || p1 >= body->s+body->len)
232             break; /* No parts left */
233         p2 = find_next_sdp_line_delimiter(p1, body->s+body->len,
234                                           mpdel, body->s+body->len);
235         /* p2 is text limit for application parsing */
236         rest = eat_line(p1 + mpdel.len + 2, p2 - p1 - mpdel.len - 2);
237         if ( rest > p2 ) {
238                     LM_ERR("Unparsable <%.*s>\n", (int)(p1-p1), p1);
239             return -1;
240         }
241         while( rest<p2 ) {
242             memset(&hf,0, sizeof(struct hdr_field));
243             rest = get_sdp_hdr_field(rest, p2, &hf);
244             if(hf.type==HDR_EOH_T)
245                 break;
246             if(hf.type==HDR_ERROR_T)
247                 return -1;
248             if(hf.type==HDR_CONTENTTYPE_T) {
249                 if(decode_mime_type(hf.body.s, hf.body.s + hf.body.len,
250                                     &mime)==NULL)
251                     return -1;
252                 if (((((unsigned int)mime)>>16) == TYPE_APPLICATION)
253                     && ((mime&0x00ff) == SUBTYPE_SDP)) {
254                     c = 1;
255                 }
256             }
257         } /* end of while */
258         if(c==1)
259         {
260             if (rest < p2 && *rest == '\r') rest++;
261             if (rest < p2 && *rest == '\n') rest++;
262             if (rest < p2 && p2[-1] == '\n') p2--;
263             if (rest < p2 && p2[-1] == '\r') p2--;
264             body->s = rest;
265             body->len = p2-rest;
266             goto done;
267         }
268     }
269
270     error:
271     return -1;
272
273     done:
274     /*LM_DBG("DEBUG:extract_body:=|%.*s|\n",body->len,body->s);*/
275     return ret; /* mirrors return type of check_content_type */
276 }
277
278 /*
279  * Some helper functions taken verbatim from tm module.
280  */
281
282 /*
283  * Extract Call-ID value
284  * assumes the callid header is already parsed
285  * (so make sure it is, before calling this function or
286  *  it might fail even if the message _has_ a callid)
287  */
288 int
289 get_callid(struct sip_msg* _m, str* _cid)
290 {
291
292     if ((parse_headers(_m, HDR_CALLID_F, 0) == -1)) {
293                 LM_ERR("failed to parse call-id header\n");
294         return -1;
295     }
296
297     if (_m->callid == NULL) {
298                 LM_ERR("call-id not found\n");
299         return -1;
300     }
301
302     _cid->s = _m->callid->body.s;
303     _cid->len = _m->callid->body.len;
304     trim(_cid);
305     return 0;
306 }
307
308 /*
309  * Extract tag from To header field of a response
310  */
311 int
312 get_to_tag(struct sip_msg* _m, str* _tag)
313 {
314
315     if (parse_to_header(_m) < 0) {
316                 LM_ERR("To header field missing\n");
317         return -1;
318     }
319
320     if (get_to(_m)->tag_value.len) {
321         _tag->s = get_to(_m)->tag_value.s;
322         _tag->len = get_to(_m)->tag_value.len;
323     } else {
324         _tag->s = NULL; /* fixes gcc 4.0 warnings */
325         _tag->len = 0;
326     }
327
328     return 0;
329 }
330
331 /*
332  * Extract tag from From header field of a request
333  */
334 int
335 get_from_tag(struct sip_msg* _m, str* _tag)
336 {
337
338     if (parse_from_header(_m)<0) {
339                 LM_ERR("failed to parse From header\n");
340         return -1;
341     }
342
343     if (get_from(_m)->tag_value.len) {
344         _tag->s = get_from(_m)->tag_value.s;
345         _tag->len = get_from(_m)->tag_value.len;
346     } else {
347         _tag->s = NULL; /* fixes gcc 4.0 warnings */
348         _tag->len = 0;
349     }
350
351     return 0;
352 }
353
354 /*
355  * Extract URI from the Contact header field
356  */
357 int
358 get_contact_uri(struct sip_msg* _m, struct sip_uri *uri, contact_t** _c)
359 {
360
361     if ((parse_headers(_m, HDR_CONTACT_F, 0) == -1) || !_m->contact)
362         return -1;
363     if (!_m->contact->parsed && parse_contact(_m->contact) < 0) {
364                 LM_ERR("failed to parse Contact body\n");
365         return -1;
366     }
367     *_c = ((contact_body_t*)_m->contact->parsed)->contacts;
368     if (*_c == NULL)
369         /* no contacts found */
370         return -1;
371
372     if (parse_uri((*_c)->uri.s, (*_c)->uri.len, uri) < 0 || uri->host.len <= 0) {
373                 LM_ERR("failed to parse Contact URI [%.*s]\n",
374                        (*_c)->uri.len, ((*_c)->uri.s)?(*_c)->uri.s:"");
375         return -1;
376     }
377     return 0;
378 }
379
380 /*
381  * Extract branch from Via header
382  */
383 int
384 get_via_branch(struct sip_msg* msg, int vianum, str* _branch)
385 {
386     struct via_body *via;
387     struct via_param *p;
388
389     if (parse_via_header(msg, vianum, &via) < 0)
390         return -1;
391
392     for (p = via->param_lst; p; p = p->next)
393     {
394         if (p->name.len == strlen("branch")
395             && strncasecmp(p->name.s, "branch", strlen("branch")) == 0) {
396             _branch->s = p->value.s;
397             _branch->len = p->value.len;
398             return 0;
399         }
400     }
401     return -1;
402 }
403
404 int get_sdp_ipaddr_media(struct sip_msg *msg, str *ip_addr) {
405     sdp_session_cell_t *sdp_session;
406     sdp_stream_cell_t *sdp_stream;
407     sdp_info_t *sdp = (sdp_info_t *) msg->body;
408     if (!sdp) {
409                 LM_INFO("sdp null\n");
410         return -1;
411     }
412
413     char *s = ip_addr2a(&msg->rcv.src_ip);
414             LM_INFO("=========>msg->rcv.src_ip:%s\n", s);
415 //            LM_INFO("=========>msg->contact-body:%.*s\n", msg->contact->body.len, msg->contact->body.s);
416 //            LM_INFO("=========>msg->contact-name:%.*s\n", msg->contact->name.len, msg->contact->name.s);
417
418     pv_value_t pv_val;
419     if (custom_sdp_ip_avp) {
420         if ((pv_get_spec_value(msg, custom_sdp_ip_avp, &pv_val) == 0)
421             && (pv_val.flags & PV_VAL_STR) && (pv_val.rs.len > 0)) {
422             ip_addr->s = pv_val.rs.s;
423             ip_addr->len = pv_val.rs.len;
424                     LM_INFO("=========>custom_sdp_ip_avp:%.*s\n",   ip_addr->len,   ip_addr->s);
425
426             return 0;
427         }
428         else
429                 LM_DBG("invalid AVP value, using default user from RURI\n");
430     }
431
432
433     int sdp_session_num = 0;
434     sdp_session = get_sdp_session(msg, sdp_session_num);
435
436     if (!sdp_session) {
437                 LM_INFO("can not get the sdp session\n");
438         return 0;
439     }
440
441     if (sdp_session->ip_addr.s && sdp_session->ip_addr.len > 0) {
442                 LM_INFO("sdp_session->ip_addr:%.*s\n", sdp_session->ip_addr.len, sdp_session->ip_addr.s);
443
444         ip_addr->s = sdp_session->ip_addr.s;
445         ip_addr->len = sdp_session->ip_addr.len;
446         trim(ip_addr);
447
448     }
449     else {
450         int sdp_stream_num = 0;
451         sdp_stream = get_sdp_stream(msg, sdp_session_num, sdp_stream_num);
452         if (!sdp_stream) {
453                     LM_INFO("can not get the sdp stream\n");
454             return 0;
455         }
456         if (sdp_stream->ip_addr.s && sdp_stream->ip_addr.len > 0) {
457             LM_INFO("sdp_stream->ip_addr:%.*s\n", sdp_stream->ip_addr.len, sdp_stream->ip_addr.s);
458             ip_addr->s = sdp_stream->ip_addr.s;
459             ip_addr->len = sdp_stream->ip_addr.len;
460             trim(ip_addr);
461         }
462     }
463
464     
465     return 0;
466 }
467
468
469 int get_sdp_port_media(struct sip_msg *msg, str *port){
470 //    sdp_session_cell_t *sdp_session;
471     sdp_stream_cell_t *sdp_stream;
472     int sdp_session_num = 0;
473
474     sdp_info_t *sdp = (sdp_info_t *)msg->body;
475     if(!sdp) {
476                 LM_INFO("sdp null\n");
477         return -1;
478     }
479
480 //    sdp_session = get_sdp_session(msg, sdp_session_num);
481 //    if(!sdp_session) {
482 //                LM_INFO("can not get the sdp session\n");
483 //        return 0;
484 //    } else {
485 //                LM_INFO("NEW_IP_ADDRESS:>%.*s>\n", sdp_session->ip_addr.len, sdp_session->ip_addr.s);
486 //        lrk_sdp_info->ip_addr.s = sdp_session->ip_addr;
487         int sdp_stream_num = 0;
488         sdp_stream = get_sdp_stream(msg, sdp_session_num, sdp_stream_num);
489         if (!sdp_stream) {
490                     LM_INFO("can not get the sdp stream\n");
491             return -1;
492         } else {
493 //                    LM_INFO ("PORT:<%.*s>\n", sdp_stream->port.len, sdp_stream->port.s);
494 //            str2int(&sdp_stream->port, lrk_sdp_info->port)
495             port->s = sdp_stream->port.s;
496             port->len = sdp_stream->port.len;
497             trim(port);
498         }
499 //    }
500     return 0;
501
502 }
503
504 void init_custom_sdp_ip(pv_spec_t *custom_sdp_ip_avp_p)
505 {
506     custom_sdp_ip_avp = custom_sdp_ip_avp_p;
507
508 }