00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166 #include <sys/types.h>
00167 #include <sys/socket.h>
00168 #include <sys/time.h>
00169 #include <netinet/in.h>
00170 #include <netinet/in_systm.h>
00171 #ifndef __USE_BSD
00172 #define __USE_BSD
00173 #endif
00174 #include <netinet/ip.h>
00175 #ifndef __FAVOR_BSD
00176 #define __FAVOR_BSD
00177 #endif
00178 #include <netinet/udp.h>
00179 #include <arpa/inet.h>
00180 #include <sys/uio.h>
00181 #include <sys/un.h>
00182 #include <ctype.h>
00183 #include <errno.h>
00184 #include <netdb.h>
00185 #include <poll.h>
00186 #include <stdio.h>
00187 #include <stdlib.h>
00188 #include <string.h>
00189 #include <unistd.h>
00190
00191 #include "../../flags.h"
00192 #include "../../sr_module.h"
00193 #include "../../dprint.h"
00194 #include "../../data_lump.h"
00195 #include "../../data_lump_rpl.h"
00196 #include "../../error.h"
00197 #include "../../forward.h"
00198 #include "../../mem/mem.h"
00199 #include "../../parser/parse_from.h"
00200 #include "../../parser/parse_to.h"
00201 #include "../../parser/parse_uri.h"
00202 #include "../../parser/parser_f.h"
00203 #include "../../resolve.h"
00204 #include "../../timer.h"
00205 #include "../../trim.h"
00206 #include "../../ut.h"
00207 #include "../../mi/attr.h"
00208 #include "../../pvar.h"
00209 #include "../../msg_translator.h"
00210 #include "../../usr_avp.h"
00211 #include "../../socket_info.h"
00212 #include "../../mod_fix.h"
00213 #include "../registrar/sip_msg.h"
00214 #include "../usrloc/usrloc.h"
00215 #include "nathelper.h"
00216 #include "nhelpr_funcs.h"
00217 #include "sip_pinger.h"
00218 #include "rtpproxy_stream.h"
00219
00220 MODULE_VERSION
00221
00222 #if !defined(AF_LOCAL)
00223 #define AF_LOCAL AF_UNIX
00224 #endif
00225 #if !defined(PF_LOCAL)
00226 #define PF_LOCAL PF_UNIX
00227 #endif
00228
00229
00230 #define NAT_UAC_TEST_C_1918 0x01
00231 #define NAT_UAC_TEST_RCVD 0x02
00232 #define NAT_UAC_TEST_V_1918 0x04
00233 #define NAT_UAC_TEST_S_1918 0x08
00234 #define NAT_UAC_TEST_RPORT 0x10
00235
00236
00237 #define DEFAULT_RTPP_SET_ID 0
00238
00239 #define MI_SET_NATPING_STATE "nh_enable_ping"
00240 #define MI_DEFAULT_NATPING_STATE 1
00241
00242 #define MI_ENABLE_RTP_PROXY "nh_enable_rtpp"
00243 #define MI_MIN_RECHECK_TICKS 0
00244 #define MI_MAX_RECHECK_TICKS (unsigned int)-1
00245
00246 #define MI_SHOW_RTP_PROXIES "nh_show_rtpp"
00247
00248 #define MI_RTP_PROXY_NOT_FOUND "RTP proxy not found"
00249 #define MI_RTP_PROXY_NOT_FOUND_LEN (sizeof(MI_RTP_PROXY_NOT_FOUND)-1)
00250 #define MI_PING_DISABLED "NATping disabled from script"
00251 #define MI_PING_DISABLED_LEN (sizeof(MI_PING_DISABLED)-1)
00252 #define MI_SET "set"
00253 #define MI_SET_LEN (sizeof(MI_SET)-1)
00254 #define MI_INDEX "index"
00255 #define MI_INDEX_LEN (sizeof(MI_INDEX)-1)
00256 #define MI_DISABLED "disabled"
00257 #define MI_DISABLED_LEN (sizeof(MI_DISABLED)-1)
00258 #define MI_WEIGHT "weight"
00259 #define MI_WEIGHT_LEN (sizeof(MI_WEIGHT)-1)
00260 #define MI_RECHECK_TICKS "recheck_ticks"
00261 #define MI_RECHECK_T_LEN (sizeof(MI_RECHECK_TICKS)-1)
00262
00263
00264
00265
00266 #define SUP_CPROTOVER 20040107
00267
00268 #define REQ_CPROTOVER "20050322"
00269
00270 #define REP_CPROTOVER "20071116"
00271 #define PTL_CPROTOVER "20081102"
00272
00273 #define CPORT "22222"
00274 static int nat_uac_test_f(struct sip_msg* msg, char* str1, char* str2);
00275 static int fix_nated_contact_f(struct sip_msg *, char *, char *);
00276 static int fix_nated_sdp_f(struct sip_msg *, char *, char *);
00277 static int extract_mediaip(str *, str *, int *, char *);
00278 static int extract_mediainfo(str *, str *, str *);
00279 static int extract_rtcp(str *body, str *rtcpport);
00280 static int alter_mediaip(struct sip_msg *, str *, str *, int, str *, int, int);
00281 static int alter_mediaport(struct sip_msg *, str *, str *, str *, int);
00282 static int alter_rtcp(struct sip_msg *msg, str *body, str *oldport, str *newport);
00283 static char *gencookie();
00284 static int rtpp_test(struct rtpp_node*, int, int);
00285 static int unforce_rtp_proxy_f(struct sip_msg *, char *, char *);
00286 static int force_rtp_proxy0_f(struct sip_msg *, char *, char *);
00287 static int force_rtp_proxy1_f(struct sip_msg *, char *, char *);
00288 static int force_rtp_proxy2_f(struct sip_msg *, char *, char *);
00289 static int force_rtp_proxy(struct sip_msg *, char *, char *, int);
00290 static int fix_nated_register_f(struct sip_msg *, char *, char *);
00291 static int fixup_fix_nated_register(void** param, int param_no);
00292 static int fixup_fix_sdp(void** param, int param_no);
00293 static int add_rcv_param_f(struct sip_msg *, char *, char *);
00294 static int start_recording_f(struct sip_msg *, char *, char *);
00295 static int rtpproxy_answer1_f(struct sip_msg *, char *, char *);
00296 static int rtpproxy_answer2_f(struct sip_msg *, char *, char *);
00297 static int rtpproxy_offer1_f(struct sip_msg *, char *, char *);
00298 static int rtpproxy_offer2_f(struct sip_msg *, char *, char *);
00299
00300 static char *find_sdp_line(char *, char *, char);
00301 static char *find_next_sdp_line(char *, char *, char, char *);
00302
00303 static int add_rtpproxy_socks(struct rtpp_set * rtpp_list, char * rtpproxy);
00304 static int fixup_set_id(void ** param, int param_no);
00305 static int set_rtp_proxy_set_f(struct sip_msg * msg, char * str1, char * str2);
00306 static struct rtpp_set * select_rtpp_set(int id_set);
00307
00308 static int rtpproxy_set_store(modparam_t type, void * val);
00309 static int nathelper_add_rtpproxy_set( char * rtp_proxies);
00310
00311 static void nh_timer(unsigned int, void *);
00312 static int mod_init(void);
00313 static int child_init(int);
00314 static void mod_destroy(void);
00315
00316
00317 static struct mi_root* mi_enable_natping(struct mi_root* cmd_tree,
00318 void* param );
00319 static struct mi_root* mi_enable_rtp_proxy(struct mi_root* cmd_tree,
00320 void* param );
00321 static struct mi_root* mi_show_rtpproxies(struct mi_root* cmd_tree,
00322 void* param);
00323
00324
00325 static usrloc_api_t ul;
00326
00327 static int cblen = 0;
00328 static int natping_interval = 0;
00329 struct socket_info* force_socket = 0;
00330
00331
00332 static struct {
00333 const char *cnetaddr;
00334 uint32_t netaddr;
00335 uint32_t mask;
00336 } nets_1918[] = {
00337 {"10.0.0.0", 0, 0xffffffffu << 24},
00338 {"172.16.0.0", 0, 0xffffffffu << 20},
00339 {"192.168.0.0", 0, 0xffffffffu << 16},
00340 {NULL, 0, 0}
00341 };
00342
00343 static struct {
00344 const char *s;
00345 int len;
00346 int is_rtp;
00347 } sup_ptypes[] = {
00348 {.s = "udp", .len = 3, .is_rtp = 0},
00349 {.s = "udptl", .len = 5, .is_rtp = 0},
00350 {.s = "rtp/avp", .len = 7, .is_rtp = 1},
00351 {.s = "rtp/avpf", .len = 8, .is_rtp = 1},
00352 {.s = "rtp/savp", .len = 8, .is_rtp = 1},
00353 {.s = "rtp/savpf", .len = 9, .is_rtp = 1},
00354 {.s = "udp/bfcp", .len = 8, .is_rtp = 0},
00355 {.s = NULL, .len = 0, .is_rtp = 0}
00356 };
00357
00358
00359
00360
00361
00362 static int ping_nated_only = 0;
00363 static const char sbuf[4] = {0, 0, 0, 0};
00364 static char *force_socket_str = 0;
00365 static int rtpproxy_disable_tout = 60;
00366 static int rtpproxy_retr = 5;
00367 static int rtpproxy_tout = 1;
00368 static pid_t mypid;
00369 static unsigned int myseqn = 0;
00370 static str nortpproxy_str = str_init("a=nortpproxy:yes");
00371 static int sipping_flag = -1;
00372 static int natping_processes = 1;
00373
00374 static char* rcv_avp_param = NULL;
00375 static unsigned short rcv_avp_type = 0;
00376 static int_str rcv_avp_name;
00377
00378 static char *natping_socket = 0;
00379 static int raw_sock = -1;
00380 static unsigned int raw_ip = 0;
00381 static unsigned short raw_port = 0;
00382
00383
00384 static char ** rtpp_strings=0;
00385 static int rtpp_sets=0;
00386 static int rtpp_set_count = 0;
00387 static unsigned int current_msg_id = (unsigned int)-1;
00388
00389 struct rtpp_set_head * rtpp_set_list =0;
00390 struct rtpp_set * selected_rtpp_set =0;
00391 struct rtpp_set * default_rtpp_set=0;
00392
00393
00394 static unsigned int rtpp_no = 0;
00395 static int *rtpp_socks = 0;
00396
00397
00398
00399 unsigned int *natping_state=0;
00400
00401 static cmd_export_t cmds[] = {
00402 {"fix_nated_contact", (cmd_function)fix_nated_contact_f, 0,
00403 0, 0,
00404 REQUEST_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00405 {"fix_nated_sdp", (cmd_function)fix_nated_sdp_f, 1,
00406 fixup_fix_sdp, 0,
00407 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00408 {"fix_nated_sdp", (cmd_function)fix_nated_sdp_f, 2,
00409 fixup_fix_sdp, 0,
00410 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00411 {"set_rtp_proxy_set", (cmd_function)set_rtp_proxy_set_f, 1,
00412 fixup_set_id, 0,
00413 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00414 {"unforce_rtp_proxy", (cmd_function)unforce_rtp_proxy_f, 0,
00415 0, 0,
00416 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00417 {"force_rtp_proxy", (cmd_function)force_rtp_proxy0_f, 0,
00418 0, 0,
00419 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00420 {"force_rtp_proxy", (cmd_function)force_rtp_proxy1_f, 1,
00421 0, 0,
00422 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00423 {"force_rtp_proxy", (cmd_function)force_rtp_proxy2_f, 2,
00424 0, 0,
00425 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00426 {"nat_uac_test", (cmd_function)nat_uac_test_f, 1,
00427 fixup_uint_null, 0,
00428 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00429 {"fix_nated_register", (cmd_function)fix_nated_register_f, 0,
00430 fixup_fix_nated_register, 0,
00431 REQUEST_ROUTE },
00432 {"add_rcv_param", (cmd_function)add_rcv_param_f, 0,
00433 0, 0,
00434 REQUEST_ROUTE },
00435 {"add_rcv_param", (cmd_function)add_rcv_param_f, 1,
00436 fixup_uint_null, 0,
00437 REQUEST_ROUTE },
00438 {"start_recording", (cmd_function)start_recording_f, 0,
00439 0, 0,
00440 REQUEST_ROUTE | ONREPLY_ROUTE },
00441 {"rtpproxy_offer", (cmd_function)rtpproxy_offer1_f, 0,
00442 0, 0,
00443 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00444 {"rtpproxy_offer", (cmd_function)rtpproxy_offer1_f, 1,
00445 0, 0,
00446 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00447 {"rtpproxy_offer", (cmd_function)rtpproxy_offer2_f, 2,
00448 0, 0,
00449 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00450 {"rtpproxy_answer", (cmd_function)rtpproxy_answer1_f, 0,
00451 0, 0,
00452 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00453 {"rtpproxy_answer", (cmd_function)rtpproxy_answer1_f, 1,
00454 0, 0,
00455 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00456 {"rtpproxy_answer", (cmd_function)rtpproxy_answer2_f, 2,
00457 0, 0,
00458 REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
00459 {"rtpproxy_stream2uac",(cmd_function)rtpproxy_stream2uac2_f, 2,
00460 fixup_var_str_int, 0,
00461 REQUEST_ROUTE | ONREPLY_ROUTE },
00462 {"rtpproxy_stream2uas",(cmd_function)rtpproxy_stream2uas2_f, 2,
00463 fixup_var_str_int, 0,
00464 REQUEST_ROUTE | ONREPLY_ROUTE },
00465 {"rtpproxy_stop_stream2uac",(cmd_function)rtpproxy_stop_stream2uac2_f,0,
00466 NULL, 0,
00467 REQUEST_ROUTE | ONREPLY_ROUTE },
00468 {"rtpproxy_stop_stream2uas",(cmd_function)rtpproxy_stop_stream2uas2_f,0,
00469 NULL, 0,
00470 REQUEST_ROUTE | ONREPLY_ROUTE },
00471 {0, 0, 0, 0, 0, 0}
00472 };
00473
00474 static param_export_t params[] = {
00475 {"natping_interval", INT_PARAM, &natping_interval },
00476 {"ping_nated_only", INT_PARAM, &ping_nated_only },
00477 {"nortpproxy_str", STR_PARAM, &nortpproxy_str.s },
00478 {"rtpproxy_sock", STR_PARAM|USE_FUNC_PARAM,
00479 (void*)rtpproxy_set_store },
00480 {"rtpproxy_disable_tout", INT_PARAM, &rtpproxy_disable_tout },
00481 {"rtpproxy_retr", INT_PARAM, &rtpproxy_retr },
00482 {"rtpproxy_tout", INT_PARAM, &rtpproxy_tout },
00483 {"received_avp", STR_PARAM, &rcv_avp_param },
00484 {"force_socket", STR_PARAM, &force_socket_str },
00485 {"sipping_from", STR_PARAM, &sipping_from.s },
00486 {"sipping_method", STR_PARAM, &sipping_method.s },
00487 {"sipping_bflag", INT_PARAM, &sipping_flag },
00488 {"natping_processes", INT_PARAM, &natping_processes },
00489 {"natping_socket", STR_PARAM, &natping_socket },
00490 {0, 0, 0}
00491 };
00492
00493 static mi_export_t mi_cmds[] = {
00494 {MI_SET_NATPING_STATE, mi_enable_natping, 0, 0, 0},
00495 {MI_ENABLE_RTP_PROXY, mi_enable_rtp_proxy, 0, 0, 0},
00496 {MI_SHOW_RTP_PROXIES, mi_show_rtpproxies, MI_NO_INPUT_FLAG, 0, 0},
00497 { 0, 0, 0, 0, 0}
00498 };
00499
00500
00501 struct module_exports exports = {
00502 "nathelper",
00503 DEFAULT_DLFLAGS,
00504 cmds,
00505 params,
00506 0,
00507 mi_cmds,
00508 0,
00509 0,
00510 mod_init,
00511 0,
00512 mod_destroy,
00513 child_init
00514 };
00515
00516
00517 static int rtpproxy_set_store(modparam_t type, void * val){
00518
00519 char * p;
00520 int len;
00521
00522 p = (char* )val;
00523
00524 if(p==0 || *p=='\0'){
00525 return 0;
00526 }
00527
00528 if(rtpp_sets==0){
00529 rtpp_strings = (char**)pkg_malloc(sizeof(char*));
00530 if(!rtpp_strings){
00531 LM_ERR("no pkg memory left\n");
00532 return -1;
00533 }
00534 } else {
00535 rtpp_strings = (char**)pkg_realloc(rtpp_strings,
00536 (rtpp_sets+1)* sizeof(char*));
00537 if(!rtpp_strings){
00538 LM_ERR("no pkg memory left\n");
00539 return -1;
00540 }
00541 }
00542
00543
00544 len = strlen(p);
00545 rtpp_strings[rtpp_sets] = (char*)pkg_malloc((len+1)*sizeof(char));
00546
00547 if(!rtpp_strings[rtpp_sets]){
00548 LM_ERR("no pkg memory left\n");
00549 return -1;
00550 }
00551
00552 memcpy(rtpp_strings[rtpp_sets], p, len);
00553 rtpp_strings[rtpp_sets][len] = '\0';
00554 rtpp_sets++;
00555
00556 return 0;
00557 }
00558
00559
00560 static int add_rtpproxy_socks(struct rtpp_set * rtpp_list,
00561 char * rtpproxy){
00562
00563 char *p, *p1, *p2, *plim;
00564 struct rtpp_node *pnode;
00565 int weight;
00566
00567 p = rtpproxy;
00568 plim = p + strlen(p);
00569
00570 for(;;) {
00571 weight = 1;
00572 while (*p && isspace((int)*p))
00573 ++p;
00574 if (p >= plim)
00575 break;
00576 p1 = p;
00577 while (*p && !isspace((int)*p))
00578 ++p;
00579 if (p <= p1)
00580 break;
00581
00582 p2 = memchr(p1, '=', p - p1);
00583 if (p2 != NULL) {
00584 weight = strtoul(p2 + 1, NULL, 10);
00585 } else {
00586 p2 = p;
00587 }
00588 pnode = shm_malloc(sizeof(struct rtpp_node));
00589 if (pnode == NULL) {
00590 LM_ERR("no shm memory left\n");
00591 return -1;
00592 }
00593 memset(pnode, 0, sizeof(*pnode));
00594 pnode->idx = rtpp_no++;
00595 pnode->rn_recheck_ticks = 0;
00596 pnode->rn_weight = weight;
00597 pnode->rn_umode = 0;
00598 pnode->rn_disabled = 0;
00599 pnode->rn_url.s = shm_malloc(p2 - p1 + 1);
00600 if (pnode->rn_url.s == NULL) {
00601 shm_free(pnode);
00602 LM_ERR("no shm memory left\n");
00603 return -1;
00604 }
00605 memmove(pnode->rn_url.s, p1, p2 - p1);
00606 pnode->rn_url.s[p2 - p1] = 0;
00607 pnode->rn_url.len = p2-p1;
00608
00609 LM_DBG("url is %s, len is %i\n", pnode->rn_url.s, pnode->rn_url.len);
00610
00611 pnode->rn_address = pnode->rn_url.s;
00612 if (strncasecmp(pnode->rn_address, "udp:", 4) == 0) {
00613 pnode->rn_umode = 1;
00614 pnode->rn_address += 4;
00615 } else if (strncasecmp(pnode->rn_address, "udp6:", 5) == 0) {
00616 pnode->rn_umode = 6;
00617 pnode->rn_address += 5;
00618 } else if (strncasecmp(pnode->rn_address, "unix:", 5) == 0) {
00619 pnode->rn_umode = 0;
00620 pnode->rn_address += 5;
00621 }
00622
00623 if (rtpp_list->rn_first == NULL) {
00624 rtpp_list->rn_first = pnode;
00625 } else {
00626 rtpp_list->rn_last->rn_next = pnode;
00627 }
00628
00629 rtpp_list->rn_last = pnode;
00630 rtpp_list->rtpp_node_count++;
00631 }
00632 return 0;
00633 }
00634
00635
00636
00637
00638
00639 static int nathelper_add_rtpproxy_set( char * rtp_proxies)
00640 {
00641 char *p,*p2;
00642 struct rtpp_set * rtpp_list;
00643 unsigned int my_current_id;
00644 str id_set;
00645 int new_list;
00646
00647
00648 p= rtp_proxies;
00649 if(!p || *p=='\0'){
00650 return 0;
00651 }
00652
00653 for(;*p && isspace(*p);p++);
00654 if(*p=='\0'){
00655 return 0;
00656 }
00657
00658 rtp_proxies = strstr(p, "==");
00659 if(rtp_proxies){
00660 if(*(rtp_proxies +2)=='\0'){
00661 LM_ERR("script error -invalid rtp proxy list!\n");
00662 return -1;
00663 }
00664
00665 *rtp_proxies = '\0';
00666 p2 = rtp_proxies-1;
00667 for(;isspace(*p2); *p2 = '\0',p2--);
00668 id_set.s = p; id_set.len = p2 - p+1;
00669
00670 if(id_set.len <= 0 ||str2int(&id_set, &my_current_id)<0 ){
00671 LM_ERR("script error -invalid set_id value!\n");
00672 return -1;
00673 }
00674
00675 rtp_proxies+=2;
00676 }else{
00677 rtp_proxies = p;
00678 my_current_id = DEFAULT_RTPP_SET_ID;
00679 }
00680
00681 for(;*rtp_proxies && isspace(*rtp_proxies);rtp_proxies++);
00682
00683 if(!(*rtp_proxies)){
00684 LM_ERR("script error -empty rtp_proxy list\n");
00685 return -1;;
00686 }
00687
00688
00689 rtpp_list = rtpp_set_list ? rtpp_set_list->rset_first : 0;
00690 while( rtpp_list != 0 && rtpp_list->id_set!=my_current_id)
00691 rtpp_list = rtpp_list->rset_next;
00692
00693 if(rtpp_list==NULL){
00694 rtpp_list = shm_malloc(sizeof(struct rtpp_set));
00695 if(!rtpp_list){
00696 LM_ERR("no shm memory left\n");
00697 return -1;
00698 }
00699 memset(rtpp_list, 0, sizeof(struct rtpp_set));
00700 rtpp_list->id_set = my_current_id;
00701 new_list = 1;
00702 } else {
00703 new_list = 0;
00704 }
00705
00706 if(add_rtpproxy_socks(rtpp_list, rtp_proxies)!= 0){
00707
00708 goto error;
00709 }
00710
00711 if (new_list) {
00712 if(!rtpp_set_list){
00713 rtpp_set_list = shm_malloc(sizeof(struct rtpp_set_head));
00714 if(!rtpp_set_list){
00715 LM_ERR("no shm memory left\n");
00716 return -1;
00717 }
00718 memset(rtpp_set_list, 0, sizeof(struct rtpp_set_head));
00719 }
00720
00721
00722 if(!rtpp_set_list->rset_first){
00723 rtpp_set_list->rset_first = rtpp_list;
00724 }else{
00725 rtpp_set_list->rset_last->rset_next = rtpp_list;
00726 }
00727
00728 rtpp_set_list->rset_last = rtpp_list;
00729 rtpp_set_count++;
00730
00731 if(my_current_id == DEFAULT_RTPP_SET_ID){
00732 default_rtpp_set = rtpp_list;
00733 }
00734 }
00735
00736 return 0;
00737 error:
00738 return -1;
00739 }
00740
00741
00742 static int fixup_set_id(void ** param, int param_no)
00743 {
00744 int int_val, err;
00745 struct rtpp_set* rtpp_list;
00746
00747 int_val = str2s(*param, strlen(*param), &err);
00748 if (err == 0) {
00749 pkg_free(*param);
00750 if((rtpp_list = select_rtpp_set(int_val)) ==0){
00751 LM_ERR("rtpp_proxy set %i not configured\n", int_val);
00752 return E_CFG;
00753 }
00754 *param = (void *)rtpp_list;
00755
00756 return 0;
00757 } else {
00758 LM_ERR("bad number <%s>\n", (char *)(*param));
00759 return E_CFG;
00760 }
00761 }
00762
00763 static int
00764 fixup_fix_sdp(void** param, int param_no)
00765 {
00766 pv_elem_t *model;
00767 str s;
00768
00769 if (param_no==1) {
00770
00771 return fixup_uint_null( param, param_no);
00772 }
00773
00774 model=NULL;
00775 s.s = (char*)(*param); s.len = strlen(s.s);
00776 if(pv_parse_format(&s,&model)<0) {
00777 LM_ERR("wrong format[%s]!\n", (char*)(*param));
00778 return E_UNSPEC;
00779 }
00780 if (model==NULL) {
00781 LM_ERR("empty parameter!\n");
00782 return E_UNSPEC;
00783 }
00784 *param = (void*)model;
00785 return 0;
00786 }
00787
00788 static int fixup_fix_nated_register(void** param, int param_no)
00789 {
00790 if (rcv_avp_name.n == 0) {
00791 LM_ERR("you must set 'received_avp' parameter. Must be same value as"
00792 " parameter 'received_avp' of registrar module\n");
00793 return -1;
00794 }
00795 return 0;
00796 }
00797
00798 static struct mi_root* mi_enable_rtp_proxy(struct mi_root* cmd_tree,
00799 void* param )
00800 { struct mi_node* node;
00801 str rtpp_url;
00802 unsigned int enable;
00803 struct rtpp_set * rtpp_list;
00804 struct rtpp_node * crt_rtpp;
00805 int found;
00806
00807 found = 0;
00808
00809 if(rtpp_set_list ==NULL)
00810 goto end;
00811
00812 node = cmd_tree->node.kids;
00813 if(node == NULL)
00814 return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
00815
00816 if(node->value.s == NULL || node->value.len ==0)
00817 return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
00818
00819 rtpp_url = node->value;
00820
00821 node = node->next;
00822 if(node == NULL)
00823 return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
00824
00825 enable = 0;
00826 if( strno2int( &node->value, &enable) <0)
00827 goto error;
00828
00829 for(rtpp_list = rtpp_set_list->rset_first; rtpp_list != NULL;
00830 rtpp_list = rtpp_list->rset_next){
00831
00832 for(crt_rtpp = rtpp_list->rn_first; crt_rtpp != NULL;
00833 crt_rtpp = crt_rtpp->rn_next){
00834
00835
00836 if(crt_rtpp->rn_url.len == rtpp_url.len){
00837
00838 if(strncmp(crt_rtpp->rn_url.s, rtpp_url.s, rtpp_url.len) == 0){
00839
00840 found = 1;
00841 crt_rtpp->rn_recheck_ticks =
00842 enable? MI_MIN_RECHECK_TICKS : MI_MAX_RECHECK_TICKS;
00843 crt_rtpp->rn_disabled = enable?0:1;
00844 }
00845 }
00846 }
00847 }
00848
00849 end:
00850 if(found)
00851 return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
00852 return init_mi_tree(404,MI_RTP_PROXY_NOT_FOUND,MI_RTP_PROXY_NOT_FOUND_LEN);
00853 error:
00854 return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
00855 }
00856
00857
00858
00859 static struct mi_root* mi_enable_natping(struct mi_root* cmd_tree,
00860 void* param )
00861 {
00862 unsigned int value;
00863 struct mi_node* node;
00864
00865 if (natping_state==NULL)
00866 return init_mi_tree( 400, MI_PING_DISABLED, MI_PING_DISABLED_LEN);
00867
00868 node = cmd_tree->node.kids;
00869 if(node == NULL)
00870 return init_mi_tree( 400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN);
00871
00872 value = 0;
00873 if( strno2int( &node->value, &value) <0)
00874 goto error;
00875
00876 (*natping_state) = value?1:0;
00877
00878 return init_mi_tree( 200, MI_OK_S, MI_OK_LEN);
00879 error:
00880 return init_mi_tree( 400, MI_BAD_PARM_S, MI_BAD_PARM_LEN);
00881 }
00882
00883
00884
00885 #define add_rtpp_node_int_info(_parent, _name, _name_len, _value, _child,\
00886 _len, _string, _error)\
00887 do {\
00888 (_string) = int2str((_value), &(_len));\
00889 if((_string) == 0){\
00890 LM_ERR("cannot convert int value\n");\
00891 goto _error;\
00892 }\
00893 if(((_child) = add_mi_node_child((_parent), MI_DUP_VALUE, (_name), \
00894 (_name_len), (_string), (_len)) ) == 0)\
00895 goto _error;\
00896 }while(0);
00897
00898 static struct mi_root* mi_show_rtpproxies(struct mi_root* cmd_tree,
00899 void* param)
00900 {
00901 struct mi_node* node, *crt_node, *child;
00902 struct mi_root* root;
00903 struct mi_attr * attr;
00904 struct rtpp_set * rtpp_list;
00905 struct rtpp_node * crt_rtpp;
00906 char * string, *id;
00907 int id_len, len;
00908
00909 string = id = 0;
00910
00911 root = init_mi_tree(200, MI_OK_S, MI_OK_LEN);
00912 if (!root) {
00913 LM_ERR("the MI tree cannot be initialized!\n");
00914 return 0;
00915 }
00916
00917 if(rtpp_set_list ==NULL)
00918 return root;
00919
00920 node = &root->node;
00921
00922 for(rtpp_list = rtpp_set_list->rset_first; rtpp_list != NULL;
00923 rtpp_list = rtpp_list->rset_next){
00924
00925 for(crt_rtpp = rtpp_list->rn_first; crt_rtpp != NULL;
00926 crt_rtpp = crt_rtpp->rn_next){
00927
00928 id = int2str(rtpp_list->id_set, &id_len);
00929 if(!id){
00930 LM_ERR("cannot convert set id\n");
00931 goto error;
00932 }
00933
00934 if(!(crt_node = add_mi_node_child(node, 0, crt_rtpp->rn_url.s,
00935 crt_rtpp->rn_url.len, 0,0)) ) {
00936 LM_ERR("cannot add the child node to the tree\n");
00937 goto error;
00938 }
00939
00940 LM_DBG("adding node name %s \n",crt_rtpp->rn_url.s );
00941
00942 if((attr = add_mi_attr(crt_node, MI_DUP_VALUE, MI_SET, MI_SET_LEN,
00943 id, id_len))== 0){
00944 LM_ERR("cannot add attributes to the node\n");
00945 goto error;
00946 }
00947
00948 add_rtpp_node_int_info(crt_node, MI_INDEX, MI_INDEX_LEN,
00949 crt_rtpp->idx, child, len,string,error);
00950 add_rtpp_node_int_info(crt_node, MI_DISABLED, MI_DISABLED_LEN,
00951 crt_rtpp->rn_disabled, child, len,string,error);
00952 add_rtpp_node_int_info(crt_node, MI_WEIGHT, MI_WEIGHT_LEN,
00953 crt_rtpp->rn_weight, child, len, string,error);
00954 add_rtpp_node_int_info(crt_node, MI_RECHECK_TICKS,MI_RECHECK_T_LEN,
00955 crt_rtpp->rn_recheck_ticks, child, len, string, error);
00956 }
00957 }
00958
00959 return root;
00960 error:
00961 if (root)
00962 free_mi_tree(root);
00963 return 0;
00964 }
00965
00966
00967 static int init_raw_socket(void)
00968 {
00969 int on = 1;
00970
00971 raw_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
00972 if (raw_sock ==-1) {
00973 LM_ERR("cannot create raw socket\n");
00974 return -1;
00975 }
00976
00977 if (setsockopt(raw_sock, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) == -1) {
00978 LM_ERR("cannot set socket options\n");
00979 return -1;
00980 }
00981
00982 return raw_sock;
00983 }
00984
00985
00986 static int get_natping_socket(char *socket,
00987 unsigned int *ip, unsigned short *port)
00988 {
00989 struct hostent* he;
00990 str host;
00991 int lport;
00992 int lproto;
00993
00994 if (parse_phostport( socket, strlen(socket), &host.s, &host.len,
00995 &lport, &lproto)!=0){
00996 LM_CRIT("invalid natping_socket parameter <%s>\n",natping_socket);
00997 return -1;
00998 }
00999
01000 if (lproto!=PROTO_UDP && lproto!=PROTO_NONE) {
01001 LM_CRIT("natping_socket can be only UDP <%s>\n",natping_socket);
01002 return 0;
01003 }
01004 lproto = PROTO_UDP;
01005 *port = lport?(unsigned short)lport:SIP_PORT;
01006
01007 he = sip_resolvehost( &host, port, (unsigned short*)(void*)&lproto, 0, 0);
01008 if (he==0) {
01009 LM_ERR("could not resolve hostname:\"%.*s\"\n", host.len, host.s);
01010 return -1;
01011 }
01012 if (he->h_addrtype != AF_INET) {
01013 LM_ERR("only ipv4 addresses allowed in natping_socket\n");
01014 return -1;
01015 }
01016
01017 memcpy( ip, he->h_addr_list[0], he->h_length);
01018
01019 return 0;
01020 }
01021
01022
01023 static int
01024 mod_init(void)
01025 {
01026 int i;
01027 bind_usrloc_t bind_usrloc;
01028 struct in_addr addr;
01029 str socket_str;
01030 pv_spec_t avp_spec;
01031 str s;
01032
01033 if (rcv_avp_param && *rcv_avp_param) {
01034 s.s = rcv_avp_param; s.len = strlen(s.s);
01035 if (pv_parse_spec(&s, &avp_spec)==0
01036 || avp_spec.type!=PVT_AVP) {
01037 LM_ERR("malformed or non AVP %s AVP definition\n", rcv_avp_param);
01038 return -1;
01039 }
01040
01041 if(pv_get_avp_name(0, &avp_spec.pvp, &rcv_avp_name, &rcv_avp_type)!=0)
01042 {
01043 LM_ERR("[%s]- invalid AVP definition\n", rcv_avp_param);
01044 return -1;
01045 }
01046 } else {
01047 rcv_avp_name.n = 0;
01048 rcv_avp_type = 0;
01049 }
01050
01051 if (force_socket_str) {
01052 socket_str.s=force_socket_str;
01053 socket_str.len=strlen(socket_str.s);
01054 force_socket=grep_sock_info(&socket_str,0,0);
01055 }
01056
01057
01058 if (natping_socket && natping_socket[0]) {
01059 if (get_natping_socket( natping_socket, &raw_ip, &raw_port)!=0)
01060 return -1;
01061 if (init_raw_socket() < 0)
01062 return -1;
01063 }
01064
01065
01066 if(rtpp_set_list)
01067 default_rtpp_set = select_rtpp_set(DEFAULT_RTPP_SET_ID);
01068
01069 if (nortpproxy_str.s==NULL || nortpproxy_str.s[0]==0) {
01070 nortpproxy_str.len = 0;
01071 nortpproxy_str.s = NULL;
01072 } else {
01073 nortpproxy_str.len = strlen(nortpproxy_str.s);
01074 while (nortpproxy_str.len > 0 && (nortpproxy_str.s[nortpproxy_str.len - 1] == '\r' ||
01075 nortpproxy_str.s[nortpproxy_str.len - 1] == '\n'))
01076 nortpproxy_str.len--;
01077 if (nortpproxy_str.len == 0)
01078 nortpproxy_str.s = NULL;
01079 }
01080
01081 if (natping_interval > 0) {
01082 bind_usrloc = (bind_usrloc_t)find_export("ul_bind_usrloc", 1, 0);
01083 if (!bind_usrloc) {
01084 LM_ERR("can't find usrloc module\n");
01085 return -1;
01086 }
01087
01088 if (bind_usrloc(&ul) < 0) {
01089 return -1;
01090 }
01091
01092 natping_state =(unsigned int *) shm_malloc(sizeof(unsigned int));
01093 if (!natping_state) {
01094 LM_ERR("no shmem left\n");
01095 return -1;
01096 }
01097 *natping_state = MI_DEFAULT_NATPING_STATE;
01098
01099 if (ping_nated_only && ul.nat_flag==0) {
01100 LM_ERR("bad config - ping_nated_only enabled, but no nat bflag"
01101 " set in usrloc module\n");
01102 return -1;
01103 }
01104 if (natping_processes>=8) {
01105 LM_ERR("too many natping processes (%d) max=8\n",
01106 natping_processes);
01107 return -1;
01108 }
01109
01110 sipping_flag = (sipping_flag==-1)?0:(1<<sipping_flag);
01111
01112
01113 if (sipping_flag) {
01114 if (sipping_from.s==0 || sipping_from.s[0]==0) {
01115 LM_ERR("SIP ping enabled, but SIP ping FROM is empty!\n");
01116 return -1;
01117 }
01118 if (sipping_method.s==0 || sipping_method.s[0]==0) {
01119 LM_ERR("SIP ping enabled, but SIP ping method is empty!\n");
01120 return -1;
01121 }
01122 sipping_method.len = strlen(sipping_method.s);
01123 sipping_from.len = strlen(sipping_from.s);
01124 exports.response_f = sipping_rpl_filter;
01125 init_sip_ping();
01126 }
01127
01128 for( i=0 ; i<natping_processes ; i++ ) {
01129 if (register_timer_process( nh_timer, (void*)(unsigned long)i, 1,
01130 TIMER_PROC_INIT_FLAG)<0) {
01131 LM_ERR("failed to register timer routine as process\n");
01132 return -1;
01133 }
01134 }
01135 }
01136
01137
01138 for (i = 0; nets_1918[i].cnetaddr != NULL; i++) {
01139 if (inet_aton(nets_1918[i].cnetaddr, &addr) != 1)
01140 abort();
01141 nets_1918[i].netaddr = ntohl(addr.s_addr) & nets_1918[i].mask;
01142 }
01143
01144
01145 for(i=0;i<rtpp_sets;i++){
01146 if(nathelper_add_rtpproxy_set(rtpp_strings[i]) !=0){
01147 for(;i<rtpp_sets;i++)
01148 if(rtpp_strings[i])
01149 pkg_free(rtpp_strings[i]);
01150 pkg_free(rtpp_strings);
01151 return -1;
01152 }
01153 if(rtpp_strings[i])
01154 pkg_free(rtpp_strings[i]);
01155 }
01156 if (rtpp_strings)
01157 pkg_free(rtpp_strings);
01158
01159 return 0;
01160 }
01161
01162
01163 static int
01164 child_init(int rank)
01165 {
01166 int n;
01167 char *cp;
01168 struct addrinfo hints, *res;
01169 struct rtpp_set *rtpp_list;
01170 struct rtpp_node *pnode;
01171
01172 if (rank<=0 && rank!=PROC_TIMER)
01173 return 0;
01174
01175 if(rtpp_set_list==NULL )
01176 return 0;
01177
01178
01179 mypid = getpid();
01180
01181 rtpp_socks = (int*)pkg_malloc( sizeof(int)*rtpp_no );
01182 if (rtpp_socks==NULL) {
01183 LM_ERR("no more pkg memory\n");
01184 return -1;
01185 }
01186
01187 for(rtpp_list = rtpp_set_list->rset_first; rtpp_list != 0;
01188 rtpp_list = rtpp_list->rset_next){
01189
01190 for (pnode=rtpp_list->rn_first; pnode!=0; pnode = pnode->rn_next){
01191 char *hostname;
01192
01193 if (pnode->rn_umode == 0) {
01194 rtpp_socks[pnode->idx] = -1;
01195 goto rptest;
01196 }
01197
01198
01199
01200
01201
01202 hostname = (char*)pkg_malloc(sizeof(char) * (strlen(pnode->rn_address) + 1));
01203 if (hostname==NULL) {
01204 LM_ERR("no more pkg memory\n");
01205 return -1;
01206 }
01207 strcpy(hostname, pnode->rn_address);
01208
01209 cp = strrchr(hostname, ':');
01210 if (cp != NULL) {
01211 *cp = '\0';
01212 cp++;
01213 }
01214 if (cp == NULL || *cp == '\0')
01215 cp = CPORT;
01216
01217 memset(&hints, 0, sizeof(hints));
01218 hints.ai_flags = 0;
01219 hints.ai_family = (pnode->rn_umode == 6) ? AF_INET6 : AF_INET;
01220 hints.ai_socktype = SOCK_DGRAM;
01221 if ((n = getaddrinfo(hostname, cp, &hints, &res)) != 0) {
01222 LM_ERR("%s\n", gai_strerror(n));
01223 pkg_free(hostname);
01224 return -1;
01225 }
01226 pkg_free(hostname);
01227
01228 rtpp_socks[pnode->idx] = socket((pnode->rn_umode == 6)
01229 ? AF_INET6 : AF_INET, SOCK_DGRAM, 0);
01230 if ( rtpp_socks[pnode->idx] == -1) {
01231 LM_ERR("can't create socket\n");
01232 freeaddrinfo(res);
01233 return -1;
01234 }
01235
01236 if (connect( rtpp_socks[pnode->idx], res->ai_addr, res->ai_addrlen) == -1) {
01237 LM_ERR("can't connect to a RTP proxy\n");
01238 close( rtpp_socks[pnode->idx] );
01239 rtpp_socks[pnode->idx] = -1;
01240 freeaddrinfo(res);
01241 return -1;
01242 }
01243 freeaddrinfo(res);
01244 rptest:
01245 pnode->rn_disabled = rtpp_test(pnode, 0, 1);
01246 }
01247 }
01248
01249 return 0;
01250 }
01251
01252
01253 static void mod_destroy(void)
01254 {
01255 struct rtpp_set * crt_list, * last_list;
01256 struct rtpp_node * crt_rtpp, *last_rtpp;
01257
01258
01259 if (natping_state)
01260 shm_free(natping_state);
01261
01262 if(rtpp_set_list == NULL)
01263 return;
01264
01265 for(crt_list = rtpp_set_list->rset_first; crt_list != NULL; ){
01266
01267 for(crt_rtpp = crt_list->rn_first; crt_rtpp != NULL; ){
01268
01269 if(crt_rtpp->rn_url.s)
01270 shm_free(crt_rtpp->rn_url.s);
01271
01272 last_rtpp = crt_rtpp;
01273 crt_rtpp = last_rtpp->rn_next;
01274 shm_free(last_rtpp);
01275 }
01276
01277 last_list = crt_list;
01278 crt_list = last_list->rset_next;
01279 shm_free(last_list);
01280 }
01281
01282 shm_free(rtpp_set_list);
01283 }
01284
01285
01286
01287 static int
01288 isnulladdr(str *sx, int pf)
01289 {
01290 char *cp;
01291
01292 if (pf == AF_INET6) {
01293 for(cp = sx->s; cp < sx->s + sx->len; cp++)
01294 if (*cp != '0' && *cp != ':')
01295 return 0;
01296 return 1;
01297 }
01298 return (sx->len == 7 && memcmp("0.0.0.0", sx->s, 7) == 0);
01299 }
01300
01301
01302
01303
01304
01305 static int
01306 fix_nated_contact_f(struct sip_msg* msg, char* str1, char* str2)
01307 {
01308 int offset, len, len1;
01309 char *cp, *buf, temp[2];
01310 contact_t *c;
01311 struct lump *anchor;
01312 struct sip_uri uri;
01313 str hostport;
01314
01315 if (get_contact_uri(msg, &uri, &c) == -1)
01316 return -1;
01317 if ((c->uri.s < msg->buf) || (c->uri.s > (msg->buf + msg->len))) {
01318 LM_ERR("you can't call fix_nated_contact twice, "
01319 "check your config!\n");
01320 return -1;
01321 }
01322
01323 offset = c->uri.s - msg->buf;
01324 anchor = del_lump(msg, offset, c->uri.len, HDR_CONTACT_T);
01325 if (anchor == 0)
01326 return -1;
01327
01328 hostport = uri.host;
01329 if (uri.port.len > 0)
01330 hostport.len = uri.port.s + uri.port.len - uri.host.s;
01331
01332 cp = ip_addr2a(&msg->rcv.src_ip);
01333 len = c->uri.len + strlen(cp) + 6 - hostport.len + 1;
01334 buf = pkg_malloc(len);
01335 if (buf == NULL) {
01336 LM_ERR("out of pkg memory\n");
01337 return -1;
01338 }
01339 temp[0] = hostport.s[0];
01340 temp[1] = c->uri.s[c->uri.len];
01341 c->uri.s[c->uri.len] = hostport.s[0] = '\0';
01342 len1 = snprintf(buf, len, "%s%s:%d%s", c->uri.s, cp, msg->rcv.src_port,
01343 hostport.s + hostport.len);
01344 if (len1 < len)
01345 len = len1;
01346 hostport.s[0] = temp[0];
01347 c->uri.s[c->uri.len] = temp[1];
01348 if (insert_new_lump_after(anchor, buf, len, HDR_CONTACT_T) == 0) {
01349 pkg_free(buf);
01350 return -1;
01351 }
01352 c->uri.s = buf;
01353 c->uri.len = len;
01354
01355 return 1;
01356 }
01357
01358
01359
01360
01361
01362 static inline int
01363 is1918addr(str *saddr)
01364 {
01365 struct in_addr addr;
01366 uint32_t netaddr;
01367 int i, rval;
01368 char backup;
01369
01370 rval = -1;
01371 backup = saddr->s[saddr->len];
01372 saddr->s[saddr->len] = '\0';
01373 if (inet_aton(saddr->s, &addr) != 1)
01374 goto theend;
01375 netaddr = ntohl(addr.s_addr);
01376 for (i = 0; nets_1918[i].cnetaddr != NULL; i++) {
01377 if ((netaddr & nets_1918[i].mask) == nets_1918[i].netaddr) {
01378 rval = 1;
01379 goto theend;
01380 }
01381 }
01382 rval = 0;
01383
01384 theend:
01385 saddr->s[saddr->len] = backup;
01386 return rval;
01387 }
01388
01389
01390
01391
01392 static int
01393 contact_1918(struct sip_msg* msg)
01394 {
01395 struct sip_uri uri;
01396 contact_t* c;
01397
01398 if (get_contact_uri(msg, &uri, &c) == -1)
01399 return -1;
01400
01401 return (is1918addr(&(uri.host)) == 1) ? 1 : 0;
01402 }
01403
01404
01405
01406
01407 static int
01408 sdp_1918(struct sip_msg* msg)
01409 {
01410 str body, ip;
01411 int pf;
01412
01413 if (extract_body(msg, &body) == -1) {
01414 LM_ERR("cannot extract body from msg!\n");
01415 return 0;
01416 }
01417 if (extract_mediaip(&body, &ip, &pf,"c=") == -1) {
01418 LM_ERR("can't extract media IP from the SDP\n");
01419 return 0;
01420 }
01421 if (pf != AF_INET || isnulladdr(&ip, pf))
01422 return 0;
01423
01424 return (is1918addr(&ip) == 1) ? 1 : 0;
01425 }
01426
01427
01428
01429
01430 static int
01431 via_1918(struct sip_msg* msg)
01432 {
01433
01434 return (is1918addr(&(msg->via1->host)) == 1) ? 1 : 0;
01435 }
01436
01437 static int
01438 nat_uac_test_f(struct sip_msg* msg, char* str1, char* str2)
01439 {
01440 int tests;
01441
01442 tests = (int)(long)str1;
01443
01444
01445
01446
01447 if ((tests & NAT_UAC_TEST_RPORT) &&
01448 (msg->rcv.src_port!=(msg->via1->port?msg->via1->port:SIP_PORT)) ){
01449 return 1;
01450 }
01451
01452
01453
01454
01455 if ((tests & NAT_UAC_TEST_RCVD) && received_test(msg))
01456 return 1;
01457
01458
01459
01460
01461 if ((tests & NAT_UAC_TEST_C_1918) && (contact_1918(msg)>0))
01462 return 1;
01463
01464
01465
01466 if ((tests & NAT_UAC_TEST_S_1918) && sdp_1918(msg))
01467 return 1;
01468
01469
01470
01471 if ((tests & NAT_UAC_TEST_V_1918) && via_1918(msg))
01472 return 1;
01473
01474
01475 return -1;
01476
01477 }
01478
01479 #define ADD_ADIRECTION 0x01
01480 #define FIX_MEDIP 0x02
01481 #define ADD_ANORTPPROXY 0x04
01482 #define FIX_ORGIP 0x08
01483
01484 #define ADIRECTION "a=direction:active"
01485 #define ADIRECTION_LEN (sizeof(ADIRECTION) - 1)
01486
01487 #define AOLDMEDIP "a=oldmediaip:"
01488 #define AOLDMEDIP_LEN (sizeof(AOLDMEDIP) - 1)
01489
01490 #define AOLDMEDIP6 "a=oldmediaip6:"
01491 #define AOLDMEDIP6_LEN (sizeof(AOLDMEDIP6) - 1)
01492
01493 #define AOLDMEDPRT "a=oldmediaport:"
01494 #define AOLDMEDPRT_LEN (sizeof(AOLDMEDPRT) - 1)
01495
01496
01497 static inline int
01498 replace_sdp_ip(struct sip_msg* msg, str *org_body, char *line, str *ip)
01499 {
01500 str body1, oldip, newip;
01501 str body = *org_body;
01502 unsigned hasreplaced = 0;
01503 int pf, pf1 = 0;
01504 str body2;
01505 char *bodylimit = body.s + body.len;
01506
01507
01508 if (!ip) {
01509 newip.s = ip_addr2a(&msg->rcv.src_ip);
01510 newip.len = strlen(newip.s);
01511 } else {
01512 newip = *ip;
01513 }
01514 body1 = body;
01515 for(;;) {
01516 if (extract_mediaip(&body1, &oldip, &pf,line) == -1)
01517 break;
01518 if (pf != AF_INET) {
01519 LM_ERR("not an IPv4 address in '%s' SDP\n",line);
01520 return -1;
01521 }
01522 if (!pf1)
01523 pf1 = pf;
01524 else if (pf != pf1) {
01525 LM_ERR("mismatching address families in '%s' SDP\n",line);
01526 return -1;
01527 }
01528 body2.s = oldip.s + oldip.len;
01529 body2.len = bodylimit - body2.s;
01530 if (alter_mediaip(msg, &body1, &oldip, pf, &newip, pf,1) == -1) {
01531 LM_ERR("can't alter '%s' IP\n",line);
01532 return -1;
01533 }
01534 hasreplaced = 1;
01535 body1 = body2;
01536 }
01537 if (!hasreplaced) {
01538 LM_ERR("can't extract '%s' IP from the SDP\n",line);
01539 return -1;
01540 }
01541
01542 return 0;
01543 }
01544
01545 static int
01546 fix_nated_sdp_f(struct sip_msg* msg, char* str1, char* str2)
01547 {
01548 str body;
01549 str ip;
01550 int level;
01551 char *buf;
01552 struct lump* anchor;
01553
01554 level = (int)(long)str1;
01555 if (str2 && pv_printf_s( msg, (pv_elem_p)str2, &ip)!=0)
01556 return -1;
01557
01558 if (extract_body(msg, &body) == -1) {
01559 LM_ERR("cannot extract body from msg!\n");
01560 return -1;
01561 }
01562
01563 if (level & (ADD_ADIRECTION | ADD_ANORTPPROXY)) {
01564 msg->msg_flags |= FL_FORCE_ACTIVE;
01565 anchor = anchor_lump(msg, body.s + body.len - msg->buf, 0, 0);
01566 if (anchor == NULL) {
01567 LM_ERR("anchor_lump failed\n");
01568 return -1;
01569 }
01570 if (level & ADD_ADIRECTION) {
01571 buf = pkg_malloc((ADIRECTION_LEN + CRLF_LEN) * sizeof(char));
01572 if (buf == NULL) {
01573 LM_ERR("out of pkg memory\n");
01574 return -1;
01575 }
01576 memcpy(buf, CRLF, CRLF_LEN);
01577 memcpy(buf + CRLF_LEN, ADIRECTION, ADIRECTION_LEN);
01578 if (insert_new_lump_after(anchor, buf, ADIRECTION_LEN + CRLF_LEN, 0) == NULL) {
01579 LM_ERR("insert_new_lump_after failed\n");
01580 pkg_free(buf);
01581 return -1;
01582 }
01583 }
01584 if ((level & ADD_ANORTPPROXY) && nortpproxy_str.len) {
01585 buf = pkg_malloc((nortpproxy_str.len + CRLF_LEN) * sizeof(char));
01586 if (buf == NULL) {
01587 LM_ERR("out of pkg memory\n");
01588 return -1;
01589 }
01590 memcpy(buf, CRLF, CRLF_LEN);
01591 memcpy(buf + CRLF_LEN, nortpproxy_str.s, nortpproxy_str.len);
01592 if (insert_new_lump_after(anchor, buf, nortpproxy_str.len + CRLF_LEN, 0) == NULL) {
01593 LM_ERR("insert_new_lump_after failed\n");
01594 pkg_free(buf);
01595 return -1;
01596 }
01597 }
01598 }
01599
01600 if (level & FIX_MEDIP) {
01601
01602 if (replace_sdp_ip(msg, &body, "c=", str2?&ip:0)==-1)
01603 return -1;
01604 }
01605
01606 if (level & FIX_ORGIP) {
01607
01608 if (replace_sdp_ip(msg, &body, "o=", str2?&ip:0)==-1)
01609 return -1;
01610 }
01611
01612 return 1;
01613 }
01614
01615 static int
01616 extract_mediaip(str *body, str *mediaip, int *pf, char *line)
01617 {
01618 char *cp, *cp1;
01619 int len, nextisip;
01620
01621 cp1 = NULL;
01622 for (cp = body->s; (len = body->s + body->len - cp) > 0;) {
01623 cp1 = ser_memmem(cp, line, len, 2);
01624 if (cp1 == NULL || cp1[-1] == '\n' || cp1[-1] == '\r')
01625 break;
01626 cp = cp1 + 2;
01627 }
01628 if (cp1 == NULL)
01629 return -1;
01630
01631 mediaip->s = cp1 + 2;
01632 mediaip->len = eat_line(mediaip->s, body->s + body->len - mediaip->s) - mediaip->s;
01633 trim_len(mediaip->len, mediaip->s, *mediaip);
01634
01635 nextisip = 0;
01636 for (cp = mediaip->s; cp < mediaip->s + mediaip->len;) {
01637 len = eat_token_end(cp, mediaip->s + mediaip->len) - cp;
01638 if (nextisip == 1) {
01639 mediaip->s = cp;
01640 mediaip->len = len;
01641 nextisip++;
01642 break;
01643 }
01644 if (len == 3 && memcmp(cp, "IP", 2) == 0) {
01645 switch (cp[2]) {
01646 case '4':
01647 nextisip = 1;
01648 *pf = AF_INET;
01649 break;
01650
01651 case '6':
01652 nextisip = 1;
01653 *pf = AF_INET6;
01654 break;
01655
01656 default:
01657 break;
01658 }
01659 }
01660 cp = eat_space_end(cp + len, mediaip->s + mediaip->len);
01661 }
01662 if (nextisip != 2 || mediaip->len == 0) {
01663 LM_ERR("no `IP[4|6]' in `%s' field\n",line);
01664 return -1;
01665 }
01666 return 1;
01667 }
01668
01669 static int
01670 extract_mediainfo(str *body, str *mediaport, str *payload_types)
01671 {
01672 char *cp, *cp1;
01673 int len, i;
01674 str ptype;
01675
01676 cp1 = NULL;
01677 for (cp = body->s; (len = body->s + body->len - cp) > 0;) {
01678 cp1 = ser_memmem(cp, "m=", len, 2);
01679 if (cp1 == NULL || cp1[-1] == '\n' || cp1[-1] == '\r')
01680 break;
01681 cp = cp1 + 2;
01682 }
01683 if (cp1 == NULL) {
01684 LM_ERR("no `m=' in SDP\n");
01685 return -1;
01686 }
01687 mediaport->s = cp1 + 2;
01688 mediaport->len = eat_line(mediaport->s, body->s + body->len -
01689 mediaport->s) - mediaport->s;
01690 trim_len(mediaport->len, mediaport->s, *mediaport);
01691
01692
01693 cp = eat_token_end(mediaport->s, mediaport->s + mediaport->len);
01694 mediaport->len -= cp - mediaport->s;
01695 if (mediaport->len <= 0 || cp == mediaport->s) {
01696 LM_ERR("no port in `m='\n");
01697 return -1;
01698 }
01699 mediaport->s = cp;
01700 cp = eat_space_end(mediaport->s, mediaport->s + mediaport->len);
01701 mediaport->len -= cp - mediaport->s;
01702 if (mediaport->len <= 0 || cp == mediaport->s) {
01703 LM_ERR("no port in `m='\n");
01704 return -1;
01705 }
01706
01707 mediaport->s = cp;
01708 cp = eat_token_end(mediaport->s, mediaport->s + mediaport->len);
01709 ptype.len = mediaport->len - (cp - mediaport->s);
01710 if (ptype.len <= 0 || cp == mediaport->s) {
01711 LM_ERR("no port in `m='\n");
01712 return -1;
01713 }
01714 ptype.s = cp;
01715 mediaport->len = cp - mediaport->s;
01716
01717 cp = eat_space_end(ptype.s, ptype.s + ptype.len);
01718 ptype.len -= cp - ptype.s;
01719 if (ptype.len <= 0 || cp == ptype.s) {
01720 LM_ERR("no protocol type in `m='\n");
01721 return -1;
01722 }
01723
01724 ptype.s = cp;
01725 cp = eat_token_end(ptype.s, ptype.s + ptype.len);
01726 if (cp == ptype.s) {
01727 LM_ERR("no protocol type in `m='\n");
01728 return -1;
01729 }
01730 payload_types->len = ptype.len - (cp - ptype.s);
01731 ptype.len = cp - ptype.s;
01732 payload_types->s = cp;
01733
01734 for (i = 0; sup_ptypes[i].s != NULL; i++) {
01735 if (ptype.len != sup_ptypes[i].len ||
01736 strncasecmp(ptype.s, sup_ptypes[i].s, ptype.len) != 0)
01737 continue;
01738 if (sup_ptypes[i].is_rtp == 0) {
01739 payload_types->len = 0;
01740 return 0;
01741 }
01742 cp = eat_space_end(payload_types->s, payload_types->s +
01743 payload_types->len);
01744 if (cp == payload_types->s) {
01745 LM_ERR("no payload types in `m='\n");
01746 return -1;
01747 }
01748 payload_types->len -= cp - payload_types->s;
01749 payload_types->s = cp;
01750 return 0;
01751 }
01752
01753 return -1;
01754 }
01755
01756
01757
01758
01759 static int
01760 extract_rtcp(str *body, str *rtcpport)
01761 {
01762 char *cp, *cp1;
01763 int len;
01764
01765 cp1 = NULL;
01766 for (cp = body->s; (len = body->s + body->len - cp) > 0;) {
01767 cp1 = ser_memmem(cp, "a=rtcp:", len, 7);
01768 if (cp1 == NULL || cp1[-1] == '\n' || cp1[-1] == '\r')
01769 break;
01770 cp = cp1 + 7;
01771 }
01772
01773 if (cp1 == NULL)
01774 return -1;
01775
01776 rtcpport->s = cp1 + 7;
01777 rtcpport->len = eat_line(rtcpport->s, body->s + body->len -
01778 rtcpport->s) - rtcpport->s;
01779 trim_len(rtcpport->len, rtcpport->s, *rtcpport);
01780
01781 return 0;
01782 }
01783
01784 static int
01785 alter_mediaip(struct sip_msg *msg, str *body, str *oldip, int oldpf,
01786 str *newip, int newpf, int preserve)
01787 {
01788 char *buf;
01789 int offset;
01790 struct lump* anchor;
01791 str omip, nip, oip;
01792
01793
01794 if (oldpf == newpf && isnulladdr(oldip, oldpf))
01795 return 0;
01796 if (newip->len == oldip->len &&
01797 memcmp(newip->s, oldip->s, newip->len) == 0)
01798 return 0;
01799
01800 if (preserve != 0) {
01801 anchor = anchor_lump(msg, body->s + body->len - msg->buf, 0, 0);
01802 if (anchor == NULL) {
01803 LM_ERR("anchor_lump failed\n");
01804 return -1;
01805 }
01806 if (oldpf == AF_INET6) {
01807 omip.s = AOLDMEDIP6;
01808 omip.len = AOLDMEDIP6_LEN;
01809 } else {
01810 omip.s = AOLDMEDIP;
01811 omip.len = AOLDMEDIP_LEN;
01812 }
01813 buf = pkg_malloc(omip.len + oldip->len + CRLF_LEN);
01814 if (buf == NULL) {
01815 LM_ERR("out of pkg memory\n");
01816 return -1;
01817 }
01818 memcpy(buf, CRLF, CRLF_LEN);
01819 memcpy(buf + CRLF_LEN, omip.s, omip.len);
01820 memcpy(buf + CRLF_LEN + omip.len, oldip->s, oldip->len);
01821 if (insert_new_lump_after(anchor, buf,
01822 omip.len + oldip->len + CRLF_LEN, 0) == NULL) {
01823 LM_ERR("insert_new_lump_after failed\n");
01824 pkg_free(buf);
01825 return -1;
01826 }
01827 }
01828
01829 if (oldpf == newpf) {
01830 nip.len = newip->len;
01831 nip.s = pkg_malloc(nip.len);
01832 if (nip.s == NULL) {
01833 LM_ERR("out of pkg memory\n");
01834 return -1;
01835 }
01836 memcpy(nip.s, newip->s, newip->len);
01837 } else {
01838 nip.len = newip->len + 2;
01839 nip.s = pkg_malloc(nip.len);
01840 if (nip.s == NULL) {
01841 LM_ERR("out of pkg memory\n");
01842 return -1;
01843 }
01844 memcpy(nip.s + 2, newip->s, newip->len);
01845 nip.s[0] = (newpf == AF_INET6) ? '6' : '4';
01846 nip.s[1] = ' ';
01847 }
01848
01849 oip = *oldip;
01850 if (oldpf != newpf) {
01851 do {
01852 oip.s--;
01853 oip.len++;
01854 } while (*oip.s != '6' && *oip.s != '4');
01855 }
01856 offset = oip.s - msg->buf;
01857 anchor = del_lump(msg, offset, oip.len, 0);
01858 if (anchor == NULL) {
01859 LM_ERR("del_lump failed\n");
01860 pkg_free(nip.s);
01861 return -1;
01862 }
01863
01864 if (insert_new_lump_after(anchor, nip.s, nip.len, 0) == 0) {
01865 LM_ERR("insert_new_lump_after failed\n");
01866 pkg_free(nip.s);
01867 return -1;
01868 }
01869 return 0;
01870 }
01871
01872 static int
01873 alter_mediaport(struct sip_msg *msg, str *body, str *oldport, str *newport,
01874 int preserve)
01875 {
01876 char *buf;
01877 int offset;
01878 struct lump* anchor;
01879
01880
01881 if (newport->len == oldport->len &&
01882 memcmp(newport->s, oldport->s, newport->len) == 0)
01883 return 0;
01884
01885
01886
01887
01888
01889
01890
01891 #if 0
01892
01893
01894 if (msg->msg_flags & FL_SDP_PORT_AFS) {
01895 LM_ERR("you can't rewrite the same SDP twice, check your config!\n");
01896 return -1;
01897 }
01898 #endif
01899
01900 if (preserve != 0) {
01901 anchor = anchor_lump(msg, body->s + body->len - msg->buf, 0, 0);
01902 if (anchor == NULL) {
01903 LM_ERR("anchor_lump failed\n");
01904 return -1;
01905 }
01906 buf = pkg_malloc(AOLDMEDPRT_LEN + oldport->len + CRLF_LEN);
01907 if (buf == NULL) {
01908 LM_ERR("out of pkg memory\n");
01909 return -1;
01910 }
01911 memcpy(buf, CRLF, CRLF_LEN);
01912 memcpy(buf + CRLF_LEN, AOLDMEDPRT, AOLDMEDPRT_LEN);
01913 memcpy(buf + CRLF_LEN + AOLDMEDPRT_LEN, oldport->s, oldport->len);
01914 if (insert_new_lump_after(anchor, buf,
01915 AOLDMEDPRT_LEN + oldport->len + CRLF_LEN, 0) == NULL) {
01916 LM_ERR("insert_new_lump_after failed\n");
01917 pkg_free(buf);
01918 return -1;
01919 }
01920 }
01921
01922 buf = pkg_malloc(newport->len);
01923 if (buf == NULL) {
01924 LM_ERR("out of pkg memory\n");
01925 return -1;
01926 }
01927 offset = oldport->s - msg->buf;
01928 anchor = del_lump(msg, offset, oldport->len, 0);
01929 if (anchor == NULL) {
01930 LM_ERR("del_lump failed\n");
01931 pkg_free(buf);
01932 return -1;
01933 }
01934 memcpy(buf, newport->s, newport->len);
01935 if (insert_new_lump_after(anchor, buf, newport->len, 0) == 0) {
01936 LM_ERR("insert_new_lump_after failed\n");
01937 pkg_free(buf);
01938 return -1;
01939 }
01940
01941 #if 0
01942 msg->msg_flags |= FL_SDP_PORT_AFS;
01943 #endif
01944 return 0;
01945 }
01946
01947
01948
01949
01950 static int
01951 alter_rtcp(struct sip_msg *msg, str *body, str *oldport, str *newport)
01952 {
01953 char *buf;
01954 int offset;
01955 struct lump* anchor;
01956
01957
01958 if (newport->len == oldport->len &&
01959 memcmp(newport->s, oldport->s, newport->len) == 0)
01960 return 0;
01961
01962 buf = pkg_malloc(newport->len);
01963 if (buf == NULL) {
01964 LM_ERR("alter_rtcp: out of memory\n");
01965 return -1;
01966 }
01967 offset = oldport->s - msg->buf;
01968 anchor = del_lump(msg, offset, oldport->len, 0);
01969 if (anchor == NULL) {
01970 LM_ERR("alter_rtcp: del_lump failed\n");
01971 pkg_free(buf);
01972 return -1;
01973 }
01974 memcpy(buf, newport->s, newport->len);
01975 if (insert_new_lump_after(anchor, buf, newport->len, 0) == 0) {
01976 LM_ERR("alter_rtcp: insert_new_lump_after failed\n");
01977 pkg_free(buf);
01978 return -1;
01979 }
01980
01981 return 0;
01982 }
01983
01984 static char * gencookie(void)
01985 {
01986 static char cook[34];
01987
01988 sprintf(cook, "%d_%u ", (int)mypid, myseqn);
01989 myseqn++;
01990 return cook;
01991 }
01992
01993 static int
01994 rtpp_checkcap(struct rtpp_node *node, char *cap, int caplen)
01995 {
01996 char *cp;
01997 struct iovec vf[4] = {{NULL, 0}, {"VF", 2}, {" ", 1}, {NULL, 0}};
01998
01999 vf[3].iov_base = cap;
02000 vf[3].iov_len = caplen;
02001
02002 cp = send_rtpp_command(node, vf, 4);
02003 if (cp == NULL)
02004 return -1;
02005 if (cp[0] == 'E' || atoi(cp) != 1)
02006 return 0;
02007 return 1;
02008 }
02009
02010 static int
02011 rtpp_test(struct rtpp_node *node, int isdisabled, int force)
02012 {
02013 int rtpp_ver, rval;
02014 char *cp;
02015 struct iovec v[2] = {{NULL, 0}, {"V", 1}};
02016
02017 if(node->rn_recheck_ticks == MI_MAX_RECHECK_TICKS){
02018 LM_DBG("rtpp %s disabled for ever\n", node->rn_url.s);
02019 return 1;
02020 }
02021
02022 if (force == 0) {
02023 if (isdisabled == 0)
02024 return 0;
02025 if (node->rn_recheck_ticks > get_ticks())
02026 return 1;
02027 }
02028 cp = send_rtpp_command(node, v, 2);
02029 if (cp == NULL) {
02030 LM_WARN("can't get version of the RTP proxy\n");
02031 goto error;
02032 }
02033 rtpp_ver = atoi(cp);
02034 if (rtpp_ver != SUP_CPROTOVER) {
02035 LM_WARN("unsupported version of RTP proxy <%s> found: %d supported,"
02036 "%d present\n", node->rn_url.s, SUP_CPROTOVER, rtpp_ver);
02037 goto error;
02038 }
02039 rval = rtpp_checkcap(node, REQ_CPROTOVER, sizeof(REQ_CPROTOVER) - 1);
02040 if (rval == -1) {
02041 LM_WARN("RTP proxy went down during version query\n");
02042 goto error;
02043 }
02044 if (rval == 0) {
02045 LM_WARN("of RTP proxy <%s> doesn't support required protocol version"
02046 "%s\n", node->rn_url.s, REQ_CPROTOVER);
02047 goto error;
02048 }
02049 LM_INFO("rtp proxy <%s> found, support for it %senabled\n",
02050 node->rn_url.s, force == 0 ? "re-" : "");
02051
02052 rval = rtpp_checkcap(node, REP_CPROTOVER, sizeof(REP_CPROTOVER) - 1);
02053 if (rval != -1) {
02054 node->rn_rep_supported = rval;
02055 } else {
02056 node->rn_rep_supported = 0;
02057 }
02058 rval = rtpp_checkcap(node, PTL_CPROTOVER, sizeof(PTL_CPROTOVER) - 1);
02059 if (rval != -1) {
02060 node->rn_ptl_supported = rval;
02061 } else {
02062 node->rn_ptl_supported = 0;
02063 }
02064 return 0;
02065 error:
02066 LM_WARN("support for RTP proxy <%s> has been disabled%s\n", node->rn_url.s,
02067 rtpproxy_disable_tout < 0 ? "" : " temporarily");
02068 if (rtpproxy_disable_tout >= 0)
02069 node->rn_recheck_ticks = get_ticks() + rtpproxy_disable_tout;
02070
02071 return 1;
02072 }
02073
02074 char *
02075 send_rtpp_command(struct rtpp_node *node, struct iovec *v, int vcnt)
02076 {
02077 struct sockaddr_un addr;
02078 int fd, len, i;
02079 char *cp;
02080 static char buf[256];
02081 struct pollfd fds[1];
02082
02083 len = 0;
02084 cp = buf;
02085 if (node->rn_umode == 0) {
02086 memset(&addr, 0, sizeof(addr));
02087 addr.sun_family = AF_LOCAL;
02088 strncpy(addr.sun_path, node->rn_address,
02089 sizeof(addr.sun_path) - 1);
02090 #ifdef HAVE_SOCKADDR_SA_LEN
02091 addr.sun_len = strlen(addr.sun_path);
02092 #endif
02093
02094 fd = socket(AF_LOCAL, SOCK_STREAM, 0);
02095 if (fd < 0) {
02096 LM_ERR("can't create socket\n");
02097 goto badproxy;
02098 }
02099 if (connect(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
02100 close(fd);
02101 LM_ERR("can't connect to RTP proxy\n");
02102 goto badproxy;
02103 }
02104
02105 do {
02106 len = writev(fd, v + 1, vcnt - 1);
02107 } while (len == -1 && errno == EINTR);
02108 if (len <= 0) {
02109 close(fd);
02110 LM_ERR("can't send command to a RTP proxy\n");
02111 goto badproxy;
02112 }
02113 do {
02114 len = read(fd, buf, sizeof(buf) - 1);
02115 } while (len == -1 && errno == EINTR);
02116 close(fd);
02117 if (len <= 0) {
02118 LM_ERR("can't read reply from a RTP proxy\n");
02119 goto badproxy;
02120 }
02121 } else {
02122 fds[0].fd = rtpp_socks[node->idx];
02123 fds[0].events = POLLIN;
02124 fds[0].revents = 0;
02125
02126 while ((poll(fds, 1, 0) == 1) &&
02127 ((fds[0].revents & POLLIN) != 0)) {
02128 recv(rtpp_socks[node->idx], buf, sizeof(buf) - 1, 0);
02129 fds[0].revents = 0;
02130 }
02131 v[0].iov_base = gencookie();
02132 v[0].iov_len = strlen(v[0].iov_base);
02133 for (i = 0; i < rtpproxy_retr; i++) {
02134 do {
02135 len = writev(rtpp_socks[node->idx], v, vcnt);
02136 } while (len == -1 && (errno == EINTR || errno == ENOBUFS));
02137 if (len <= 0) {
02138 LM_ERR("can't send command to a RTP proxy\n");
02139 goto badproxy;
02140 }
02141 while ((poll(fds, 1, rtpproxy_tout * 1000) == 1) &&
02142 (fds[0].revents & POLLIN) != 0) {
02143 do {
02144 len = recv(rtpp_socks[node->idx], buf, sizeof(buf)-1, 0);
02145 } while (len == -1 && errno == EINTR);
02146 if (len <= 0) {
02147 LM_ERR("can't read reply from a RTP proxy\n");
02148 goto badproxy;
02149 }
02150 if (len >= (v[0].iov_len - 1) &&
02151 memcmp(buf, v[0].iov_base, (v[0].iov_len - 1)) == 0) {
02152 len -= (v[0].iov_len - 1);
02153 cp += (v[0].iov_len - 1);
02154 if (len != 0) {
02155 len--;
02156 cp++;
02157 }
02158 goto out;
02159 }
02160 fds[0].revents = 0;
02161 }
02162 }
02163 if (i == rtpproxy_retr) {
02164 LM_ERR("timeout waiting reply from a RTP proxy\n");
02165 goto badproxy;
02166 }
02167 }
02168
02169 out:
02170 cp[len] = '\0';
02171 return cp;
02172 badproxy:
02173 LM_ERR("proxy <%s> does not respond, disable it\n", node->rn_url.s);
02174 node->rn_disabled = 1;
02175 node->rn_recheck_ticks = get_ticks() + rtpproxy_disable_tout;
02176
02177 return NULL;
02178 }
02179
02180
02181
02182
02183
02184 static struct rtpp_set * select_rtpp_set(int id_set ){
02185
02186 struct rtpp_set * rtpp_list;
02187
02188
02189 if(!rtpp_set_list || !rtpp_set_list->rset_first){
02190 LM_ERR("no rtp_proxy configured\n");
02191 return 0;
02192 }
02193
02194 for(rtpp_list=rtpp_set_list->rset_first; rtpp_list!=0 &&
02195 rtpp_list->id_set!=id_set; rtpp_list=rtpp_list->rset_next);
02196 if(!rtpp_list){
02197 LM_ERR(" script error-invalid id_set to be selected\n");
02198 }
02199
02200 return rtpp_list;
02201 }
02202
02203
02204
02205
02206
02207
02208 struct rtpp_node *
02209 select_rtpp_node(str callid, int do_test)
02210 {
02211 unsigned sum, sumcut, weight_sum;
02212 struct rtpp_node* node;
02213 int was_forced;
02214
02215 if(!selected_rtpp_set){
02216 LM_ERR("script error -no valid set selected\n");
02217 return NULL;
02218 }
02219
02220 if (selected_rtpp_set->rtpp_node_count == 1) {
02221 node = selected_rtpp_set->rn_first;
02222 if (node->rn_disabled && node->rn_recheck_ticks <= get_ticks())
02223 node->rn_disabled = rtpp_test(node, 1, 0);
02224 return node->rn_disabled ? NULL : node;
02225 }
02226
02227
02228 for(sum = 0; callid.len > 0; callid.len--)
02229 sum += callid.s[callid.len - 1];
02230 sum &= 0xff;
02231
02232 was_forced = 0;
02233 retry:
02234 weight_sum = 0;
02235 for (node=selected_rtpp_set->rn_first; node!=NULL; node=node->rn_next) {
02236
02237 if (node->rn_disabled && node->rn_recheck_ticks <= get_ticks()){
02238
02239 node->rn_disabled = rtpp_test(node, 1, 0);
02240 }
02241 if (!node->rn_disabled)
02242 weight_sum += node->rn_weight;
02243 }
02244 if (weight_sum == 0) {
02245
02246 if (was_forced)
02247 return NULL;
02248 was_forced = 1;
02249 for(node=selected_rtpp_set->rn_first; node!=NULL; node=node->rn_next) {
02250 node->rn_disabled = rtpp_test(node, 1, 1);
02251 }
02252 goto retry;
02253 }
02254 sumcut = sum % weight_sum;
02255
02256
02257
02258
02259 for (node=selected_rtpp_set->rn_first; node!=NULL; node=node->rn_next) {
02260 if (node->rn_disabled)
02261 continue;
02262 if (sumcut < node->rn_weight)
02263 goto found;
02264 sumcut -= node->rn_weight;
02265 }
02266
02267 return NULL;
02268 found:
02269 if (do_test) {
02270 node->rn_disabled = rtpp_test(node, node->rn_disabled, 0);
02271 if (node->rn_disabled)
02272 goto retry;
02273 }
02274 return node;
02275 }
02276
02277 static int
02278 unforce_rtp_proxy_f(struct sip_msg* msg, char* str1, char* str2)
02279 {
02280 str callid, from_tag, to_tag;
02281 struct rtpp_node *node;
02282 struct iovec v[1 + 4 + 3] = {{NULL, 0}, {"D", 1}, {" ", 1}, {NULL, 0}, {" ", 1}, {NULL, 0}, {" ", 1}, {NULL, 0}};
02283
02284
02285 if (get_callid(msg, &callid) == -1 || callid.len == 0) {
02286 LM_ERR("can't get Call-Id field\n");
02287 return -1;
02288 }
02289 to_tag.s = 0;
02290 if (get_to_tag(msg, &to_tag) == -1) {
02291 LM_ERR("can't get To tag\n");
02292 return -1;
02293 }
02294 if (get_from_tag(msg, &from_tag) == -1 || from_tag.len == 0) {
02295 LM_ERR("can't get From tag\n");
02296 return -1;
02297 }
02298 STR2IOVEC(callid, v[3]);
02299 STR2IOVEC(from_tag, v[5]);
02300 STR2IOVEC(to_tag, v[7]);
02301
02302 if(msg->id != current_msg_id){
02303 selected_rtpp_set = default_rtpp_set;
02304 }
02305
02306 node = select_rtpp_node(callid, 1);
02307 if (!node) {
02308 LM_ERR("no available proxies\n");
02309 return -1;
02310 }
02311 send_rtpp_command(node, v, (to_tag.len > 0) ? 8 : 6);
02312
02313 return 1;
02314 }
02315
02316
02317
02318
02319
02320
02321 static char *
02322 find_sdp_line(char* p, char* plimit, char linechar)
02323 {
02324 static char linehead[3] = "x=";
02325 char *cp, *cp1;
02326 linehead[0] = linechar;
02327
02328 cp = p;
02329 for (;;) {
02330 if (cp >= plimit)
02331 return NULL;
02332 cp1 = ser_memmem(cp, linehead, plimit-cp, 2);
02333 if (cp1 == NULL)
02334 return NULL;
02335
02336
02337
02338
02339 if (cp1[-1] == '\n' || cp1[-1] == '\r')
02340 return cp1;
02341
02342
02343
02344
02345
02346 if (plimit - cp1 < 2)
02347 return NULL;
02348 cp = cp1 + 2;
02349 }
02350 }
02351
02352
02353
02354 static char *
02355 find_next_sdp_line(char* p, char* plimit, char linechar, char* defptr)
02356 {
02357 char *t;
02358 if (p >= plimit || plimit - p < 3)
02359 return defptr;
02360 t = find_sdp_line(p + 2, plimit, linechar);
02361 return t ? t : defptr;
02362 }
02363
02364 static int
02365 set_rtp_proxy_set_f(struct sip_msg * msg, char * str1, char * str2)
02366 {
02367 current_msg_id = msg->id;
02368 selected_rtpp_set = (struct rtpp_set *)str1;
02369 return 1;
02370 }
02371
02372 static int
02373 rtpproxy_offer1_f(struct sip_msg *msg, char *str1, char *str2)
02374 {
02375 char *cp;
02376 char newip[IP_ADDR_MAX_STR_SIZE];
02377
02378 cp = ip_addr2a(&msg->rcv.dst_ip);
02379 strcpy(newip, cp);
02380 return rtpproxy_offer2_f(msg, str1, newip);
02381 }
02382
02383 static int
02384 rtpproxy_offer2_f(struct sip_msg *msg, char *param1, char *param2)
02385 {
02386
02387 if (msg->first_line.type == SIP_REQUEST)
02388 if (msg->first_line.u.request.method_value != METHOD_INVITE)
02389 return -1;
02390
02391 return force_rtp_proxy(msg, param1, param2, 1);
02392 }
02393
02394 static int
02395 rtpproxy_answer1_f(struct sip_msg *msg, char *str1, char *str2)
02396 {
02397 char *cp;
02398 char newip[IP_ADDR_MAX_STR_SIZE];
02399
02400 cp = ip_addr2a(&msg->rcv.dst_ip);
02401 strcpy(newip, cp);
02402 return rtpproxy_answer2_f(msg, str1, newip);
02403 }
02404
02405 static int
02406 rtpproxy_answer2_f(struct sip_msg *msg, char *param1, char *param2)
02407 {
02408
02409 if (msg->first_line.type == SIP_REQUEST)
02410 if (msg->first_line.u.request.method_value != METHOD_ACK)
02411 return -1;
02412
02413 return force_rtp_proxy(msg, param1, param2, 0);
02414 }
02415
02416 static int
02417 force_rtp_proxy2_f(struct sip_msg *msg, char *param1, char *param2)
02418 {
02419 int offer;
02420
02421 if (msg->first_line.type == SIP_REQUEST &&
02422 msg->first_line.u.request.method_value == METHOD_INVITE) {
02423 offer = 1;
02424 } else if (msg->first_line.type == SIP_REPLY) {
02425 offer = 0;
02426 } else {
02427 return -1;
02428 }
02429
02430 return force_rtp_proxy(msg, param1, param2, offer);
02431 }
02432
02433 static int
02434 force_rtp_proxy(struct sip_msg* msg, char* str1, char* str2, int offer)
02435 {
02436 str body, body1, oldport, oldip, newport, newip;
02437 str callid, from_tag, to_tag, tmp, payload_types;
02438 str oldrtcp, newrtcp;
02439 int create, port, len, asymmetric, flookup, argc, proxied, real;
02440 int orgip, commip;
02441 int oidx, pf, pf1, force, swap, rep_oidx;
02442 char opts[32];
02443 char rep_opts[16];
02444 char *cp, *cp1;
02445 char *cpend, *next;
02446 char **ap, *argv[10];
02447 struct lump* anchor;
02448 struct rtpp_node *node;
02449 struct iovec v[16] = {
02450 {NULL, 0},
02451 {NULL, 0},
02452 {" ", 1},
02453 {NULL, 0},
02454 {" ", 1},
02455 {NULL, 7},
02456 {" ", 1},
02457 {NULL, 1},
02458 {" ", 1},
02459 {NULL, 0},
02460 {";", 1},
02461 {NULL, 0},
02462 {" ", 1},
02463 {NULL, 0},
02464 {";", 1},
02465 {NULL, 0}
02466 };
02467 char *v1p, *v2p, *c1p, *c2p, *m1p, *m2p, *bodylimit, *o1p;
02468 char medianum_buf[20];
02469 int medianum, media_multi;
02470 str medianum_str, tmpstr1;
02471 int c1p_altered;
02472 static int swap_warned = 0;
02473
02474 v[1].iov_base=opts;
02475 asymmetric = flookup = force = real = orgip = commip = swap = 0;
02476 oidx = 1;
02477 rep_oidx = 0;
02478 for (cp = str1; cp != NULL && *cp != '\0'; cp++) {
02479 switch (*cp) {
02480 case 'a':
02481 case 'A':
02482 opts[oidx++] = 'A';
02483 asymmetric = 1;
02484 real = 1;
02485 break;
02486
02487 case 'i':
02488 case 'I':
02489 opts[oidx++] = 'I';
02490 break;
02491
02492 case 'e':
02493 case 'E':
02494 opts[oidx++] = 'E';
02495 break;
02496
02497 case 'l':
02498 case 'L':
02499 if (offer == 0)
02500 return -1;
02501 flookup = 1;
02502 break;
02503
02504 case 'f':
02505 case 'F':
02506 force = 1;
02507 break;
02508
02509 case 'r':
02510 case 'R':
02511 real = 1;
02512 break;
02513
02514 case 'c':
02515 case 'C':
02516 commip = 1;
02517 break;
02518
02519 case 'o':
02520 case 'O':
02521 orgip = 1;
02522 break;
02523
02524 case 's':
02525 case 'S':
02526 swap = 1;
02527 if (swap_warned != 0)
02528 break;
02529 LM_WARN("swap flag (`%c') is depreciated, use "
02530 "rtpproxy_offer() and rtpproxy_answer() "
02531 "instead\n", *cp);
02532 swap_warned = 1;
02533 break;
02534
02535 case 'w':
02536 case 'W':
02537 opts[oidx++] = 'S';
02538 break;
02539
02540 case 'z':
02541 case 'Z':
02542 rep_opts[rep_oidx++] = 'Z';
02543
02544 for (; cp[1] != '\0' && isdigit(cp[1]); cp++)
02545 rep_opts[rep_oidx++] = cp[1];
02546 break;
02547
02548 default:
02549 LM_ERR("unknown option `%c'\n", *cp);
02550 return -1;
02551 }
02552 }
02553
02554 if (offer != 0) {
02555 create = swap?0:1;
02556 } else {
02557 create = swap?1:0;
02558 }
02559
02560
02561
02562 if (extract_body(msg, &body) == -1) {
02563 LM_ERR("can't extract body from the message\n");
02564 return -1;
02565 }
02566 if (get_callid(msg, &callid) == -1 || callid.len == 0) {
02567 LM_ERR("can't get Call-Id field\n");
02568 return -1;
02569 }
02570 to_tag.s = 0;
02571 if (get_to_tag(msg, &to_tag) == -1) {
02572 LM_ERR("can't get To tag\n");
02573 return -1;
02574 }
02575 if (get_from_tag(msg, &from_tag) == -1 || from_tag.len == 0) {
02576 LM_ERR("can't get From tag\n");
02577 return -1;
02578 }
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592 if (flookup != 0) {
02593 if (to_tag.len == 0)
02594 return -1;
02595 create = 0;
02596 if (swap != 0) {
02597 tmp = from_tag;
02598 from_tag = to_tag;
02599 to_tag = tmp;
02600 }
02601 } else if (swap != 0 || (msg->first_line.type == SIP_REPLY && offer != 0)) {
02602 if (to_tag.len == 0)
02603 return -1;
02604 tmp = from_tag;
02605 from_tag = to_tag;
02606 to_tag = tmp;
02607 }
02608 proxied = 0;
02609 if (nortpproxy_str.len) {
02610 for ( cp=body.s ; (len=body.s+body.len-cp) >= nortpproxy_str.len ; ) {
02611 cp1 = ser_memmem(cp, nortpproxy_str.s, len, nortpproxy_str.len);
02612 if (cp1 == NULL)
02613 break;
02614 if (cp1[-1] == '\n' || cp1[-1] == '\r') {
02615 proxied = 1;
02616 break;
02617 }
02618 cp = cp1 + nortpproxy_str.len;
02619 }
02620 }
02621 if (proxied != 0 && force == 0)
02622 return -1;
02623
02624
02625
02626
02627
02628
02629
02630
02631
02632
02633
02634
02635 bodylimit = body.s + body.len;
02636 v1p = find_sdp_line(body.s, bodylimit, 'v');
02637 if (v1p == NULL) {
02638 LM_ERR("no sessions in SDP\n");
02639 return -1;
02640 }
02641 v2p = find_next_sdp_line(v1p, bodylimit, 'v', bodylimit);
02642 media_multi = (v2p != bodylimit);
02643 v2p = v1p;
02644 medianum = 0;
02645
02646 if(msg->id != current_msg_id){
02647 selected_rtpp_set = default_rtpp_set;
02648 }
02649
02650 for(;;) {
02651
02652 v1p = v2p;
02653 if (v1p == NULL || v1p >= bodylimit)
02654 break;
02655 v2p = find_next_sdp_line(v1p, bodylimit, 'v', bodylimit);
02656
02657
02658 o1p = find_sdp_line(v1p, v2p, 'o');
02659 if (o1p==0) {
02660 LM_ERR("no o= in session\n");
02661 return -1;
02662 }
02663
02664 m1p = find_sdp_line(o1p, v2p, 'm');
02665 if (m1p == NULL) {
02666 LM_ERR("no m= in session\n");
02667 return -1;
02668 }
02669
02670
02671
02672
02673 c1p = find_sdp_line(o1p, m1p, 'c');
02674 c1p_altered = 0;
02675 if (orgip==0)
02676 o1p = 0;
02677
02678 m2p = m1p;
02679 for (;;) {
02680 m1p = m2p;
02681 if (m1p == NULL || m1p >= v2p)
02682 break;
02683 m2p = find_next_sdp_line(m1p, v2p, 'm', v2p);
02684
02685 c2p = find_sdp_line(m1p, m2p, 'c');
02686
02687 tmpstr1.s = c2p ? c2p : c1p;
02688 if (tmpstr1.s == NULL) {
02689
02690 LM_ERR("can't find media IP in the message\n");
02691 return -1;
02692 }
02693 tmpstr1.len = v2p - tmpstr1.s;
02694 if (extract_mediaip(&tmpstr1, &oldip, &pf,"c=") == -1) {
02695 LM_ERR("can't extract media IP from the message\n");
02696 return -1;
02697 }
02698 tmpstr1.s = m1p;
02699 tmpstr1.len = m2p - m1p;
02700 if (extract_mediainfo(&tmpstr1, &oldport, &payload_types) == -1) {
02701 LM_ERR("can't extract media port from the message\n");
02702 return -1;
02703 }
02704
02705 tmpstr1.s = m1p;
02706 tmpstr1.len = m2p - m1p;
02707 oldrtcp.s = NULL;
02708 oldrtcp.len = 0;
02709 extract_rtcp(&tmpstr1, &oldrtcp);
02710
02711 ++medianum;
02712 if (asymmetric != 0 || real != 0) {
02713 newip = oldip;
02714 } else {
02715 newip.s = ip_addr2a(&msg->rcv.src_ip);
02716 newip.len = strlen(newip.s);
02717 }
02718
02719 if (pf == AF_INET6) {
02720 opts[oidx] = '6';
02721 oidx++;
02722 }
02723 opts[0] = (create == 0) ? 'L' : 'U';
02724 v[1].iov_len = oidx;
02725 STR2IOVEC(callid, v[3]);
02726 STR2IOVEC(newip, v[5]);
02727 STR2IOVEC(oldport, v[7]);
02728 STR2IOVEC(from_tag, v[9]);
02729 if (1 || media_multi)
02730 {
02731 snprintf(medianum_buf, sizeof medianum_buf, "%d", medianum);
02732 medianum_str.s = medianum_buf;
02733 medianum_str.len = strlen(medianum_buf);
02734 STR2IOVEC(medianum_str, v[11]);
02735 STR2IOVEC(medianum_str, v[15]);
02736 } else {
02737 v[10].iov_len = v[11].iov_len = 0;
02738 v[14].iov_len = v[15].iov_len = 0;
02739 }
02740 STR2IOVEC(to_tag, v[13]);
02741 do {
02742 node = select_rtpp_node(callid, 1);
02743 if (!node) {
02744 LM_ERR("no available proxies\n");
02745 return -1;
02746 }
02747 len = v[1].iov_len;
02748 if (rep_oidx > 0) {
02749 if (node->rn_rep_supported == 0) {
02750 LM_WARN("re-packetization is requested but is not "
02751 "supported by the selected RTP proxy node\n");
02752 } else {
02753 memcpy((char *)v[1].iov_base + v[1].iov_len,
02754 rep_opts, rep_oidx);
02755 v[1].iov_len += rep_oidx;
02756 }
02757 }
02758 if (payload_types.len > 0 && node->rn_ptl_supported != 0) {
02759 cp1 = (char *)v[1].iov_base + v[1].iov_len;
02760 *cp1 = 'c';
02761 cp1++;
02762
02763
02764
02765
02766 for (cp = payload_types.s;
02767 cp < payload_types.s + payload_types.len; cp++) {
02768 if (isdigit(*cp)) {
02769 *cp1 = *cp;
02770 cp1++;
02771 continue;
02772 }
02773 *cp1 = ',';
02774 cp1++;
02775 do {
02776 cp++;
02777 } while (!isdigit(*cp) &&
02778 cp < payload_types.s + payload_types.len);
02779 cp--;
02780 }
02781 v[1].iov_len = cp1 - (char *)v[1].iov_base;
02782 }
02783 cp = send_rtpp_command(node, v, (to_tag.len > 0) ? 16 : 12);
02784 v[1].iov_len = len;
02785 } while (cp == NULL);
02786 LM_DBG("proxy reply: %s\n", cp);
02787
02788 argc = 0;
02789 memset(argv, 0, sizeof(argv));
02790 cpend=cp+strlen(cp);
02791 next=eat_token_end(cp, cpend);
02792 for (ap=argv; cp<cpend; cp=next+1, next=eat_token_end(cp, cpend)){
02793 *next=0;
02794 if (*cp != '\0') {
02795 *ap=cp;
02796 argc++;
02797 if ((char*)++ap >= ((char*)argv+sizeof(argv)))
02798 break;
02799 }
02800 }
02801 if (argc < 1) {
02802 LM_ERR("no reply from rtp proxy\n");
02803 return -1;
02804 }
02805 port = atoi(argv[0]);
02806 if (port <= 0 || port > 65535) {
02807 if (port != 0 || flookup == 0)
02808 LM_ERR("incorrect port %i in reply "
02809 "from rtp proxy\n",port);
02810 return -1;
02811 }
02812
02813 pf1 = (argc >= 3 && argv[2][0] == '6') ? AF_INET6 : AF_INET;
02814
02815 if (isnulladdr(&oldip, pf)) {
02816 if (pf1 == AF_INET6) {
02817 newip.s = "::";
02818 newip.len = 2;
02819 } else {
02820 newip.s = "0.0.0.0";
02821 newip.len = 7;
02822 }
02823 } else {
02824 newip.s = (argc < 2) ? str2 : argv[1];
02825 newip.len = strlen(newip.s);
02826 }
02827
02828 newport.s = int2str(port, &newport.len);
02829
02830 body1.s = m1p;
02831 body1.len = bodylimit - body1.s;
02832
02833
02834
02835
02836
02837 if(oldport.len!=1 || oldport.s[0]!='0')
02838 {
02839 if (alter_mediaport(msg, &body1, &oldport, &newport, 0) == -1)
02840 return -1;
02841 }
02842
02843
02844
02845
02846
02847
02848
02849
02850 if (oldrtcp.s && oldrtcp.len) {
02851 newrtcp.s = int2str(port+1, &newrtcp.len);
02852
02853 body1.s = m1p;
02854 body1.len = bodylimit - body1.s;
02855 if (alter_rtcp(msg, &body1, &oldrtcp, &newrtcp) == -1)
02856 return -1;
02857 }
02858
02859
02860
02861
02862
02863
02864 if (c2p != NULL || !c1p_altered) {
02865 body1.s = c2p ? c2p : c1p;
02866 body1.len = bodylimit - body1.s;
02867 if (alter_mediaip(msg, &body1, &oldip, pf, &newip, pf1, 0)==-1)
02868 return -1;
02869 if (!c2p)
02870 c1p_altered = 1;
02871 }
02872
02873
02874
02875 if (commip && c1p && !c1p_altered) {
02876 tmpstr1.s = c1p;
02877 tmpstr1.len = v2p - tmpstr1.s;
02878 if (extract_mediaip(&tmpstr1, &oldip, &pf,"c=") == -1) {
02879 LM_ERR("can't extract media IP from the message\n");
02880 return -1;
02881 }
02882 body1.s = c1p;
02883 body1.len = bodylimit - body1.s;
02884 if (alter_mediaip(msg, &body1, &oldip, pf, &newip, pf1, 0)==-1)
02885 return -1;
02886 c1p_altered = 1;
02887 }
02888
02889
02890
02891 if (o1p) {
02892 tmpstr1.s = o1p;
02893 tmpstr1.len = v2p - tmpstr1.s;
02894 if (extract_mediaip(&tmpstr1, &oldip, &pf,"o=") == -1) {
02895 LM_ERR("can't extract media IP from the message\n");
02896 return -1;
02897 }
02898 body1.s = o1p;
02899 body1.len = bodylimit - body1.s;
02900 if (alter_mediaip(msg, &body1, &oldip, pf, &newip, pf1, 0)==-1)
02901 return -1;
02902 o1p = 0;
02903 }
02904 }
02905 }
02906
02907 if (proxied == 0 && nortpproxy_str.len) {
02908 cp = pkg_malloc((nortpproxy_str.len + CRLF_LEN) * sizeof(char));
02909 if (cp == NULL) {
02910 LM_ERR("out of pkg memory\n");
02911 return -1;
02912 }
02913 anchor = anchor_lump(msg, body.s + body.len - msg->buf, 0, 0);
02914 if (anchor == NULL) {
02915 LM_ERR("anchor_lump failed\n");
02916 pkg_free(cp);
02917 return -1;
02918 }
02919 memcpy(cp, CRLF, CRLF_LEN);
02920 memcpy(cp + CRLF_LEN, nortpproxy_str.s, nortpproxy_str.len);
02921 if (insert_new_lump_after(anchor, cp, nortpproxy_str.len + CRLF_LEN, 0) == NULL) {
02922 LM_ERR("insert_new_lump_after failed\n");
02923 pkg_free(cp);
02924 return -1;
02925 }
02926 }
02927
02928 return 1;
02929 }
02930
02931 static int
02932 force_rtp_proxy1_f(struct sip_msg* msg, char* str1, char* str2)
02933 {
02934 char *cp;
02935 char newip[IP_ADDR_MAX_STR_SIZE];
02936
02937 cp = ip_addr2a(&msg->rcv.dst_ip);
02938 strcpy(newip, cp);
02939
02940 return force_rtp_proxy2_f(msg, str1, newip);
02941 }
02942
02943 static int
02944 force_rtp_proxy0_f(struct sip_msg* msg, char* str1, char* str2)
02945 {
02946 char arg[1] = {'\0'};
02947
02948 return force_rtp_proxy1_f(msg, arg, NULL);
02949 }
02950
02951
02952 static u_short raw_checksum(unsigned char *buffer, int len)
02953 {
02954 u_long sum = 0;
02955
02956 while (len > 1) {
02957 sum += *buffer << 8;
02958 buffer++;
02959 sum += *buffer;
02960 buffer++;
02961 len -= 2;
02962 }
02963 if (len) {
02964 sum += *buffer << 8;
02965 }
02966 sum = (sum >> 16) + (sum & 0xffff);
02967 sum = (sum >> 16) + (sum);
02968
02969 return (u_short) ~sum;
02970 }
02971
02972
02973 static int send_raw(const char *buf, int buf_len, union sockaddr_union *to,
02974 const unsigned int s_ip, const unsigned int s_port)
02975 {
02976 struct ip *ip;
02977 struct udphdr *udp;
02978 unsigned char packet[50];
02979 int len = sizeof(struct ip) + sizeof(struct udphdr) + buf_len;
02980
02981 if (len > sizeof(packet)) {
02982 LM_ERR("payload too big\n");
02983 return -1;
02984 }
02985
02986 ip = (struct ip*) packet;
02987 udp = (struct udphdr *) (packet + sizeof(struct ip));
02988 memcpy(packet + sizeof(struct ip) + sizeof(struct udphdr), buf, buf_len);
02989
02990 ip->ip_v = 4;
02991 ip->ip_hl = sizeof(struct ip) / 4;
02992 ip->ip_tos = 0;
02993 ip->ip_len = htons(len);
02994 ip->ip_id = 23;
02995 ip->ip_off = 0;
02996 ip->ip_ttl = 69;
02997 ip->ip_p = 17;
02998 ip->ip_src.s_addr = s_ip;
02999 ip->ip_dst.s_addr = to->sin.sin_addr.s_addr;
03000
03001 ip->ip_sum = raw_checksum((unsigned char *) ip, sizeof(struct ip));
03002
03003 udp->uh_sport = htons(s_port);
03004 udp->uh_dport = to->sin.sin_port;
03005 udp->uh_ulen = htons((unsigned short) sizeof(struct udphdr) + buf_len);
03006 udp->uh_sum = 0;
03007
03008 return sendto(raw_sock, packet, len, 0, (struct sockaddr *) to, sizeof(struct sockaddr_in));
03009 }
03010
03011
03012 static void
03013 nh_timer(unsigned int ticks, void *timer_idx)
03014 {
03015 static unsigned int iteration = 0;
03016 int rval;
03017 void *buf, *cp;
03018 str c;
03019 str opt;
03020 str path;
03021 struct sip_uri curi;
03022 union sockaddr_union to;
03023 struct hostent* he;
03024 struct socket_info* send_sock;
03025 unsigned int flags;
03026 unsigned short proto;
03027
03028 if((*natping_state) == 0)
03029 goto done;
03030
03031 buf = NULL;
03032 if (cblen > 0) {
03033 buf = pkg_malloc(cblen);
03034 if (buf == NULL) {
03035 LM_ERR("out of pkg memory\n");
03036 goto done;
03037 }
03038 }
03039 rval = ul.get_all_ucontacts(buf, cblen, (ping_nated_only?ul.nat_flag:0),
03040 ((unsigned int)(unsigned long)timer_idx)*natping_interval+iteration,
03041 natping_processes*natping_interval);
03042 if (rval<0) {
03043 LM_ERR("failed to fetch contacts\n");
03044 goto done;
03045 }
03046 if (rval > 0) {
03047 if (buf != NULL)
03048 pkg_free(buf);
03049 cblen = rval * 2;
03050 buf = pkg_malloc(cblen);
03051 if (buf == NULL) {
03052 LM_ERR("out of pkg memory\n");
03053 goto done;
03054 }
03055 rval = ul.get_all_ucontacts(buf,cblen,(ping_nated_only?ul.nat_flag:0),
03056 ((unsigned int)(unsigned long)timer_idx)*natping_interval+iteration,
03057 natping_processes*natping_interval);
03058 if (rval != 0) {
03059 pkg_free(buf);
03060 goto done;
03061 }
03062 }
03063
03064 if (buf == NULL)
03065 goto done;
03066
03067 cp = buf;
03068 while (1) {
03069 memcpy(&(c.len), cp, sizeof(c.len));
03070 if (c.len == 0)
03071 break;
03072 c.s = (char*)cp + sizeof(c.len);
03073 cp = (char*)cp + sizeof(c.len) + c.len;
03074 memcpy( &send_sock, cp, sizeof(send_sock));
03075 cp = (char*)cp + sizeof(send_sock);
03076 memcpy( &flags, cp, sizeof(flags));
03077 cp = (char*)cp + sizeof(flags);
03078 memcpy( &(path.len), cp, sizeof(path.len));
03079 path.s = path.len ? ((char*)cp + sizeof(path.len)) : NULL ;
03080 cp = (char*)cp + sizeof(path.len) + path.len;
03081
03082
03083 if ( path.len && (flags&sipping_flag)!=0 ) {
03084
03085 if (get_path_dst_uri( &path, &opt) < 0) {
03086 LM_ERR("failed to get dst_uri for Path\n");
03087 continue;
03088 }
03089
03090 if (parse_uri(opt.s, opt.len, &curi) < 0) {
03091 LM_ERR("can't parse contact dst_uri\n");
03092 continue;
03093 }
03094 } else {
03095
03096 if (parse_uri(c.s, c.len, &curi) < 0) {
03097 LM_ERR("can't parse contact uri\n");
03098 continue;
03099 }
03100 }
03101 if (curi.proto != PROTO_UDP && curi.proto != PROTO_NONE)
03102 continue;
03103 if (curi.port_no == 0)
03104 curi.port_no = SIP_PORT;
03105 proto = curi.proto;
03106
03107
03108 he = sip_resolvehost(&curi.host, &curi.port_no, &proto, 0, 0);
03109 if (he == NULL){
03110 LM_ERR("can't resolve_host\n");
03111 continue;
03112 }
03113 hostent2su(&to, he, 0, curi.port_no);
03114 if (send_sock==0) {
03115 send_sock=force_socket ? force_socket :
03116 get_send_socket(0, &to, PROTO_UDP);
03117 }
03118 if (send_sock == NULL) {
03119 LM_ERR("can't get sending socket\n");
03120 continue;
03121 }
03122 if ( (flags&sipping_flag)!=0 &&
03123 (opt.s=build_sipping( &c, send_sock, &path, &opt.len))!=0 ) {
03124 if (udp_send(send_sock, opt.s, opt.len, &to)<0){
03125 LM_ERR("sip udp_send failed\n");
03126 }
03127 } else if (raw_ip) {
03128 if (send_raw((char*)sbuf, sizeof(sbuf), &to, raw_ip, raw_port)<0) {
03129 LM_ERR("send_raw failed\n");
03130 }
03131 } else {
03132 if (udp_send(send_sock, (char *)sbuf, sizeof(sbuf), &to)<0 ) {
03133 LM_ERR("udp_send failed\n");
03134 }
03135 }
03136 }
03137 pkg_free(buf);
03138 done:
03139 iteration++;
03140 if (iteration==natping_interval)
03141 iteration = 0;
03142 }
03143
03144
03145
03146
03147
03148
03149
03150 static int
03151 create_rcv_uri(str* uri, struct sip_msg* m)
03152 {
03153 static char buf[MAX_URI_SIZE];
03154 char* p;
03155 str ip, port;
03156 int len;
03157 str proto;
03158
03159 if (!uri || !m) {
03160 LM_ERR("invalid parameter value\n");
03161 return -1;
03162 }
03163
03164 ip.s = ip_addr2a(&m->rcv.src_ip);
03165 ip.len = strlen(ip.s);
03166
03167 port.s = int2str(m->rcv.src_port, &port.len);
03168
03169 switch(m->rcv.proto) {
03170 case PROTO_NONE:
03171 case PROTO_UDP:
03172 proto.s = 0;
03173 proto.len = 0;
03174 break;
03175
03176 case PROTO_TCP:
03177 proto.s = "TCP";
03178 proto.len = 3;
03179 break;
03180
03181 case PROTO_TLS:
03182 proto.s = "TLS";
03183 proto.len = 3;
03184 break;
03185
03186 case PROTO_SCTP:
03187 proto.s = "SCTP";
03188 proto.len = 4;
03189 break;
03190
03191 default:
03192 LM_ERR("unknown transport protocol\n");
03193 return -1;
03194 }
03195
03196 len = 4 + ip.len + 2*(m->rcv.src_ip.af==AF_INET6)+ 1 + port.len;
03197 if (proto.s) {
03198 len += TRANSPORT_PARAM_LEN;
03199 len += proto.len;
03200 }
03201
03202 if (len > MAX_URI_SIZE) {
03203 LM_ERR("buffer too small\n");
03204 return -1;
03205 }
03206
03207 p = buf;
03208 memcpy(p, "sip:", 4);
03209 p += 4;
03210
03211 if (m->rcv.src_ip.af==AF_INET6)
03212 *p++ = '[';
03213 memcpy(p, ip.s, ip.len);
03214 p += ip.len;
03215 if (m->rcv.src_ip.af==AF_INET6)
03216 *p++ = ']';
03217
03218 *p++ = ':';
03219
03220 memcpy(p, port.s, port.len);
03221 p += port.len;
03222
03223 if (proto.s) {
03224 memcpy(p, TRANSPORT_PARAM, TRANSPORT_PARAM_LEN);
03225 p += TRANSPORT_PARAM_LEN;
03226
03227 memcpy(p, proto.s, proto.len);
03228 p += proto.len;
03229 }
03230
03231 uri->s = buf;
03232 uri->len = len;
03233
03234 return 0;
03235 }
03236
03237
03238
03239
03240
03241
03242 static int
03243 add_rcv_param_f(struct sip_msg* msg, char* str1, char* str2)
03244 {
03245 contact_t* c;
03246 struct lump* anchor;
03247 char* param;
03248 str uri;
03249 int hdr_param;
03250
03251 hdr_param = str1?0:1;
03252
03253 if (create_rcv_uri(&uri, msg) < 0) {
03254 return -1;
03255 }
03256
03257 if (contact_iterator(&c, msg, 0) < 0) {
03258 return -1;
03259 }
03260
03261 while(c) {
03262 param = (char*)pkg_malloc(RECEIVED_LEN + 2 + uri.len);
03263 if (!param) {
03264 LM_ERR("no pkg memory left\n");
03265 return -1;
03266 }
03267 memcpy(param, RECEIVED, RECEIVED_LEN);
03268 param[RECEIVED_LEN] = '\"';
03269 memcpy(param + RECEIVED_LEN + 1, uri.s, uri.len);
03270 param[RECEIVED_LEN + 1 + uri.len] = '\"';
03271
03272 if (hdr_param) {
03273
03274 anchor = anchor_lump(msg, c->name.s + c->len - msg->buf, 0, 0);
03275 } else {
03276
03277 anchor = anchor_lump(msg, c->uri.s + c->uri.len - msg->buf, 0, 0);
03278 }
03279 if (anchor == NULL) {
03280 LM_ERR("anchor_lump failed\n");
03281 return -1;
03282 }
03283
03284 if (insert_new_lump_after(anchor, param, RECEIVED_LEN + 1 + uri.len + 1, 0) == 0) {
03285 LM_ERR("insert_new_lump_after failed\n");
03286 pkg_free(param);
03287 return -1;
03288 }
03289
03290 if (contact_iterator(&c, msg, c) < 0) {
03291 return -1;
03292 }
03293 }
03294
03295 return 1;
03296 }
03297
03298
03299 static int start_recording_f(struct sip_msg* msg, char *foo, char *bar)
03300 {
03301 int nitems;
03302 str callid = {0, 0};
03303 str from_tag = {0, 0};
03304 str to_tag = {0, 0};
03305 struct rtpp_node *node;
03306 struct iovec v[1 + 4 + 3] = {{NULL, 0}, {"R", 1}, {" ", 1}, {NULL, 0}, {" ", 1}, {NULL, 0}, {" ", 1}, {NULL, 0}};
03307
03308
03309 if (get_callid(msg, &callid) == -1 || callid.len == 0) {
03310 LM_ERR("can't get Call-Id field\n");
03311 return -1;
03312 }
03313
03314 if (get_to_tag(msg, &to_tag) == -1) {
03315 LM_ERR("can't get To tag\n");
03316 return -1;
03317 }
03318
03319 if (get_from_tag(msg, &from_tag) == -1 || from_tag.len == 0) {
03320 LM_ERR("can't get From tag\n");
03321 return -1;
03322 }
03323
03324 if(msg->id != current_msg_id){
03325 selected_rtpp_set = default_rtpp_set;
03326 }
03327
03328 STR2IOVEC(callid, v[3]);
03329 STR2IOVEC(from_tag, v[5]);
03330 STR2IOVEC(to_tag, v[7]);
03331 node = select_rtpp_node(callid, 1);
03332 if (!node) {
03333 LM_ERR("no available proxies\n");
03334 return -1;
03335 }
03336
03337 nitems = 8;
03338 if (msg->first_line.type == SIP_REPLY) {
03339 if (to_tag.len == 0)
03340 return -1;
03341 STR2IOVEC(to_tag, v[5]);
03342 STR2IOVEC(from_tag, v[7]);
03343 } else {
03344 STR2IOVEC(from_tag, v[5]);
03345 STR2IOVEC(to_tag, v[7]);
03346 if (to_tag.len <= 0)
03347 nitems = 6;
03348 }
03349 send_rtpp_command(node, v, nitems);
03350
03351 return 1;
03352 }
03353
03354
03355
03356
03357
03358
03359
03360 static int
03361 fix_nated_register_f(struct sip_msg* msg, char* str1, char* str2)
03362 {
03363 str uri;
03364 int_str val;
03365
03366 if(rcv_avp_name.n==0)
03367 return 1;
03368
03369 if (create_rcv_uri(&uri, msg) < 0) {
03370 return -1;
03371 }
03372
03373 val.s = uri;
03374
03375 if (add_avp(AVP_VAL_STR|rcv_avp_type, rcv_avp_name, val) < 0) {
03376 LM_ERR("failed to create AVP\n");
03377 return -1;
03378 }
03379
03380 return 1;
03381 }