app_lua: added internal alternative to luaL_openlib()
[sip-router] / src / modules / lrkproxy / lrkproxy.c
1 /*
2  * Copyright (C) 2003-2008 Sippy Software, Inc., http://www.sippysoft.com
3  * Copyright (C) 2020 Mojtaba Esfandiari.S, Nasim-Telecom
4  *
5  * This file is part of Kamailio, a free SIP server.
6  *
7  * Kamailio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version
11  *
12  * Kamailio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
20  *
21  */
22
23 #include <sys/types.h>
24 #include <sys/socket.h>
25 #include <sys/time.h>
26 #include <netinet/in.h>
27 #include <netinet/in_systm.h>
28 #ifndef __USE_BSD
29 #define  __USE_BSD
30 #endif
31 #include <netinet/ip.h>
32 #ifndef __FAVOR_BSD
33 #define __FAVOR_BSD
34 #endif
35 #include <netinet/udp.h>
36 #include <arpa/inet.h>
37 #include <sys/uio.h>
38 #include <sys/un.h>
39 #include <ctype.h>
40 #include <errno.h>
41 #include <netdb.h>
42 #include <poll.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <string.h>
46 #include <unistd.h>
47
48 #include "../../core/flags.h"
49 #include "../../core/sr_module.h"
50 #include "../../core/dprint.h"
51 #include "../../core/data_lump.h"
52 #include "../../core/data_lump_rpl.h"
53 #include "../../core/error.h"
54 #include "../../core/forward.h"
55 #include "../../core/mem/mem.h"
56 #include "../../core/parser/parse_from.h"
57 #include "../../core/parser/parse_to.h"
58 #include "../../core/parser/parse_uri.h"
59 #include "../../core/parser/parser_f.h"
60 #include "../../core/parser/sdp/sdp.h"
61 #include "../../core/resolve.h"
62 #include "../../core/timer.h"
63 #include "../../core/trim.h"
64 #include "../../core/ut.h"
65 #include "../../core/pt.h"
66 #include "../../core/timer_proc.h"
67 #include "../../core/rpc.h"
68 #include "../../core/rpc_lookup.h"
69 #include "../../core/pvar.h"
70 #include "../../core/lvalue.h"
71 #include "../../core/msg_translator.h"
72 #include "../../core/usr_avp.h"
73 #include "../../core/socket_info.h"
74 #include "../../core/mod_fix.h"
75 #include "../../core/dset.h"
76 #include "../../core/route.h"
77 #include "../../core/kemi.h"
78 #include "../../modules/tm/tm_load.h"
79 #include "lrkproxy.h"
80 #include "lrkproxy_hash.h"
81 #include "lrkproxy_funcs.h"
82
83 MODULE_VERSION
84
85
86 #if !defined(AF_LOCAL)
87 #define AF_LOCAL AF_UNIX
88 #endif
89 #if !defined(PF_LOCAL)
90 #define PF_LOCAL PF_UNIX
91 #endif
92
93 ///* NAT UAC test constants */
94 //#define       NAT_UAC_TEST_C_1918     0x01
95 //#define       NAT_UAC_TEST_RCVD       0x02
96 //#define       NAT_UAC_TEST_V_1918     0x04
97 //#define       NAT_UAC_TEST_S_1918     0x08
98 //#define       NAT_UAC_TEST_RPORT      0x10
99
100 #define DEFAULT_LRKP_SET_ID             0
101 static str DEFAULT_LRKP_SET_ID_STR = str_init("0");
102
103 //#define RPC_DEFAULT_NATPING_STATE     1
104
105 #define RPC_MIN_RECHECK_TICKS           0
106 #define RPC_MAX_RECHECK_TICKS           (unsigned int)-1
107
108
109 /* Supported version of the LRK proxy command protocol */
110 #define SUP_CPROTOVER   "20190708"
111 /* Required additional version of the LRK proxy command protocol */
112 #define REQ_CPROTOVER   "20190709"
113 /* Additional version necessary for re-packetization support */
114 #define REP_CPROTOVER   "20190708"
115 #define PTL_CPROTOVER   "20190708"
116
117 #define CPORT           "22333"
118 #define HASH_SIZE   128
119
120 static char *gencookie();
121 static int lrkp_test(struct lrkp_node*);
122 static int lrkp_get_config(struct lrkp_node *node);
123 static int lrkp_set_conntrack_rule(struct lrkproxy_hash_entry *e);
124
125
126 static int lrkproxy_force(struct sip_msg *msg, const char *flags, enum lrk_operation op, int more);
127 static int lrkproxy_unforce(struct sip_msg *msg, const char *flags, enum lrk_operation op, int more);
128
129 static int lrkproxy_manage0(struct sip_msg *msg, char *flags, char *ip);
130 static int lrkproxy_manage1(struct sip_msg *msg, char *flags, char *ip);
131 static int lrkproxy_manage2(struct sip_msg *msg, char *flags, char *ip);
132
133 static int change_media_sdp(sip_msg_t *msg, struct lrkproxy_hash_entry *e, const char *flags, enum lrk_operation op);
134
135 static int add_lrkproxy_socks(struct lrkp_set * lrkp_list, char * lrkproxy);
136 static int fixup_set_id(void ** param, int param_no);
137 static int set_lrkproxy_set_f(struct sip_msg * msg, char * str1, char * str2);
138
139 static struct lrkp_set * select_lrkp_set(int id_set);
140
141 static int lrkproxy_set_store(modparam_t type, void * val);
142 static int lrkproxy_add_lrkproxy_set( char * lrk_proxies);
143
144 static int mod_init(void);
145 static int child_init(int);
146 static void mod_destroy(void);
147
148 /* Pseudo-Variables */
149 //static int pv_get_lrkstat_f(struct sip_msg *, pv_param_t *, pv_value_t *);
150
151 static int lrkproxy_disable_tout = 60;
152 static int lrkproxy_retr = 5;
153 static int lrkproxy_tout = 1;
154 static pid_t mypid;
155 static unsigned int myseqn = 0;
156 //static str nolrkproxy_str = str_init("a=nolrkproxy:yes");
157 //static str extra_id_pv_param = {NULL, 0};
158
159 static char ** lrkp_strings=0;
160 static int lrkp_sets=0; /*used in lrkproxy_set_store()*/
161 static int lrkp_set_count = 0;
162 static unsigned int current_msg_id = (unsigned int)-1;
163 /* LRK proxy balancing list */
164 struct lrkp_set_head * lrkp_set_list =0;
165 struct lrkp_set * selected_lrkp_set =0;
166 struct lrkp_set * default_lrkp_set=0;
167 struct lrkp_node *selected_lrkp_node = 0;
168 int lrkp_algorithm = LRK_LINER;
169 static int hash_table_size = 0;
170 static int hash_table_tout = 3600;
171
172 /*!< The gt is game-theory variable, It could be set 0:disable and 1:enable
173  * default is 0.
174  */
175 int gt = 0;
176
177 /*
178  * the custom_sdp_ip_spec variable is used for specific SDP information based $si (source address)
179  * */
180 static str custom_sdp_ip_spec = {NULL, 0};
181 pv_spec_t custom_sdp_ip_avp;
182
183
184
185
186 //static char *ice_candidate_priority_avp_param = NULL;
187 //static int ice_candidate_priority_avp_type;
188 //static int_str ice_candidate_priority_avp;
189 //static str lrk_inst_pv_param = {NULL, 0};
190 //static pv_spec_t *lrk_inst_pvar = NULL;
191
192 /* array with the sockets used by lrkproxy (per process)*/
193 static unsigned int lrkp_no = 0;
194 static int *lrkp_socks = 0;
195
196
197 typedef struct lrkp_set_link {
198         struct lrkp_set *rset;
199         pv_spec_t *rpv;
200 } lrkp_set_link_t;
201
202 /* tm */
203 static struct tm_binds tmb;
204
205 /*0-> disabled, 1 ->enabled*/
206 //unsigned int *natping_state=0;
207
208 static cmd_export_t cmds[] = {
209
210         {"set_lrkproxy_set",  (cmd_function)set_lrkproxy_set_f,    1,
211                 fixup_set_id, 0,
212                 ANY_ROUTE},
213         {"lrkproxy_manage",     (cmd_function)lrkproxy_manage0,     0,
214                                                        0, 0,
215                    ANY_ROUTE},
216         {"lrkproxy_manage",     (cmd_function)lrkproxy_manage1,     1,
217                                                        fixup_spve_null, fixup_free_spve_null,
218                    ANY_ROUTE},
219         {"lrkproxy_manage",     (cmd_function)lrkproxy_manage2,     2,
220                                                        fixup_spve_spve, fixup_free_spve_spve,
221                    ANY_ROUTE},
222
223         {0, 0, 0, 0, 0, 0}
224 };
225
226 static param_export_t params[] = {
227         {"lrkproxy_sock",         PARAM_STRING|USE_FUNC_PARAM,
228                 (void*)lrkproxy_set_store          },
229         {"lrkproxy_disable_tout", INT_PARAM, &lrkproxy_disable_tout },
230         {"lrkproxy_retr",         INT_PARAM, &lrkproxy_retr         },
231         {"lrkproxy_tout",         INT_PARAM, &lrkproxy_tout         },
232         {"lrkp_alg",         INT_PARAM, &lrkp_algorithm         },
233         {"hash_table_tout",       INT_PARAM, &hash_table_tout        },
234         {"hash_table_size",       INT_PARAM, &hash_table_size        },
235         {"custom_sdp_ip_avp",     PARAM_STR, &custom_sdp_ip_spec},
236         {"gt",   INT_PARAM  , &gt},
237
238         {0, 0, 0}
239 };
240
241 /** module exports */
242 struct module_exports exports= {
243         "lrkproxy",        /* module name */
244         DEFAULT_DLFLAGS, /* dlopen flags */
245         cmds,            /* cmd exports */
246         params,          /* param exports */
247         0,               /* RPC method exports */
248         0,         /* exported pseudo-variables */
249         0,               /* response handling function */
250         mod_init,        /* module initialization function */
251         child_init,               /* per-child init function */
252         mod_destroy                /* module destroy function */
253 };
254
255
256 static int lrkproxy_set_store(modparam_t type, void * val){
257
258     char * p;
259     int len;
260
261     p = (char* )val;
262
263     if(p==0 || *p=='\0'){
264         return 0;
265     }
266
267     if(lrkp_sets==0){
268         lrkp_strings = (char**)pkg_malloc(sizeof(char*));
269         if(!lrkp_strings){
270                     LM_ERR("no pkg memory left\n");
271             return -1;
272         }
273     } else {/*realloc to make room for the current set*/
274         lrkp_strings = (char**)pkg_reallocxf(lrkp_strings,
275                                              (lrkp_sets+1)* sizeof(char*));
276         if(!lrkp_strings){
277                     LM_ERR("no pkg memory left\n");
278             return -1;
279         }
280     }
281
282     /*allocate for the current set of urls*/
283     len = strlen(p);
284     lrkp_strings[lrkp_sets] = (char*)pkg_malloc((len+1)*sizeof(char));
285
286     if(!lrkp_strings[lrkp_sets]){
287                 LM_ERR("no pkg memory left\n");
288         return -1;
289     }
290
291     memcpy(lrkp_strings[lrkp_sets], p, len);
292     lrkp_strings[lrkp_sets][len] = '\0';
293     lrkp_sets++;
294
295     return 0;
296 }
297
298 struct lrkp_set *get_lrkp_set(str *const set_name)
299 {
300     unsigned int this_set_id;
301     struct lrkp_set *lrkp_list;
302     if (lrkp_set_list == NULL)
303     {
304                 LM_ERR("lrkp set list not configured\n");
305         return NULL;
306     }
307     /* Only integer set_names are valid at the moment */
308     if ((set_name->s == NULL) || (set_name->len == 0))
309     {
310                 LM_ERR("Invalid set name '%.*s'\n", set_name->len, set_name->s);
311         return NULL;
312     }
313     if (str2int(set_name, &this_set_id) < 0)
314     {
315                 LM_ERR("Invalid set name '%.*s' - must be integer\n", set_name->len, set_name->s);
316         return NULL;
317     }
318
319     lrkp_list = select_lrkp_set(this_set_id);
320
321     if(lrkp_list==NULL){        /*if a new id_set : add a new set of lrkp*/
322         lrkp_list = shm_malloc(sizeof(struct lrkp_set));
323         if(!lrkp_list){
324                     LM_ERR("no shm memory left\n");
325             return NULL;
326         }
327         memset(lrkp_list, 0, sizeof(struct lrkp_set));
328         lrkp_list->id_set = this_set_id;
329         if (lrkp_set_list->lset_first == NULL)
330         {
331             lrkp_set_list->lset_first = lrkp_list;
332         } else {
333             lrkp_set_list->lset_last->lset_next = lrkp_list;
334         }
335         lrkp_set_list->lset_last = lrkp_list;
336         lrkp_set_count++;
337
338         if (this_set_id == DEFAULT_LRKP_SET_ID)
339         {
340             default_lrkp_set = lrkp_list;
341         }
342     }
343     return lrkp_list;
344 }
345
346 int insert_lrkp_node(struct lrkp_set *const lrkp_list, const str *const url, const int weight, const int enable)
347 {
348     struct lrkp_node *pnode;
349
350     if ((pnode = shm_malloc(sizeof(struct lrkp_node) + url->len + 1)) == NULL)
351     {
352                 LM_ERR("out of shm memory\n");
353         return -1;
354     }
355
356     memset(pnode, 0, sizeof(struct lrkp_node) + url->len + 1);
357
358
359     struct lrkp_node_conf *node_conf;
360     node_conf = shm_malloc(sizeof(struct lrkp_node_conf));
361     if (!node_conf)
362     {
363                 LM_ERR("out of shm memory\n");
364         return -1;
365     }
366
367     memset(node_conf, 0, sizeof(struct lrkp_node_conf));
368     pnode->lrkp_n_c = node_conf;
369
370     pnode->idx = lrkp_no++;
371     pnode->ln_weight = weight;
372     pnode->ln_umode = 0;
373     pnode->ln_enable = enable;
374     /* Permanently disable if marked as disabled */
375 //    pnode->ln_recheck_ticks = disabled ? RPC_MAX_RECHECK_TICKS : 0;
376     pnode->ln_url.s = (char*)(pnode + 1);
377     memcpy(pnode->ln_url.s, url->s, url->len);
378     pnode->ln_url.len = url->len;
379
380             LM_DBG("url is '%.*s'\n", pnode->ln_url.len, pnode->ln_url.s);
381
382     /* Find protocol and store address */
383     pnode->ln_address = pnode->ln_url.s;
384     if (strncasecmp(pnode->ln_address, "udp:", 4) == 0) {
385         pnode->ln_umode = 1;
386         pnode->ln_address += 4;
387     } else if (strncasecmp(pnode->ln_address, "udp6:", 5) == 0) {
388         pnode->ln_umode = 6;
389         pnode->ln_address += 5;
390     } else if (strncasecmp(pnode->ln_address, "unix:", 5) == 0) {
391         pnode->ln_umode = 0;
392         pnode->ln_address += 5;
393     }
394
395     if (lrkp_list->ln_first == NULL)
396     {
397         lrkp_list->ln_first = pnode;
398     } else {
399         lrkp_list->ln_last->ln_next = pnode;
400     }
401     lrkp_list->ln_last = pnode;
402     lrkp_list->lrkp_node_count++;
403
404     return 0;
405 }
406
407 static int add_lrkproxy_socks(struct lrkp_set * lrkp_list,
408                               char * lrkproxy){
409     /* Make lrk proxies list. */
410     char *p, *p1, *p2, *plim;
411     int weight;
412     str url;
413
414     p = lrkproxy;
415     plim = p + strlen(p);
416
417     for(;;) {
418         weight = 1;
419         while (*p && isspace((int)*p))
420             ++p;
421         if (p >= plim)
422             break;
423         p1 = p;
424         while (*p && !isspace((int)*p))
425             ++p;
426         if (p <= p1)
427             break; /* may happen??? */
428         /* Have weight specified? If yes, scan it */
429         p2 = memchr(p1, '=', p - p1);
430         if (p2 != NULL) {
431             weight = strtoul(p2 + 1, NULL, 10);
432         } else {
433             p2 = p;
434         }
435
436         url.s = p1;
437         url.len = (p2-p1);
438         insert_lrkp_node(lrkp_list, &url, weight, 0);
439     }
440     return 0;
441 }
442
443 /*      0-succes
444  *  -1 - erorr
445  * */
446 static int lrkproxy_add_lrkproxy_set( char * lrk_proxies)
447 {
448     char *p,*p2;
449     struct lrkp_set * lrkp_list;
450     str id_set;
451
452     /* empty definition? */
453     p= lrk_proxies;
454     if(!p || *p=='\0'){
455         return 0;
456     }
457
458     for(;*p && isspace(*p);p++);
459     if(*p=='\0'){
460         return 0;
461     }
462
463     lrk_proxies = strstr(p, "==");
464     if(lrk_proxies){
465         if(*(lrk_proxies +2)=='\0'){
466                     LM_ERR("script error -invalid lrk proxy list!\n");
467             return -1;
468         }
469
470         *lrk_proxies = '\0';
471         p2 = lrk_proxies-1;
472         for(;isspace(*p2); *p2 = '\0',p2--);
473         id_set.s = p;   id_set.len = p2 - p+1;
474
475         if(id_set.len <= 0){
476                     LM_ERR("script error -invalid set_id value!\n");
477             return -1;
478         }
479
480         lrk_proxies+=2;
481     }else{
482         lrk_proxies = p;
483         id_set = DEFAULT_LRKP_SET_ID_STR;
484     }
485
486     for(;*lrk_proxies && isspace(*lrk_proxies);lrk_proxies++);
487
488     if(!(*lrk_proxies)){
489                 LM_ERR("script error -empty lrkproxy list\n");
490         return -1;;
491     }
492
493     lrkp_list = get_lrkp_set(&id_set);
494     if (lrkp_list == NULL)
495     {
496                 LM_ERR("Failed to get or create lrkp_list for '%.*s'\n", id_set.len, id_set.s);
497         return -1;
498     }
499
500     if(add_lrkproxy_socks(lrkp_list, lrk_proxies)!= 0){
501         return -1;
502     }
503
504     return 0;
505 }
506
507
508 static int fixup_set_id(void ** param, int param_no)
509 {
510         int int_val, err;
511         struct lrkp_set* lrkp_list;
512         lrkp_set_link_t *lrkl = NULL;
513         str s;
514
515         lrkl = (lrkp_set_link_t*)pkg_malloc(sizeof(lrkp_set_link_t));
516         if(lrkl==NULL) {
517                 LM_ERR("no more pkg memory\n");
518                 return -1;
519         }
520         memset(lrkl, 0, sizeof(lrkp_set_link_t));
521         s.s = (char*)*param;
522         s.len = strlen(s.s);
523
524         if(s.s[0] == PV_MARKER) {
525                 int_val = pv_locate_name(&s);
526                 if(int_val<0 || int_val!=s.len) {
527                         LM_ERR("invalid parameter %s\n", s.s);
528                         pkg_free(lrkl);
529                         return -1;
530                 }
531                 lrkl->rpv = pv_cache_get(&s);
532                 if(lrkl->rpv == NULL) {
533                         LM_ERR("invalid pv parameter %s\n", s.s);
534                         pkg_free(lrkl);
535                         return -1;
536                 }
537         } else {
538                 int_val = str2s(*param, strlen(*param), &err);
539                 if (err == 0) {
540                         pkg_free(*param);
541                         if((lrkp_list = select_lrkp_set(int_val)) ==0){
542                                 LM_ERR("lrkp_proxy set %i not configured\n", int_val);
543                                 pkg_free(lrkl);
544                                 return E_CFG;
545                         }
546                         lrkl->rset = lrkp_list;
547                 } else {
548                         LM_ERR("bad number <%s>\n",     (char *)(*param));
549                         pkg_free(lrkl);
550                         return E_CFG;
551                 }
552         }
553         *param = (void*)lrkl;
554         return 0;
555 }
556
557
558 static int
559 mod_init(void)
560 {
561     int i;
562 //      pv_spec_t avp_spec;
563 //      str s;
564 //      unsigned short avp_flags;
565
566 //      if(lrkproxy_rpc_init()<0)
567 //      {
568 //              LM_ERR("failed to register RPC commands\n");
569 //              return -1;
570 //      }
571
572     /* Configure the head of the lrkp_set_list */
573     lrkp_set_list = shm_malloc(sizeof(struct lrkp_set_head));
574     if (lrkp_set_list == NULL)
575     {
576                 LM_ERR("no shm memory for lrkp_set_list\n");
577         return -1;
578     }
579     memset(lrkp_set_list, 0, sizeof(struct lrkp_set_head));
580
581
582     /* storing the list of lrk proxy sets in shared memory*/
583     for(i=0;i<lrkp_sets;i++){
584                 LM_DBG("Adding LRK-Proxy set %d/%d: %s\n", i, lrkp_sets, lrkp_strings[i]);
585 //        if ((lrkp_db_url.s == NULL) &&
586         if (lrkproxy_add_lrkproxy_set(lrkp_strings[i]) != 0) {
587             for(;i<lrkp_sets;i++)
588                 if(lrkp_strings[i])
589                     pkg_free(lrkp_strings[i]);
590             pkg_free(lrkp_strings);
591                     LM_ERR("Failed to add LRK-Proxy from Config!\n");
592             return -1;
593         }
594         if(lrkp_strings[i])
595             pkg_free(lrkp_strings[i]);
596     }
597
598
599     if (lrkp_strings)
600         pkg_free(lrkp_strings);
601
602
603     /* init the hastable which keeps the all media address for both party and also the elected_node <--> callid& via-branch relation */
604     if (hash_table_size < 1){
605         hash_table_size = HASH_SIZE;    //the default size 128 entry.
606     }
607
608     if (!lrkproxy_hash_table_init(hash_table_size)) {
609                 LM_ERR("lrkproxy_hash_table_init(%d) failed!\n", hash_table_size);
610         return -1;
611     } else {
612 //                LM_DBG("lrkproxy_hash_table_init(%d) success!\n", hash_table_size);
613                 LM_INFO(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>lrkproxy_hash_table_init(%d) success!\n", hash_table_size);
614     }
615
616
617
618     /* load tm module*/
619     if (load_tm_api( &tmb ) < 0)
620     {
621                 LM_DBG("could not load the TM-functions - answer-offer model"
622                                " auto-detection is disabled\n");
623         memset(&tmb, 0, sizeof(struct tm_binds));
624     }
625
626     if (custom_sdp_ip_spec.s) {
627         if (pv_parse_spec(&custom_sdp_ip_spec, &custom_sdp_ip_avp) == 0
628             && (custom_sdp_ip_avp.type != PVT_AVP)) {
629                     LM_ERR("malformed or non AVP custom_sdp_ip "
630                                    "AVP definition in '%.*s'\n", custom_sdp_ip_spec.len,custom_sdp_ip_spec.s);
631             return -1;
632         }
633     }
634
635     init_custom_sdp_ip(custom_sdp_ip_spec.s ? &custom_sdp_ip_avp : 0);
636
637
638     return 0;
639 }
640
641
642 static int
643 child_init(int rank)
644 {
645     int n;
646     char *cp;
647     struct addrinfo hints, *res;
648     struct lrkp_set  *lrkp_list;
649     struct lrkp_node *pnode;
650
651     if(lrkp_set_list==NULL )
652         return 0;
653
654     /* do not init sockets for PROC_INIT and main process when fork=yes */
655     if(rank==PROC_INIT || (rank==PROC_MAIN && dont_fork==0)) {
656         return 0;
657     }
658
659     /* Iterate known LRK proxies - create sockets */
660     mypid = getpid();
661
662     lrkp_socks = (int*)pkg_malloc( sizeof(int)*lrkp_no );
663     if (lrkp_socks==NULL) {
664                 LM_ERR("no more pkg memory\n");
665         return -1;
666     }
667     memset(lrkp_socks, -1, sizeof(int)*lrkp_no);
668
669     for(lrkp_list = lrkp_set_list->lset_first; lrkp_list != 0;
670         lrkp_list = lrkp_list->lset_next){
671
672         for (pnode=lrkp_list->ln_first; pnode!=0; pnode = pnode->ln_next){
673             char *hostname;
674
675             if (pnode->ln_umode == 0) {
676                 lrkp_socks[pnode->idx] = -1;
677                 goto rptest;
678             }
679
680             /*
681              * This is UDP or UDP6. Detect host and port; lookup host;
682              * do connect() in order to specify peer address
683              */
684             hostname = (char*)pkg_malloc(sizeof(char) * (strlen(pnode->ln_address) + 1));
685             if (hostname==NULL) {
686                         LM_ERR("no more pkg memory\n");
687                 return -1;
688             }
689             strcpy(hostname, pnode->ln_address);
690
691             cp = strrchr(hostname, ':');
692             if (cp != NULL) {
693                 *cp = '\0';
694                 cp++;
695             }
696             if (cp == NULL || *cp == '\0')
697                 cp = CPORT;
698
699             memset(&hints, 0, sizeof(hints));
700             hints.ai_flags = 0;
701             hints.ai_family = (pnode->ln_umode == 6) ? AF_INET6 : AF_INET;
702             hints.ai_socktype = SOCK_DGRAM;
703             if ((n = getaddrinfo(hostname, cp, &hints, &res)) != 0) {
704                         LM_ERR("%s\n", gai_strerror(n));
705                 pkg_free(hostname);
706                 return -1;
707             }
708             pkg_free(hostname);
709
710             lrkp_socks[pnode->idx] = socket((pnode->ln_umode == 6)
711                                             ? AF_INET6 : AF_INET, SOCK_DGRAM, 0);
712             if ( lrkp_socks[pnode->idx] == -1) {
713                         LM_ERR("can't create socket\n");
714                 freeaddrinfo(res);
715                 return -1;
716             }
717
718             if (connect( lrkp_socks[pnode->idx], res->ai_addr, res->ai_addrlen) == -1) {
719                         LM_ERR("can't connect to a LRK proxy\n");
720                 close( lrkp_socks[pnode->idx] );
721                 lrkp_socks[pnode->idx] = -1;
722                 freeaddrinfo(res);
723                 return -1;
724             }
725             freeaddrinfo(res);
726 rptest:
727             pnode->ln_enable = lrkp_test(pnode);
728             if (pnode->ln_enable) {       //get lrk proxy config if it is enable.
729 //                LM_INFO("lrkp_test test is calling here\n"); //enable next line.
730                 lrkp_get_config(pnode);
731             }
732         }
733     }
734
735     return 0;
736 }
737
738
739 static void mod_destroy(void)
740 {
741     struct lrkp_set * crt_list, * last_list;
742     struct lrkp_node * crt_lrkp, *last_lrkp;
743
744     /*free the shared memory*/
745 //      if (natping_state)
746 //              shm_free(natping_state);
747
748     if(lrkp_set_list == NULL)
749         return;
750
751     for(crt_list = lrkp_set_list->lset_first; crt_list != NULL; ){
752
753         for(crt_lrkp = crt_list->ln_first; crt_lrkp != NULL;  ){
754
755             last_lrkp = crt_lrkp;
756             crt_lrkp = last_lrkp->ln_next;
757             shm_free(last_lrkp);
758         }
759
760         last_list = crt_list;
761         crt_list = last_list->lset_next;
762         shm_free(last_list);
763     }
764
765     shm_free(lrkp_set_list);
766
767     /* destroy the hash table */
768     if (!lrkproxy_hash_table_destroy()) {
769                 LM_ERR("lrkproxy_hash_table_destroy() failed!\n");
770     } else {
771                 LM_DBG("lrkproxy_hash_table_destroy() success!\n");
772     }
773
774 }
775
776
777 static char * gencookie(void)
778 {
779     static char cook[34];
780
781     sprintf(cook, "%d_%u ", (int)mypid, myseqn);
782     myseqn++;
783     return cook;
784 }
785
786 static int lrkp_test(struct lrkp_node *node)
787 {
788     int buflen = 256;
789     char buf[buflen];
790     struct iovec v[2] = {{NULL, 0}, {"P", 1}};
791
792     memset(buf, 0, buflen);
793     memcpy(buf, send_lrkp_command(node, v, 2, 0), buflen);
794
795 //    if (buf == NULL) {
796     if (!buf[0]) {
797         LM_ERR("can't ping the lrk proxy %s, Disable it right now.\n", node->ln_url.s);
798         return 0;
799     }
800
801     char *resp = buf + v[0].iov_len + v[1].iov_len + 1;
802     if (memcmp(resp, "PONG", 4) == 0)
803 //                LM_DBG("Recieve PONG response from lrk proxy server %s, Enable it right now.\n", node->ln_url.s);
804             LM_INFO("Recieve PONG response from lrk proxy server %s, Enable it right now.\n", node->ln_url.s);
805
806     return 1;
807
808 }
809
810 static int lrkp_get_config(struct lrkp_node *node){
811
812     int buflen = 256;
813     char buf[buflen];
814     struct iovec v[2] = {{NULL, 0}, {"G", 1}};
815     struct lrkp_node_conf *lnconf = NULL;
816
817     memset(buf, 0, buflen);
818     memcpy(buf, send_lrkp_command(node, v, 2, 0), buflen);
819
820 //    if (buf == NULL) {
821     if (!buf[0]) {
822         LM_ERR("can't get config of the lrk proxy %s, Disable it right now.\n", node->ln_url.s);
823         return 0;
824     }
825
826     lnconf = (struct lrkp_node_conf *)(buf + v[0].iov_len + v[1].iov_len + 1);
827
828     if (lnconf == NULL){
829         LM_ERR("can't get config of the lrk proxy %s, Disable it right now.\n", node->ln_url.s);
830         return 0;
831     }
832
833
834     memcpy(node->lrkp_n_c, lnconf, sizeof(struct lrkp_node_conf));
835
836 //    node->lrkp_n_c = lnconf;
837     LM_INFO("the lrk proxy %s is configured successfully right now.\n", node->ln_url.s);
838     LM_INFO("buffer internal:%s\n", node->lrkp_n_c->internal_ip);
839     LM_INFO("buffer external:%s\n", node->lrkp_n_c->external_ip);
840     LM_INFO("buffer start_port:%d\n", node->lrkp_n_c->start_port);
841     LM_INFO("buffer end_port:%d\n", node->lrkp_n_c->end_port);
842     LM_INFO("buffer current_port:%d\n", node->lrkp_n_c->current_port);
843
844     return 1;
845
846
847 }
848
849 static int lrkp_set_conntrack_rule(struct lrkproxy_hash_entry *e) {
850     int buflen = 254;
851     char buf[buflen];
852     int v_len = 0;
853
854     char src_ipv4[20];
855     char src_port[20];
856     char dst_ipv4[20];
857     char dst_port[20];
858     char snat_ipv4[20];
859     char snat_port[20];
860     char dnat_ipv4[20];
861     char dnat_port[20];
862     char timeout[20];
863     char callid[50];
864
865     struct iovec v[] = {
866             {NULL, 0},  /* reserved (cookie) */
867             {"S",  1},   /* command & common options */
868             {NULL, 0},  /* src_ipv4 */
869             {NULL, 0},  /* dst_ipnv4 */
870             {NULL, 0},  /* snat_ipv4 */
871             {NULL, 0},  /* dnat_ipv4 */
872             {NULL, 0},  /* src_port */
873             {NULL, 0},  /* dst_port*/
874             {NULL, 0},  /* snat_port */
875             {NULL, 0},  /* dnat_port*/
876             {NULL, 0},  /* timeout to clear conntrack entry*/
877             {NULL, 0},  /* callid of session */
878     };
879
880     v_len += v[1].iov_len;
881
882     //set src_ipv4 to buffer.
883     sprintf(src_ipv4, " %.*s ", e->src_ipv4.len, e->src_ipv4.s);
884     v[2].iov_base = src_ipv4;
885     v[2].iov_len = strlen(v[2].iov_base);
886     v_len += v[2].iov_len;
887
888     //set dst_ipv4 to buffer.
889     sprintf(dst_ipv4, "%.*s ", e->dst_ipv4.len, e->dst_ipv4.s);
890     v[3].iov_base = dst_ipv4;
891     v[3].iov_len = strlen(v[3].iov_base);
892     v_len += v[3].iov_len;
893
894     //set snat_ipv4 to buffer.
895     sprintf(snat_ipv4, "%.*s ", e->snat_ipv4.len, e->snat_ipv4.s);
896     v[4].iov_base = snat_ipv4;
897     v[4].iov_len = strlen(v[4].iov_base);
898     v_len += v[4].iov_len;
899
900     //set dnat_ipv4 to buffer.
901     sprintf(dnat_ipv4, "%.*s ", e->dnat_ipv4.len, e->dnat_ipv4.s);
902     v[5].iov_base = dnat_ipv4;
903     v[5].iov_len = strlen(v[5].iov_base);
904     v_len += v[5].iov_len;
905
906     //set src_port to buffer.
907     sprintf(src_port, "%.*s ", e->src_port.len, e->src_port.s);
908     v[6].iov_base = src_port;
909     v[6].iov_len = strlen(v[6].iov_base);
910     v_len += v[6].iov_len;
911
912     //set dst_port to buffer.
913     sprintf(dst_port, "%.*s ", e->dst_port.len, e->dst_port.s);
914     v[7].iov_base = dst_port;
915     v[7].iov_len = strlen(v[7].iov_base);
916     v_len += v[7].iov_len;
917
918     //set snat_port to buffer.
919     sprintf(snat_port, "%.*s ", e->snat_port.len, e->snat_port.s);
920     v[8].iov_base = snat_port;
921     v[8].iov_len = strlen(v[8].iov_base);
922     v_len += v[8].iov_len;
923
924     //set dnat_port to buffer.
925     sprintf(dnat_port, "%.*s ", e->dnat_port.len, e->dnat_port.s);
926     v[9].iov_base = dnat_port;
927     v[9].iov_len = strlen(v[9].iov_base);
928     v_len += v[9].iov_len;
929
930     //set timeout to buffer. Set to 60 sec for default.
931     sprintf(timeout, "%d ", 60);
932     v[10].iov_base = timeout;
933     v[10].iov_len = strlen(v[10].iov_base);
934     v_len += v[10].iov_len;
935
936     //set callid to buffer.
937     sprintf(callid, "%.*s ", e->callid.len, e->callid.s);
938     v[11].iov_base = callid;
939     v[11].iov_len = strlen(v[11].iov_base);
940     v_len += v[11].iov_len;
941 //    LM_ERR("e->callid.len is:%d right now.\n\n", e->callid.len);
942
943     memset(buf, 0, buflen);
944     memcpy(buf, send_lrkp_command(e->node, v, 12, v_len), buflen);
945 //
946
947 //    if (buf == NULL) {
948     if (!buf[0]) {
949                 LM_ERR("can't ping the lrk proxy %s, Disable it right now.\n", e->node->ln_url.s);
950         return 0;
951     }
952
953     v_len += v[0].iov_len;
954
955
956 //    char *resp = buf + v[0].iov_len + v[1].iov_len + v[2].iov_len;
957     char *resp = buf + v_len;
958     if (memcmp(resp, "OK", 2) == 0) {
959                 LM_INFO("Recieve OK response from lrk proxy server %s, Rule set successfully.\n", e->node->ln_url.s);
960                 LM_DBG("Recieve OK response from lrk proxy server %s, Rule set successfully.\n", e->node->ln_url.s);
961     }
962     return 1;
963
964 }
965
966
967 char *send_lrkp_command(struct lrkp_node *node, struct iovec *v, int vcnt, int more)
968 {
969     struct sockaddr_un addr;
970     int fd, len, i;
971     int ret;
972 //    char *cp;
973     static char buf[256];
974     struct pollfd fds[1];
975
976     memset(buf, 0, 256);
977     len = 0;
978 //    cp = buf;
979     if (node->ln_umode == 0) {
980         memset(&addr, 0, sizeof(addr));
981         addr.sun_family = AF_LOCAL;
982         strncpy(addr.sun_path, node->ln_address,
983                 sizeof(addr.sun_path) - 1);
984 #ifdef HAVE_SOCKADDR_SA_LEN
985         addr.sun_len = strlen(addr.sun_path);
986 #endif
987
988         fd = socket(AF_LOCAL, SOCK_STREAM, 0);
989         if (fd < 0) {
990                     LM_ERR("can't create socket\n");
991             goto badproxy;
992         }
993         if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
994             close(fd);
995                     LM_ERR("can't connect to lrk proxy\n");
996             goto badproxy;
997         }
998
999         do {
1000             len = writev(fd, v + 1, vcnt - 1);
1001         } while (len == -1 && errno == EINTR);
1002         if (len <= 0) {
1003             close(fd);
1004                     LM_ERR("can't send command to a lrk proxy %s\n", node->ln_url.s);
1005             goto badproxy;
1006         }
1007         do {
1008             len = read(fd, buf, sizeof(buf) - 1);
1009         } while (len == -1 && errno == EINTR);
1010         close(fd);
1011         if (len <= 0) {
1012                     LM_ERR("can't read reply from a lrk proxy %s\n", node->ln_url.s);
1013             goto badproxy;
1014         }
1015     } else {
1016         fds[0].fd = lrkp_socks[node->idx];
1017         fds[0].events = POLLIN;
1018         fds[0].revents = 0;
1019         /* Drain input buffer */
1020         ret = -1;
1021         while ((poll(fds, 1, 0) == 1) &&
1022                ((fds[0].revents & POLLIN) != 0) && ret != 0) {
1023             ret = recv(lrkp_socks[node->idx], buf, sizeof(buf) - 1, 0);
1024             fds[0].revents = 0;
1025         }
1026         v[0].iov_base = gencookie();
1027         v[0].iov_len = strlen(v[0].iov_base);
1028         for (i = 0; i < lrkproxy_retr; i++) {
1029             do {
1030                 len = writev(lrkp_socks[node->idx], v, vcnt);
1031             } while (len == -1 && (errno == EINTR || errno == ENOBUFS));
1032             if (len <= 0) {
1033                         LM_ERR("can't send command to a lrk proxy %s\n", node->ln_url.s);
1034                 goto badproxy;
1035             }
1036             while ((poll(fds, 1, lrkproxy_tout * 1000) == 1) &&
1037                    (fds[0].revents & POLLIN) != 0) {
1038                 do {
1039                     len = recv(lrkp_socks[node->idx], buf, sizeof(buf) - 1, 0);
1040                 } while (len == -1 && errno == EINTR);
1041                 if (len <= 0) {
1042                             LM_ERR("can't read reply from a lrk proxy %s\n", node->ln_url.s);
1043                     goto badproxy;
1044                 }
1045                 if (len >= (v[0].iov_len - 1) &&
1046                     memcmp(buf, v[0].iov_base, (v[0].iov_len - 1)) == 0) {      //check coocke validation.
1047                     char *command = buf + v[0].iov_len;
1048                     switch (*command) {
1049                         case 'P':
1050                             if (len == v[0].iov_len + v[1].iov_len + 4 + 1)
1051                                 goto out;
1052 //                            break;
1053                         case 'G':
1054                             if (len == v[0].iov_len + v[1].iov_len + sizeof(struct lrkp_node_conf) + 1)
1055                                 goto out;
1056 //                            break;
1057                         case 'S':
1058                             if (len == more + v[0].iov_len + 2)
1059                                 goto out;
1060 //                            break;
1061                     }
1062
1063                 }
1064                 fds[0].revents = 0;
1065             }
1066         }
1067         if (i == lrkproxy_tout) {
1068                     LM_ERR("timeout waiting reply from a lrk proxy server %s\n", node->ln_url.s);
1069             goto badproxy;
1070
1071         }
1072     }
1073     out:
1074     return buf;
1075     badproxy:
1076             LM_ERR("lrk proxy <%s> does not respond, disable it\n", node->ln_url.s);
1077     node->ln_enable = 0;
1078 //    node->ln_recheck_ticks = get_ticks() + lrkproxy_disable_tout;
1079     return buf;
1080 }
1081
1082 /*
1083  * select the set with the id_set id
1084  */
1085 static struct lrkp_set * select_lrkp_set(int id_set ){
1086
1087     struct lrkp_set * lrkp_list;
1088     /*is it a valid set_id?*/
1089
1090     if(!lrkp_set_list)
1091     {
1092                 LM_ERR("lrkproxy set list not initialised\n");
1093         return NULL;
1094     }
1095
1096     for(lrkp_list=lrkp_set_list->lset_first; lrkp_list!=NULL &&
1097                                              lrkp_list->id_set!=id_set; lrkp_list=lrkp_list->lset_next);
1098
1099     return lrkp_list;
1100 }
1101
1102
1103 struct lrkp_node *select_lrkp_node(int do_test)
1104 {
1105     struct lrkp_node* node;
1106     int was_forced;
1107     int was_forced2;
1108
1109     if(!selected_lrkp_set){
1110         LM_ERR("script error -no valid set selected\n");
1111         return NULL;
1112     }
1113     /* Most popular case: 1 proxy, nothing to calculate */
1114     if (selected_lrkp_set->lrkp_node_count == 1) {
1115         node = selected_lrkp_set->ln_first;
1116 //        if (node->rn_disabled && node->rn_recheck_ticks <= get_ticks())
1117         if (!node->ln_enable) {
1118             node->ln_enable = lrkp_test(node);
1119             if (node->ln_enable) {       //get lrk proxy config if it is enable.
1120                 lrkp_get_config(node);
1121                 return node;
1122             }
1123         }
1124         return node->ln_enable ? node : NULL;
1125 //        return NULL;
1126     }
1127
1128
1129     /* Check node is enable and test it again*/
1130 retry:
1131     for (node=selected_lrkp_set->ln_first; node!=NULL; node=node->ln_next) {
1132
1133         if (!node->ln_enable) {
1134             /* Try to enable if it's time to try. */
1135             node->ln_enable = lrkp_test(node);
1136             if (node->ln_enable)       //get lrk proxy config if it is enable.
1137                 lrkp_get_config(node);
1138         }
1139     }
1140
1141     if (lrkp_algorithm == LRK_LINER) {
1142         was_forced = 0;
1143         retry2:
1144         for (node = selected_lrkp_set->ln_first; node != NULL; node = node->ln_next)
1145             if (node->ln_enable)
1146                 goto found;
1147         if (was_forced)
1148             return NULL;
1149
1150         was_forced = 1;
1151         //trying to enable all lrkproxy and check again.
1152         for (node = selected_lrkp_set->ln_first; node != NULL; node = node->ln_next) {
1153             /* Try to enable if it's time to try. */
1154             node->ln_enable = lrkp_test(node);
1155             if (node->ln_enable)       //get lrk proxy config if it is enable.
1156                 lrkp_get_config(node);
1157         }
1158
1159
1160         goto retry2;
1161     }
1162     else if(lrkp_algorithm == LRK_RR) {
1163         was_forced2 = 0;
1164 retry3:
1165         if (!selected_lrkp_node) {
1166             selected_lrkp_node = selected_lrkp_set->ln_first;
1167             node = selected_lrkp_set->ln_first;
1168             if(node->ln_enable)
1169                     goto found;
1170 //            was_forced2 = 1;
1171         }
1172         for (node = selected_lrkp_node->ln_next; node != NULL; node = node->ln_next)
1173 //        for (node = selected_lrkp_node; node != NULL; node = node->ln_next) {
1174             if (node->ln_enable) {
1175                 selected_lrkp_node = node;
1176                 goto found;
1177             }
1178 //            selected_lrkp_node = node->ln_next;
1179 //        if (sumcut < node->ln_weight)
1180 //        sumcut -= node->ln_weight;
1181
1182         if (was_forced2)
1183             return NULL;
1184
1185         was_forced2 = 1;
1186         selected_lrkp_node = NULL;
1187
1188         goto retry3;
1189     }
1190
1191     found:
1192     if (do_test) {
1193 //    //todo...
1194         node->ln_enable = lrkp_test(node);
1195         if (!node->ln_enable)
1196             goto retry;
1197     }
1198     return node;
1199 }
1200
1201 //static int change_media_sdp(sip_msg_t *msg, struct lrkp_node *n, const char *flags, int type) {
1202 static int change_media_sdp(sip_msg_t *msg, struct lrkproxy_hash_entry *e, const char *flags, enum lrk_operation op) {
1203     struct lump *l;
1204     str body;
1205     str newbody;
1206
1207     int len;
1208     char *start_sdp_o = NULL; //"o=";
1209     char *start_sdp_s = NULL; //"s=";
1210     char *start_sdp_c = NULL; //"c=IN IP4";
1211     char *start_sdp_m = NULL; //"m=audio";
1212     char *ip_selected = NULL;
1213     char *sdp_param_start = NULL;
1214     char *sdp_param_end = NULL;
1215     char *off=NULL;
1216     char sdp_new_o[128];
1217     char sdp_new_s[128];
1218     char sdp_new_c[128];
1219     char sdp_new_m[128];
1220
1221     body.s = get_body(msg);
1222     if (body.s == 0) {
1223                 LM_ERR("failed to get the message body\n");
1224         return -1;
1225     }
1226
1227     body.len = msg->len - (int) (body.s - msg->buf);
1228     if (body.len == 0) {
1229                 LM_DBG("message body has zero length\n");
1230         return -1;
1231     }
1232 //            LM_INFO("body:<%.*s>\n", body.len, body.s);
1233
1234     //allocate new buffer to new sdp buffer.
1235     newbody.len = 1024;
1236     newbody.s = pkg_malloc(newbody.len);
1237     if (newbody.s == NULL) {
1238                 LM_ERR("out of pkg memory\n");
1239         return -1;
1240     }
1241     memset(newbody.s, 0, 1024);
1242
1243     off = body.s;
1244     start_sdp_o = strstr(off, "o=");
1245     start_sdp_s = strstr(off, "s=");
1246     start_sdp_c = strstr(off, "c=IN IP4");
1247     start_sdp_m = strstr(off, "m=audio");
1248
1249     //The external_ip should be set in config file for relaying RTP media between NIC.
1250 //    if (e->node->lrkp_n_c->external_ip && flags) {
1251     if(flags) {
1252         if (strstr(flags, "ei")) {
1253             ip_selected = e->node->lrkp_n_c->internal_ip;// lrk_node->internal_ip;
1254         } else if (strstr(flags, "ie")) {
1255             ip_selected = e->node->lrkp_n_c->external_ip; //lrk_node->external_ip;
1256         } else {
1257             LM_INFO("unknown flags, use internal_ip\n");
1258             ip_selected = e->node->lrkp_n_c->internal_ip;
1259         }
1260     }
1261     else {
1262         LM_INFO("no flags set, use internal_ip\n");
1263         ip_selected = e->node->lrkp_n_c->internal_ip;
1264     }
1265
1266     if (op == OP_OFFER) {
1267         e->dst_ipv4.s = ip_selected;
1268         e->dst_ipv4.len = strlen(e->dst_ipv4.s);
1269
1270         str current_port;
1271         current_port.s = int2str(e->node->lrkp_n_c->current_port, &current_port.len);
1272
1273         if (shm_str_dup(&e->dst_port, &current_port) < 0) {
1274                     LM_ERR("lrkproxy fail to insert dst_port, calllen=%d dst_port=%.*s\n",
1275                            e->callid.len, current_port.len, current_port.s);
1276             lrkproxy_hash_table_free_entry(e);
1277             return 0;
1278         }
1279
1280 //        e->dst_port = e->node->lrkp_n_c->current_port;
1281     }
1282     else if (op == OP_ANSWER){
1283         e->snat_ipv4.s = ip_selected;
1284         e->snat_ipv4.len = strlen(e->snat_ipv4.s);
1285
1286         str current_port;
1287         unsigned int snat_port;
1288
1289         str2int(&e->dst_port, &snat_port);
1290
1291         /*check if gt is enable or not*/
1292         if (!gt)
1293             snat_port += 2;
1294
1295         current_port.s = int2str(snat_port, &current_port.len);
1296
1297         if (shm_str_dup(&e->snat_port, &current_port) < 0) {
1298                     LM_ERR("lrkproxy fail to insert snat_port, calllen=%d snat_port=%.*s\n",
1299                            e->callid.len, current_port.len, current_port.s);
1300             lrkproxy_hash_table_free_entry(e);
1301             return 0;
1302         }
1303
1304 //        e->snat_port = e->dst_port + 2;
1305     }
1306
1307
1308     while (*off != EOB)    //while end of body.
1309     {
1310         sdp_param_start = off;
1311         sdp_param_end = sdp_param_start;
1312         while (*sdp_param_end != CR && *sdp_param_end != LF && *sdp_param_end != EOB) sdp_param_end++;
1313         len = (int) (sdp_param_end - sdp_param_start);
1314         if ((int) (start_sdp_o - off) == 0) {
1315             memset(sdp_new_o, 0, 128);
1316             snprintf(sdp_new_o, 128, "o=lrkproxy %s %s IN IP4 %s\r", SUP_CPROTOVER, REQ_CPROTOVER, ip_selected);
1317             strncat(newbody.s, sdp_new_o, strlen(sdp_new_o));
1318             off += len + 1;
1319             continue;
1320         }
1321         if ((int) (start_sdp_s - off) == 0) {
1322             memset(sdp_new_s, 0, 128);
1323             snprintf(sdp_new_s, 128, "s=lrkproxy Support only Audio Call\r");
1324             strncat(newbody.s, sdp_new_s, strlen(sdp_new_s));
1325             off += len + 1;
1326             continue;
1327         }
1328         if ((int) (start_sdp_c - off) == 0) {
1329             memset(sdp_new_c, 0, 128);
1330             snprintf(sdp_new_c, 128, "c=IN IP4 %s\r", ip_selected);
1331             strncat(newbody.s, sdp_new_c, strlen(sdp_new_c));
1332             off += len + 1;
1333             continue;
1334         }
1335         if ((int)(start_sdp_m - off) == 0){
1336             memset(sdp_new_m, 0, 128);
1337             char *avp_flags = off;
1338 //            int occure = 0;
1339             for (;*avp_flags && !isspace(*avp_flags); avp_flags++);
1340             for (avp_flags++;*avp_flags && !isspace(*avp_flags); avp_flags++);
1341             avp_flags++;
1342             if (op == OP_OFFER)
1343                 snprintf(sdp_new_m, 128, "m=audio %.*s %.*s\r",e->dst_port.len, e->dst_port.s, (int)(len - (avp_flags-off)), avp_flags);
1344 //                snprintf(sdp_new_m, 128, "m=audio %d %.*s\r",e->node->lrkp_n_c->current_port, (int)(len - (avp_flags-off)), avp_flags);
1345             else if (op == OP_ANSWER)
1346                 snprintf(sdp_new_m, 128, "m=audio %.*s %.*s\r",e->snat_port.len, e->snat_port.s, (int)(len - (avp_flags-off)), avp_flags);
1347 //               snprintf(sdp_new_m, 128, "m=audio %d %.*s\r",e->node->lrkp_n_c->current_port, (int)(len - (avp_flags-off)), avp_flags);
1348 //            printf("%.*s\n\n", len - (avp_flags-off), avp_flags);
1349             strncat(newbody.s,sdp_new_m, strlen(sdp_new_m));
1350             off += len+1;
1351             continue;
1352         }
1353
1354         strncat(newbody.s, off, len + 1);
1355         off += len + 1;
1356     }
1357
1358
1359 //    LM_INFO("%.*s", (int)strlen(newbody.s), newbody.s);
1360     l = del_lump(msg, body.s - msg->buf, body.len, 0);
1361     if (!l) {
1362                 LM_ERR("del_lump failed\n");
1363         return -1;
1364     }
1365
1366
1367     if (insert_new_lump_after(l, newbody.s, strlen(newbody.s), 0) == 0) {
1368                 LM_ERR("could not insert new lump\n");
1369         pkg_free(newbody.s);
1370         return -1;
1371     }
1372
1373             LM_BUG("Insert_new_lump successfully\n");
1374
1375     return 1;
1376 }
1377
1378 /* This function assumes p points to a line of requested type. */
1379
1380         static int
1381 set_lrkproxy_set_f(struct sip_msg * msg, char * str1, char * str2)
1382 {
1383         lrkp_set_link_t *lrkl;
1384         pv_value_t val;
1385
1386         lrkl = (lrkp_set_link_t*)str1;
1387
1388         current_msg_id = 0;
1389         selected_lrkp_set = 0;
1390
1391         if(lrkl->rset != NULL) {
1392                 current_msg_id = msg->id;
1393                 selected_lrkp_set = lrkl->rset;
1394         } else {
1395                 if(pv_get_spec_value(msg, lrkl->rpv, &val)<0) {
1396                         LM_ERR("cannot evaluate pv param\n");
1397                         return -1;
1398                 }
1399                 if(!(val.flags & PV_VAL_INT)) {
1400                         LM_ERR("pv param must hold an integer value\n");
1401                         return -1;
1402                 }
1403                 selected_lrkp_set = select_lrkp_set(val.ri);
1404                 if(selected_lrkp_set==NULL) {
1405                         LM_ERR("could not locate lrkproxy set %d\n", val.ri);
1406                         return -1;
1407                 }
1408                 current_msg_id = msg->id;
1409         }
1410         return 1;
1411 }
1412
1413 static int
1414 lrkproxy_manage(struct sip_msg *msg, char *flags, char *ip)
1415 {
1416     int method;
1417     int nosdp;
1418     tm_cell_t *t = NULL;
1419
1420     if (msg->cseq==NULL && ((parse_headers(msg, HDR_CSEQ_F, 0)==-1) ||
1421                             (msg->cseq==NULL)))
1422     {
1423                 LM_ERR("no CSEQ header\n");
1424         return -1;
1425     }
1426
1427     method = get_cseq(msg)->method_id;
1428
1429     if (!(method==METHOD_INVITE || method==METHOD_ACK || method==METHOD_CANCEL
1430           || method==METHOD_BYE || method==METHOD_UPDATE))
1431         return -1;
1432
1433     if (method==METHOD_CANCEL || method==METHOD_BYE)
1434         return lrkproxy_unforce(msg, flags, OP_DELETE, 1);
1435
1436     if (msg->msg_flags & FL_SDP_BODY)
1437         nosdp = 0;
1438     else
1439         nosdp = parse_sdp(msg);
1440
1441     if (msg->first_line.type == SIP_REQUEST) {
1442         if(method==METHOD_ACK && nosdp==0)
1443             return lrkproxy_force(msg, flags, OP_ANSWER, 1);
1444         if(method==METHOD_UPDATE && nosdp==0)
1445             return lrkproxy_force(msg, flags, OP_OFFER, 1);
1446         if(method==METHOD_INVITE && nosdp==0) {
1447             msg->msg_flags |= FL_SDP_BODY;
1448             if(tmb.t_gett!=NULL) {
1449                 t = tmb.t_gett();
1450                 if(t!=NULL && t!=T_UNDEFINED && t->uas.request!=NULL) {
1451                     t->uas.request->msg_flags |= FL_SDP_BODY;
1452                 }
1453             }
1454             if(route_type==FAILURE_ROUTE)
1455                 return lrkproxy_unforce(msg, flags, OP_DELETE, 1);
1456             return lrkproxy_force(msg, flags, OP_OFFER, 1);
1457         }
1458     } else if (msg->first_line.type == SIP_REPLY) {
1459         if (msg->first_line.u.reply.statuscode>=300)
1460             return lrkproxy_unforce(msg, flags, OP_DELETE, 2);
1461         if (nosdp==0) {
1462             if (method==METHOD_UPDATE)
1463                 return lrkproxy_force(msg, flags, OP_ANSWER, 2);
1464             if (tmb.t_gett==NULL || tmb.t_gett()==NULL
1465                 || tmb.t_gett()==T_UNDEFINED)
1466                 return lrkproxy_force(msg, flags, OP_ANSWER, 2);
1467             if (tmb.t_gett()->uas.request->msg_flags & FL_SDP_BODY)
1468                 return lrkproxy_force(msg, flags, OP_ANSWER, 2);
1469             return lrkproxy_force(msg, flags, OP_OFFER, 2);
1470         }
1471     }
1472
1473     return -1;
1474 }
1475
1476 static int
1477 lrkproxy_manage0(struct sip_msg *msg, char *flags, char *ip)
1478 {
1479     return lrkproxy_manage(msg, 0, 0);
1480 }
1481
1482 static int
1483 lrkproxy_manage1(struct sip_msg *msg, char *flags, char *ip)
1484 {
1485     str flag_str;
1486     if(fixup_get_svalue(msg, (gparam_p)flags, &flag_str)<0)
1487     {
1488                 LM_ERR("invalid flags parameter\n");
1489         return -1;
1490     }
1491     return lrkproxy_manage(msg, flag_str.s, 0);
1492 }
1493
1494 static int
1495 lrkproxy_manage2(struct sip_msg *msg, char *flags, char *ip)
1496 {
1497     str flag_str;
1498     str ip_str;
1499     if(fixup_get_svalue(msg, (gparam_p)flags, &flag_str)<0)
1500     {
1501                 LM_ERR("invalid flags parameter\n");
1502         return -1;
1503     }
1504     if(fixup_get_svalue(msg, (gparam_p)ip, &ip_str)<0)
1505     {
1506                 LM_ERR("invalid IP parameter\n");
1507         return -1;
1508     }
1509     return lrkproxy_manage(msg, flag_str.s, ip_str.s);
1510 }
1511
1512
1513 static int lrkproxy_force(struct sip_msg *msg, const char *flags, enum lrk_operation op, int more) {
1514
1515 //    lrk_sdp_info_t lrk_sdp_info;
1516     struct lrkproxy_hash_entry *entry = NULL;
1517     str viabranch = STR_NULL;
1518     str call_id;
1519     int via_id;
1520
1521     if (get_callid(msg, &call_id) == -1) {
1522                 LM_ERR("can't get Call-Id field\n");
1523         return -1;
1524     }
1525
1526     /*We have to choice VIA id,
1527      * for SIP_REQUEST we use VIA1 and for SIP_REPLY we use VIA2 */
1528     via_id = more;
1529
1530     if (get_via_branch(msg, via_id, &viabranch) == -1) {
1531                 LM_ERR("can't get Call-Id field\n");
1532         return -1;
1533     }
1534
1535     if (op == OP_OFFER) {
1536                 LM_INFO ("Here is SIP_REQUEST &  METHOD_INVITE\n");
1537         int more_test = 1;
1538
1539         //select new node based on lrkp_algorithm param.
1540         struct lrkp_node *node = select_lrkp_node(more_test);
1541         if (!node) {
1542                     LM_ERR("can't ping any lrk proxy right now.\n");
1543             return -1;
1544         }
1545
1546                 LM_DBG("selected lrk proxy node: %s\n", node->ln_url.s);
1547
1548         //check if entry not exist.
1549         entry = lrkproxy_hash_table_lookup(call_id, viabranch);
1550         if (entry)
1551             return -1;
1552
1553 //        lrk_get_sdp_info(msg, &lrk_sdp_info);
1554
1555         //build new entry for hash table.
1556 //            struct lrkproxy_hash_entry *entry = shm_malloc(sizeof(struct lrkproxy_hash_entry));
1557         entry = shm_malloc(sizeof(struct lrkproxy_hash_entry));
1558         if (!entry) {
1559                     LM_ERR("lrkproxy hash table fail to create entry for calllen=%d callid=%.*s viabranch=%.*s\n",
1560                            call_id.len, call_id.len, call_id.s,
1561                            viabranch.len, viabranch.s);
1562             return 0;
1563         }
1564         memset(entry, 0, sizeof(struct lrkproxy_hash_entry));
1565
1566         // fill the entry
1567         if (call_id.s && call_id.len > 0) {
1568             if (shm_str_dup(&entry->callid, &call_id) < 0) {
1569                         LM_ERR("lrkproxy hash table fail to instert call_id, calllen=%d callid=%.*s\n",
1570                                call_id.len, call_id.len, call_id.s);
1571                 lrkproxy_hash_table_free_entry(entry);
1572                 return 0;
1573             }
1574         }
1575
1576         if (viabranch.s && viabranch.len > 0) {
1577             if (shm_str_dup(&entry->viabranch, &viabranch) < 0) {
1578                         LM_ERR("lrkproxy hash table fail to insert viabranch, calllen=%d viabranch=%.*s\n",
1579                                call_id.len, viabranch.len, viabranch.s);
1580                 lrkproxy_hash_table_free_entry(entry);
1581                 return 0;
1582             }
1583         }
1584
1585         //fill src_ipv4 and src_port for entry.
1586         str src_ipv4;
1587
1588         if (get_sdp_ipaddr_media(msg, &src_ipv4) == -1) {
1589                     LM_ERR("can't get media src_ipv4 from sdp field\n");
1590             return -1;
1591         }
1592
1593         if (src_ipv4.s && src_ipv4.len > 0) {
1594                     LM_DBG("src_ipv4 from sdp:%.*s\n", src_ipv4.len, src_ipv4.s);
1595             if (shm_str_dup(&entry->src_ipv4, &src_ipv4) < 0) {
1596                         LM_ERR("lrkproxy hash table fail to insert src_ipv4, calllen=%d src_ipv4=%.*s\n",
1597                                call_id.len, src_ipv4.len, src_ipv4.s);
1598                 lrkproxy_hash_table_free_entry(entry);
1599                 return 0;
1600             }
1601         }
1602
1603         str src_port;
1604         if (get_sdp_port_media(msg, &src_port) == -1) {
1605                     LM_ERR("can't get media src_port from sdp field\n");
1606             return -1;
1607         }
1608
1609
1610         if (src_port.s && src_port.len > 0) {
1611                     LM_DBG("src_port from sdp:%.*s\n", src_port.len, src_port.s);
1612             if (shm_str_dup(&entry->src_port, &src_port) < 0) {
1613                         LM_ERR("lrkproxy hash table fail to insert src_port, calllen=%d src_port=%.*s\n",
1614                                call_id.len, src_port.len, src_port.s);
1615                 lrkproxy_hash_table_free_entry(entry);
1616                 return 0;
1617             }
1618         }
1619
1620 //            entry->
1621         entry->node = node;
1622         entry->next = NULL;
1623         entry->tout = get_ticks() + hash_table_tout;
1624
1625         // insert the key<->entry from the hashtable
1626         if (!lrkproxy_hash_table_insert(call_id, viabranch, entry)) {
1627                     LM_ERR(
1628                     "lrkproxy hash table fail to insert node=%.*s for calllen=%d callid=%.*s viabranch=%.*s\n",
1629                     node->ln_url.len, node->ln_url.s, call_id.len,
1630                     call_id.len, call_id.s, viabranch.len, viabranch.s);
1631             lrkproxy_hash_table_free_entry(entry);
1632             return 0;
1633         } else {
1634                     LM_INFO("lrkproxy hash table insert node=%.*s for calllen=%d callid=%.*s viabranch=%.*s\n",
1635                             node->ln_url.len, node->ln_url.s, call_id.len,
1636                             call_id.len, call_id.s, viabranch.len, viabranch.s);
1637
1638                     LM_DBG("lrkproxy hash table insert node=%.*s for calllen=%d callid=%.*s viabranch=%.*s\n",
1639                            node->ln_url.len, node->ln_url.s, call_id.len,
1640                            call_id.len, call_id.s, viabranch.len, viabranch.s);
1641         }
1642
1643
1644         if (flags)
1645             change_media_sdp(msg, entry, flags, op);
1646         else
1647             change_media_sdp(msg, entry, NULL, op);
1648
1649         if (node->lrkp_n_c->current_port >= node->lrkp_n_c->end_port)
1650             node->lrkp_n_c->current_port = node->lrkp_n_c->start_port;
1651         else {
1652             if (gt)
1653                 node->lrkp_n_c->current_port += 2;
1654             else
1655                 node->lrkp_n_c->current_port += 4;
1656         }
1657     } else if (op == OP_ANSWER) {
1658                 LM_INFO ("Here is SIP_REPLY of METHOD_INVITE\n");
1659
1660
1661         entry = lrkproxy_hash_table_lookup(call_id, viabranch);
1662         if (!entry){
1663                     LM_ERR("No found entry in hash table\n");
1664                     //todo...
1665             return 0;
1666         }
1667
1668         //fill other data for entry
1669         str dnat_ipv4;
1670         if (get_sdp_ipaddr_media(msg, &dnat_ipv4) == -1) {
1671                     LM_ERR("can't get media dnat_ipv4 from sdp field\n");
1672             return -1;
1673         }
1674
1675         if(dnat_ipv4.s && dnat_ipv4.len > 0) {
1676                     LM_DBG("dnat_ipv4 from sdp:%.*s\n", dnat_ipv4.len, dnat_ipv4.s);
1677             if (shm_str_dup(&entry->dnat_ipv4, &dnat_ipv4) < 0) {
1678                         LM_ERR("lrkproxy hash table fail to insert dnat_ipv4, calllen=%d dnat_ipv4=%.*s\n",
1679                                call_id.len, dnat_ipv4.len, dnat_ipv4.s);
1680                 lrkproxy_hash_table_free_entry(entry);
1681                 return 0;
1682             }
1683         }
1684
1685         str dnat_port;
1686         if (get_sdp_port_media(msg, &dnat_port) == -1) {
1687                     LM_ERR("can't get media port from sdp field\n");
1688             return -1;
1689         }
1690
1691
1692         if(dnat_port.s && dnat_port.len > 0) {
1693                     LM_DBG("port from sdp:%.*s\n", dnat_port.len, dnat_port.s);
1694             if (shm_str_dup(&entry->dnat_port, &dnat_port) < 0) {
1695                         LM_ERR("lrkproxy hash table fail to insert dnat_port, calllen=%d dnat_port=%.*s\n",
1696                                call_id.len, dnat_port.len, dnat_port.s);
1697                 lrkproxy_hash_table_free_entry(entry);
1698                 return 0;
1699             }
1700         }
1701
1702
1703         if (flags)
1704             change_media_sdp(msg, entry, flags, op);
1705         else
1706             change_media_sdp(msg, entry, NULL, op);
1707
1708
1709         LM_INFO("selected node: %s\n",entry->node->ln_url.s);
1710         LM_INFO("call_is: %.*s\n",entry->callid.len, entry->callid.s);
1711         LM_INFO("viabranch: %.*s\n",entry->viabranch.len, entry->viabranch.s);
1712         LM_INFO("src_ipv4: %.*s\n",entry->src_ipv4.len, entry->src_ipv4.s);
1713         LM_INFO("src_port: %.*s\n",entry->src_port.len, entry->src_port.s);
1714         LM_INFO("dst_ipv4: %.*s\n",entry->dst_ipv4.len, entry->dst_ipv4.s);
1715         LM_INFO("dst_port: %.*s\n",entry->dst_port.len, entry->dst_port.s);
1716
1717         LM_INFO("dnat_ipv4: %.*s\n",entry->dnat_ipv4.len, entry->dnat_ipv4.s);
1718         LM_INFO("dnat_port: %.*s\n",entry->dnat_port.len, entry->dnat_port.s);
1719         LM_INFO("snat_ipv4: %.*s\n",entry->snat_ipv4.len, entry->snat_ipv4.s);
1720         LM_INFO("snat_port: %.*s\n",entry->snat_port.len, entry->snat_port.s);
1721
1722
1723         lrkp_set_conntrack_rule(entry);
1724
1725     }
1726     return 1;
1727 }
1728
1729 static int lrkproxy_unforce(struct sip_msg *msg, const char *flags, enum lrk_operation op, int more){
1730 //            LM_INFO ("Here is lrkproxy_unforce\n");
1731 //    struct lrkproxy_hash_entry *entry = NULL;
1732     str viabranch = STR_NULL;
1733     str call_id;
1734     int via_id;
1735
1736     if (get_callid(msg, &call_id) == -1) {
1737                 LM_ERR("can't get Call-Id field\n");
1738         return -1;
1739     }
1740
1741     /*We have to choice VIA id,
1742      * for SIP_REQUEST we use VIA1 and for SIP_REPLY we use VIA2 */
1743     via_id = more;
1744
1745     if (get_via_branch(msg, via_id, &viabranch) == -1) {
1746                 LM_ERR("can't get Call-Id field\n");
1747         return -1;
1748     }
1749
1750     if (op == OP_DELETE) {
1751         /* Delete the key<->value from the hashtable */
1752         if (!lrkproxy_hash_table_remove(call_id, viabranch, op)) {
1753                     LM_ERR("lrkproxy hash table failed to remove entry for callen=%d callid=%.*s viabranch=%.*s\n",
1754                            call_id.len, call_id.len, call_id.s,
1755                            viabranch.len, viabranch.s);
1756         } else {
1757                     LM_DBG("lrkproxy hash table remove entry for callen=%d callid=%.*s viabranch=%.*s\n",
1758                            call_id.len, call_id.len, call_id.s,
1759                            viabranch.len, viabranch.s);
1760         }
1761     }
1762     LM_INFO("lrkproxy hash table remove entry for callen=%d callid=%.*s viabranch=%.*s successfully\n",
1763             call_id.len, call_id.len, call_id.s,
1764             viabranch.len, viabranch.s);
1765     return 1;
1766 }