00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <unistd.h>
00026 #include <string.h>
00027 #include <ctype.h>
00028 #include <errno.h>
00029 #include <time.h>
00030 #include <sys/types.h>
00031 #include <arpa/inet.h>
00032
00033 #include "../../sr_module.h"
00034 #include "../../mem/shm_mem.h"
00035 #include "../../mem/mem.h"
00036 #include "../../lock_ops.h"
00037 #include "../../dprint.h"
00038 #include "../../str.h"
00039 #include "../../pvar.h"
00040 #include "../../error.h"
00041 #include "../../timer.h"
00042 #include "../../resolve.h"
00043 #include "../../data_lump.h"
00044 #include "../../mod_fix.h"
00045 #include "../../script_cb.h"
00046 #include "../../timer_proc.h"
00047 #include "../../parser/msg_parser.h"
00048 #include "../../parser/parse_from.h"
00049 #include "../../parser/parse_uri.h"
00050 #include "../../parser/parse_expires.h"
00051 #include "../../parser/contact/parse_contact.h"
00052 #include "../../lib/kcore/statistics.h"
00053 #include "../dialog/dlg_load.h"
00054 #include "../../modules/tm/tm_load.h"
00055 #include "../../modules/sl/sl.h"
00056
00057
00058 MODULE_VERSION
00059
00060
00061 #if defined(__GNUC__) && !defined(__STRICT_ANSI__)
00062 # define INLINE inline
00063 #else
00064 # define INLINE
00065 #endif
00066
00067
00068
00069 #define FL_DO_KEEPALIVE (1<<31)
00070
00071 #define HASH_SIZE 512
00072
00073
00074 #define max(a, b) ((a)>(b) ? (a) : (b))
00075 #define min(a, b) ((a)<(b) ? (a) : (b))
00076
00077 #define STR_MATCH(str, buf) ((str).len==strlen(buf) && memcmp(buf, (str).s, (str).len)==0)
00078 #define STR_IMATCH(str, buf) ((str).len==strlen(buf) && strncasecmp(buf, (str).s, (str).len)==0)
00079
00080 #define STR_MATCH_STR(str, str2) ((str).len==(str2).len && memcmp((str).s, (str2).s, (str).len)==0)
00081 #define STR_IMATCH_STR(str, str2) ((str).len==(str2).len && strncasecmp((str).s, (str2).s, (str).len)==0)
00082
00083 #define STR_HAS_PREFIX(str, prefix) ((str).len>(prefix).len && memcmp((prefix).s, (str).s, (prefix).len)==0)
00084 #define STR_HAS_IPREFIX(str, prefix) ((str).len>(prefix).len && strncasecmp((prefix).s, (str).s, (prefix).len)==0)
00085
00086
00087 typedef int Bool;
00088 #define True 1
00089 #define False 0
00090
00091
00092 typedef Bool (*NatTestFunction)(struct sip_msg *msg);
00093
00094 typedef enum {
00095 NTNone=0,
00096 NTPrivateContact=1,
00097 NTSourceAddress=2,
00098 NTPrivateVia=4
00099 } NatTestType;
00100
00101 typedef struct {
00102 NatTestType test;
00103 NatTestFunction proc;
00104 } NatTest;
00105
00106 typedef struct {
00107 const char *name;
00108 uint32_t address;
00109 uint32_t mask;
00110 } NetInfo;
00111
00112
00113 typedef struct SIP_Dialog {
00114 struct dlg_cell *dlg;
00115 time_t expire;
00116 struct SIP_Dialog *next;
00117 } SIP_Dialog;
00118
00119
00120 typedef struct NAT_Contact {
00121 char *uri;
00122 struct socket_info *socket;
00123
00124 time_t registration_expire;
00125 time_t subscription_expire;
00126 SIP_Dialog *dialogs;
00127
00128 struct NAT_Contact *next;
00129 } NAT_Contact;
00130
00131
00132 typedef struct HashSlot {
00133 NAT_Contact *head;
00134 gen_lock_t lock;
00135 } HashSlot;
00136
00137
00138 typedef struct HashTable {
00139 HashSlot *slots;
00140 unsigned size;
00141 } HashTable;
00142
00143
00144 #define URI_LIST_INITIAL_SIZE 8
00145 #define URI_LIST_RESIZE_INCREMENT 8
00146
00147 typedef struct Dialog_Param {
00148 char *caller_uri;
00149 char *callee_uri;
00150 time_t expire;
00151 Bool confirmed;
00152 gen_lock_t lock;
00153 struct {
00154 char **uri;
00155 int count;
00156 int size;
00157 } callee_candidates;
00158 } Dialog_Param;
00159
00160
00161
00162
00163 typedef struct Keepalive_Params {
00164
00165 char *method;
00166 char *from;
00167 char *extra_headers;
00168
00169
00170 char callid_prefix[20];
00171 unsigned callid_counter;
00172 unsigned from_tag;
00173 char *event_header;
00174 } Keepalive_Params;
00175
00176
00177
00178
00179 static int NAT_Keepalive(struct sip_msg *msg);
00180 static int FixContact(struct sip_msg *msg);
00181 static int ClientNatTest(struct sip_msg *msg, unsigned int tests);
00182
00183 static Bool test_private_contact(struct sip_msg *msg);
00184 static Bool test_source_address(struct sip_msg *msg);
00185 static Bool test_private_via(struct sip_msg *msg);
00186
00187 static INLINE char* shm_strdup(char *source);
00188
00189 static int mod_init(void);
00190 static int child_init(int rank);
00191 static void mod_destroy(void);
00192 static int preprocess_request(struct sip_msg *msg, unsigned int flags, void *param);
00193 static int reply_filter(struct sip_msg *reply);
00194
00195 static int pv_parse_nat_contact_name(pv_spec_p sp, str *in);
00196 static int pv_get_keepalive_socket(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
00197 static int pv_get_source_uri(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
00198
00199
00200
00201
00202 static HashTable *nat_table = NULL;
00203
00204 static Bool keepalive_disabled = False;
00205
00206 static unsigned int keepalive_interval = 60;
00207
00208 static char *keepalive_state_file = "keepalive_state";
00209
00210 static Keepalive_Params keepalive_params = {"NOTIFY", NULL, "", "", 0, 0, ""};
00211
00212 struct tm_binds tm_api;
00213 struct dlg_binds dlg_api;
00214 Bool have_dlg_api = False;
00215
00216 static int dialog_flag = -1;
00217 static unsigned dialog_default_timeout = 12*3600;
00218
00219 stat_var *keepalive_endpoints = 0;
00220 stat_var *registered_endpoints = 0;
00221 stat_var *subscribed_endpoints = 0;
00222 stat_var *dialog_endpoints = 0;
00223
00224 static NetInfo rfc1918nets[] = {
00225 {"10.0.0.0", 0x0a000000UL, 0xff000000UL},
00226 {"172.16.0.0", 0xac100000UL, 0xfff00000UL},
00227 {"192.168.0.0", 0xc0a80000UL, 0xffff0000UL},
00228 {NULL, 0UL, 0UL}
00229 };
00230
00231 static NatTest NAT_Tests[] = {
00232 {NTPrivateContact, test_private_contact},
00233 {NTSourceAddress, test_source_address},
00234 {NTPrivateVia, test_private_via},
00235 {NTNone, NULL}
00236 };
00237
00239 sl_api_t slb;
00240
00241 static cmd_export_t commands[] = {
00242 {"nat_keepalive", (cmd_function)NAT_Keepalive, 0, NULL, 0, REQUEST_ROUTE},
00243 {"fix_contact", (cmd_function)FixContact, 0, NULL, 0, REQUEST_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE |LOCAL_ROUTE},
00244 {"client_nat_test", (cmd_function)ClientNatTest, 1, fixup_uint_null, 0, REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE|LOCAL_ROUTE},
00245 {0, 0, 0, 0, 0, 0}
00246 };
00247
00248 static param_export_t parameters[] = {
00249 {"keepalive_interval", INT_PARAM, &keepalive_interval},
00250 {"keepalive_method", STR_PARAM, &keepalive_params.method},
00251 {"keepalive_from", STR_PARAM, &keepalive_params.from},
00252 {"keepalive_extra_headers", STR_PARAM, &keepalive_params.extra_headers},
00253 {"keepalive_state_file", STR_PARAM, &keepalive_state_file},
00254 {0, 0, 0}
00255 };
00256
00257 static pv_export_t pvars[] = {
00258 {str_init("keepalive.socket"), PVT_OTHER, pv_get_keepalive_socket, NULL, pv_parse_nat_contact_name, NULL, NULL, 0},
00259 {str_init("source_uri"), PVT_OTHER, pv_get_source_uri, NULL, NULL, NULL, NULL, 0},
00260 {{0, 0}, 0, 0, 0, 0, 0, 0, 0}
00261 };
00262
00263 #ifdef STATISTICS
00264 static stat_export_t statistics[] = {
00265 {"keepalive_endpoints", STAT_NO_RESET, &keepalive_endpoints},
00266 {"registered_endpoints", STAT_NO_RESET, ®istered_endpoints},
00267 {"subscribed_endpoints", STAT_NO_RESET, &subscribed_endpoints},
00268 {"dialog_endpoints", STAT_NO_RESET, &dialog_endpoints},
00269 {0, 0, 0}
00270 };
00271 #endif
00272
00273 struct module_exports exports = {
00274 "nat_traversal",
00275 DEFAULT_DLFLAGS,
00276 commands,
00277 parameters,
00278 NULL,
00279 NULL,
00280 pvars,
00281 NULL,
00282 mod_init,
00283 reply_filter,
00284 mod_destroy,
00285 child_init
00286 };
00287
00288
00289
00290
00291
00292
00293 static SIP_Dialog*
00294 SIP_Dialog_new(struct dlg_cell *dlg, time_t expire)
00295 {
00296 SIP_Dialog *dialog;
00297
00298 dialog = (SIP_Dialog*)shm_malloc(sizeof(SIP_Dialog));
00299 if (!dialog) {
00300 LM_ERR("out of memory while creating new SIP_Dialog structure\n");
00301 return NULL;
00302 }
00303 dialog->dlg = dlg;
00304 dialog->expire = expire;
00305 dialog->next = NULL;
00306
00307
00308 update_stat(dialog_endpoints, 1);
00309
00310 return dialog;
00311 }
00312
00313
00314 static void
00315 SIP_Dialog_del(SIP_Dialog *dialog)
00316 {
00317 if (!dialog)
00318 return;
00319
00320 if (dialog->expire > 0)
00321 update_stat(dialog_endpoints, -1);
00322 shm_free(dialog);
00323 }
00324
00325
00326
00327
00328 static SIP_Dialog*
00329 SIP_Dialog_purge_expired(SIP_Dialog *dialog, time_t now)
00330 {
00331 SIP_Dialog *next;
00332
00333 if (dialog==NULL)
00334 return NULL;
00335
00336 dialog->next = SIP_Dialog_purge_expired(dialog->next, now);
00337
00338 if (now > dialog->expire) {
00339 next = dialog->next;
00340 SIP_Dialog_del(dialog);
00341 return next;
00342 }
00343
00344 return dialog;
00345 }
00346
00347
00348 static INLINE void
00349 SIP_Dialog_end(SIP_Dialog *dialog)
00350 {
00351 if (dialog->expire > 0) {
00352 dialog->expire = 0;
00353 update_stat(dialog_endpoints, -1);
00354 }
00355 }
00356
00357
00358
00359
00360 static INLINE void
00361 SIP_Registration_update(NAT_Contact *contact, time_t expire)
00362 {
00363 if (expire > contact->registration_expire) {
00364 if (contact->registration_expire == 0)
00365 update_stat(registered_endpoints, 1);
00366 contact->registration_expire = expire;
00367 }
00368 }
00369
00370 static INLINE void
00371 SIP_Registration_expire(NAT_Contact *contact, time_t now)
00372 {
00373 if (contact->registration_expire && now > contact->registration_expire) {
00374 update_stat(registered_endpoints, -1);
00375 contact->registration_expire = 0;
00376 }
00377 }
00378
00379 static INLINE void
00380 SIP_Subscription_update(NAT_Contact *contact, time_t expire)
00381 {
00382 if (expire > contact->subscription_expire) {
00383 if (contact->subscription_expire == 0)
00384 update_stat(subscribed_endpoints, 1);
00385 contact->subscription_expire = expire;
00386 }
00387 }
00388
00389 static INLINE void
00390 SIP_Subscription_expire(NAT_Contact *contact, time_t now)
00391 {
00392 if (contact->subscription_expire && now > contact->subscription_expire) {
00393 update_stat(subscribed_endpoints, -1);
00394 contact->subscription_expire = 0;
00395 }
00396 }
00397
00398
00399
00400
00401
00402 static NAT_Contact*
00403 NAT_Contact_new(char *uri, struct socket_info *socket)
00404 {
00405 NAT_Contact *contact;
00406
00407 contact = (NAT_Contact*)shm_malloc(sizeof(NAT_Contact));
00408 if (!contact) {
00409 LM_ERR("out of memory while creating new NAT_Contact structure\n");
00410 return NULL;
00411 }
00412 memset(contact, 0, sizeof(NAT_Contact));
00413
00414 contact->uri = shm_strdup(uri);
00415 if (!contact->uri) {
00416 LM_ERR("out of memory while creating new NAT_Contact structure\n");
00417 shm_free(contact);
00418 return NULL;
00419 }
00420 contact->socket = socket;
00421
00422 update_stat(keepalive_endpoints, 1);
00423
00424 return contact;
00425 }
00426
00427
00428 static void
00429 NAT_Contact_del(NAT_Contact *contact)
00430 {
00431 SIP_Dialog *dialog, *next;
00432
00433 if (!contact)
00434 return;
00435
00436 dialog = contact->dialogs;
00437 while (dialog) {
00438 next = dialog->next;
00439 SIP_Dialog_del(dialog);
00440 dialog = next;
00441 }
00442
00443 if (contact->registration_expire > 0)
00444 update_stat(registered_endpoints, -1);
00445 if (contact->subscription_expire > 0)
00446 update_stat(subscribed_endpoints, -1);
00447 update_stat(keepalive_endpoints, -1);
00448
00449 shm_free(contact->uri);
00450 shm_free(contact);
00451 }
00452
00453
00454 static Bool
00455 NAT_Contact_match(NAT_Contact *contact, const char *uri)
00456 {
00457 return strcmp(contact->uri, uri)==0;
00458 }
00459
00460
00461 static SIP_Dialog*
00462 NAT_Contact_get_dialog(NAT_Contact *contact, struct dlg_cell *dlg)
00463 {
00464 SIP_Dialog *dialog;
00465
00466 dialog = contact->dialogs;
00467
00468 while (dialog) {
00469 if (dialog->dlg == dlg)
00470 break;
00471 dialog = dialog->next;
00472 }
00473
00474 return dialog;
00475 }
00476
00477
00478 static NAT_Contact*
00479 NAT_Contact_purge_expired(NAT_Contact *contact, time_t now)
00480 {
00481 NAT_Contact *next;
00482
00483 if (contact==NULL)
00484 return NULL;
00485
00486 contact->next = NAT_Contact_purge_expired(contact->next, now);
00487
00488 SIP_Registration_expire(contact, now);
00489 SIP_Subscription_expire(contact, now);
00490 contact->dialogs = SIP_Dialog_purge_expired(contact->dialogs, now);
00491
00492 if (!contact->registration_expire && !contact->subscription_expire && !contact->dialogs) {
00493 next = contact->next;
00494 NAT_Contact_del(contact);
00495 return next;
00496 }
00497
00498 return contact;
00499 }
00500
00501
00502
00503
00504
00505 #define HASH(table, key) (hash_string(key) % (table)->size)
00506
00507 static INLINE unsigned
00508 hash_string(const char *key)
00509 {
00510 register unsigned ret = 0;
00511 register unsigned ctr = 0;
00512
00513 while (*key) {
00514 ret ^= *(char*)key++ << ctr;
00515 ctr = (ctr + 1) % sizeof (char *);
00516 }
00517
00518 return ret;
00519 }
00520
00521
00522 static HashTable*
00523 HashTable_new(void)
00524 {
00525 HashTable *table;
00526 int i, j;
00527
00528 table = shm_malloc(sizeof(HashTable));
00529 if (!table) {
00530 LM_ERR("cannot allocate shared memory for hash table\n");
00531 return NULL;
00532 }
00533 memset(table, 0, sizeof(HashTable));
00534
00535 table->size = HASH_SIZE;
00536
00537 table->slots = shm_malloc(sizeof(HashSlot)*table->size);
00538 if (!table->slots) {
00539 LM_ERR("cannot allocate shared memory for hash table\n");
00540 shm_free(table);
00541 return NULL;
00542 }
00543 memset(table->slots, 0, sizeof(HashSlot)*table->size);
00544
00545 for (i=0; i<table->size; i++) {
00546 if (!lock_init(&table->slots[i].lock)) {
00547 LM_ERR("cannot initialize hash table locks\n");
00548 for (j=0; j<i; j++)
00549 lock_destroy(&table->slots[j].lock);
00550 shm_free(table->slots);
00551 shm_free(table);
00552 return NULL;
00553 }
00554 }
00555
00556 return table;
00557 }
00558
00559
00560 static void
00561 HashTable_del(HashTable *table)
00562 {
00563 NAT_Contact *contact, *next;
00564 int i;
00565
00566 for (i=0; i < table->size; i++) {
00567 lock_get(&table->slots[i].lock);
00568 contact = table->slots[i].head;
00569 while (contact) {
00570 next = contact->next;
00571 NAT_Contact_del(contact);
00572 contact = next;
00573 }
00574 table->slots[i].head = NULL;
00575 lock_release(&table->slots[i].lock);
00576 }
00577
00578 shm_free(table->slots);
00579 shm_free(table);
00580 }
00581
00582
00583
00584
00585 static NAT_Contact*
00586 HashTable_search(HashTable *table, char *uri, unsigned slot)
00587 {
00588 NAT_Contact *contact;
00589
00590 contact = table->slots[slot].head;
00591
00592 while (contact) {
00593 if (NAT_Contact_match(contact, uri))
00594 break;
00595 contact = contact->next;
00596 }
00597
00598 return contact;
00599 }
00600
00601
00602
00603
00604
00605 static Dialog_Param*
00606 Dialog_Param_new(void)
00607 {
00608 Dialog_Param *param;
00609
00610 param = shm_malloc(sizeof(Dialog_Param));
00611 if (!param) {
00612 LM_ERR("cannot allocate shared memory for dialog callback param\n");
00613 return NULL;
00614 }
00615 memset(param, 0, sizeof(Dialog_Param));
00616
00617 param->callee_candidates.uri = shm_malloc(sizeof(char*) * URI_LIST_INITIAL_SIZE);
00618 if (!param->callee_candidates.uri) {
00619 LM_ERR("cannot allocate shared memory for callee_candidates uri list\n");
00620 shm_free(param);
00621 return NULL;
00622 }
00623 memset(param->callee_candidates.uri, 0, sizeof(char*) * URI_LIST_INITIAL_SIZE);
00624 param->callee_candidates.size = URI_LIST_INITIAL_SIZE;
00625
00626 param->expire = time(NULL) + dialog_default_timeout;
00627
00628 if (!lock_init(¶m->lock)) {
00629 LM_ERR("cannot initialize dialog param structure lock\n");
00630 shm_free(param->callee_candidates.uri);
00631 shm_free(param);
00632 return NULL;
00633 }
00634
00635 return param;
00636 }
00637
00638
00639 static void
00640 Dialog_Param_del(Dialog_Param *param)
00641 {
00642 int i;
00643
00644 if (!param)
00645 return;
00646
00647 lock_destroy(¶m->lock);
00648
00649 if (param->caller_uri)
00650 shm_free(param->caller_uri);
00651 if (param->callee_uri)
00652 shm_free(param->callee_uri);
00653 for (i=0; i<param->callee_candidates.count; i++)
00654 shm_free(param->callee_candidates.uri[i]);
00655 shm_free(param->callee_candidates.uri);
00656 shm_free(param);
00657 }
00658
00659
00660
00661
00662 static Bool
00663 Dialog_Param_has_candidate(Dialog_Param *param, char *candidate)
00664 {
00665 int i;
00666
00667 for (i=0; i<param->callee_candidates.count; i++) {
00668 if (strcmp(candidate, param->callee_candidates.uri[i])==0) {
00669 return True;
00670 }
00671 }
00672
00673 return False;
00674 }
00675
00676
00677
00678
00679 static Bool
00680 Dialog_Param_add_candidate(Dialog_Param *param, char *candidate)
00681 {
00682 char **new_uri, *new_candidate;
00683 int new_size;
00684
00685 if (param->callee_candidates.count == param->callee_candidates.size) {
00686 new_size = param->callee_candidates.size + URI_LIST_RESIZE_INCREMENT;
00687 LM_DBG("growing callee_candidates list size from %d to %d entries\n", param->callee_candidates.size, new_size);
00688 new_uri = shm_realloc(param->callee_candidates.uri, new_size);
00689 if (!new_uri) {
00690 LM_ERR("failed to grow callee_candidates uri list\n");
00691 return False;
00692 }
00693 param->callee_candidates.uri = new_uri;
00694 param->callee_candidates.size = new_size;
00695 }
00696
00697 new_candidate = shm_strdup(candidate);
00698 if (!new_candidate) {
00699 LM_ERR("cannot allocate shared memory for new candidate uri\n");
00700 return False;
00701 }
00702
00703 param->callee_candidates.uri[param->callee_candidates.count] = new_candidate;
00704 param->callee_candidates.count++;
00705
00706 return True;
00707 }
00708
00709
00710
00711
00712
00713
00714 static INLINE void
00715 ltrim(str *string)
00716 {
00717 while (string->len>0 && isspace((int)*(string->s))) {
00718 string->len--;
00719 string->s++;
00720 }
00721 }
00722
00723
00724 static INLINE void
00725 rtrim(str *string)
00726 {
00727 char *ptr;
00728
00729 ptr = string->s + string->len - 1;
00730 while (string->len>0 && (*ptr==0 || isspace((int)*ptr))) {
00731 string->len--;
00732 ptr--;
00733 }
00734 }
00735
00736
00737 static INLINE void
00738 trim(str *string)
00739 {
00740 ltrim(string);
00741 rtrim(string);
00742 }
00743
00744
00745 static INLINE char*
00746 shm_strdup(char *source)
00747 {
00748 char *copy;
00749
00750 if (!source)
00751 return NULL;
00752
00753 copy = (char*)shm_malloc(strlen(source) + 1);
00754 if (!copy)
00755 return NULL;
00756 strcpy(copy, source);
00757
00758 return copy;
00759 }
00760
00761
00762 static Bool
00763 get_contact_uri(struct sip_msg* msg, struct sip_uri *uri, contact_t **_c)
00764 {
00765
00766 if ((parse_headers(msg, HDR_CONTACT_F, 0) == -1) || !msg->contact)
00767 return False;
00768
00769 if (!msg->contact->parsed && parse_contact(msg->contact) < 0) {
00770 LM_ERR("cannot parse the Contact header\n");
00771 return False;
00772 }
00773
00774 *_c = ((contact_body_t*)msg->contact->parsed)->contacts;
00775
00776 if (*_c == NULL) {
00777 return False;
00778 }
00779
00780 if (parse_uri((*_c)->uri.s, (*_c)->uri.len, uri) < 0 || uri->host.len <= 0) {
00781 LM_ERR("cannot parse the Contact URI\n");
00782 return False;
00783 }
00784
00785 return True;
00786 }
00787
00788
00789 #define is_private_address(x) (rfc1918address(x)==1 ? 1 : 0)
00790
00791
00792 static INLINE int
00793 rfc1918address(str *address)
00794 {
00795 struct ip_addr *ip;
00796 uint32_t netaddr;
00797 int i;
00798
00799 ip = str2ip(address);
00800 if (ip == NULL)
00801 return -1;
00802
00803 netaddr = ntohl(ip->u.addr32[0]);
00804
00805 for (i=0; rfc1918nets[i].name!=NULL; i++) {
00806 if ((netaddr & rfc1918nets[i].mask)==rfc1918nets[i].address) {
00807 return 1;
00808 }
00809 }
00810
00811 return 0;
00812 }
00813
00814
00815
00816 static Bool
00817 test_source_address(struct sip_msg *msg)
00818 {
00819 Bool different_ip, different_port;
00820 int via1_port;
00821
00822 different_ip = received_test(msg);
00823 via1_port = (msg->via1->port ? msg->via1->port : SIP_PORT);
00824 different_port = (msg->rcv.src_port != via1_port);
00825
00826 return (different_ip || different_port);
00827 }
00828
00829
00830
00831 static Bool
00832 test_private_contact(struct sip_msg *msg)
00833 {
00834 struct sip_uri uri;
00835 contact_t* contact;
00836
00837 if (!get_contact_uri(msg, &uri, &contact))
00838 return False;
00839
00840 return is_private_address(&(uri.host));
00841 }
00842
00843
00844
00845 static Bool
00846 test_private_via(struct sip_msg *msg)
00847 {
00848 return is_private_address(&(msg->via1->host));
00849 }
00850
00851
00852
00853 static int
00854 get_expires(struct sip_msg *msg)
00855 {
00856 exp_body_t *expires;
00857
00858 if (parse_headers(msg, HDR_EXPIRES_F, 0) < 0) {
00859 LM_ERR("failed to parse the Expires header\n");
00860 return 0;
00861 }
00862 if (!msg->expires)
00863 return 0;
00864
00865 if (parse_expires(msg->expires) < 0) {
00866 LM_ERR("failed to parse the Expires header body\n");
00867 return 0;
00868 }
00869
00870 expires = (exp_body_t*)msg->expires->parsed;
00871
00872 return ((expires->valid && expires->val) ? expires->val + time(NULL) : 0);
00873 }
00874
00875
00876
00877 static time_t
00878 get_register_expire(struct sip_msg *request, struct sip_msg *reply)
00879 {
00880 struct hdr_field contact_hdr, *hdr, *r_hdr;
00881 contact_body_t *contact_body, *r_contact_body;
00882 contact_t *contact, *r_contact;
00883 param_t *expires_param;
00884 time_t now, expire=0;
00885 unsigned exp;
00886 Bool matched;
00887
00888 if (!request->contact)
00889 return 0;
00890
00891 if (parse_headers(reply, HDR_EOH_F, 0) < 0) {
00892 LM_ERR("failed to parse headers for REGISTER reply\n");
00893 return 0;
00894 }
00895
00896 if (!reply->contact)
00897 return 0;
00898
00899 now = time(NULL);
00900
00901
00902
00903
00904 for (hdr=request->contact; hdr; hdr = next_sibling_hdr(hdr)) {
00905 if (!hdr->parsed) {
00906 memcpy(&contact_hdr, hdr, sizeof(struct hdr_field));
00907 if (parse_contact(&contact_hdr) < 0) {
00908 LM_ERR("failed to parse the Contact header body\n");
00909 continue;
00910 }
00911 contact_body = (contact_body_t*)contact_hdr.parsed;
00912 } else {
00913 contact_body = (contact_body_t*)hdr->parsed;
00914 }
00915
00916 if (contact_body->star) {
00917 if (!hdr->parsed)
00918 clean_hdr_field(&contact_hdr);
00919 return 0;
00920 }
00921
00922 for (contact=contact_body->contacts; contact; contact=contact->next) {
00923 for (r_hdr=reply->contact, matched=False; r_hdr && !matched; r_hdr=next_sibling_hdr(r_hdr)) {
00924 if (!r_hdr->parsed && parse_contact(r_hdr) < 0) {
00925 LM_ERR("failed to parse the Contact header body in reply\n");
00926 continue;
00927 }
00928 r_contact_body = (contact_body_t*)r_hdr->parsed;
00929 for (r_contact=r_contact_body->contacts; r_contact; r_contact=r_contact->next) {
00930 if (STR_MATCH_STR(contact->uri, r_contact->uri)) {
00931 expires_param = r_contact->expires;
00932 if (expires_param && expires_param->body.len && str2int(&expires_param->body, &exp) == 0)
00933 expire = max(expire, exp);
00934 matched = True;
00935 break;
00936 }
00937 }
00938 }
00939 }
00940
00941 if (!hdr->parsed) {
00942 clean_hdr_field(&contact_hdr);
00943 }
00944 }
00945
00946 LM_DBG("maximum expire for all contacts: %u\n", (unsigned)expire);
00947
00948 return (expire ? expire + now : 0);
00949 }
00950
00951
00952 static char*
00953 get_source_uri(struct sip_msg *msg)
00954 {
00955 static char uri[64];
00956 snprintf(uri, 64, "sip:%s:%d", ip_addr2a(&msg->rcv.src_ip), msg->rcv.src_port);
00957 return uri;
00958 }
00959
00960
00961 static void
00962 keepalive_registration(struct sip_msg *request, time_t expire)
00963 {
00964 NAT_Contact *contact;
00965 unsigned h;
00966 char *uri;
00967
00968 uri = get_source_uri(request);
00969
00970 h = HASH(nat_table, uri);
00971 lock_get(&nat_table->slots[h].lock);
00972
00973 contact = HashTable_search(nat_table, uri, h);
00974 if (contact) {
00975 SIP_Registration_update(contact, expire);
00976 } else {
00977 contact = NAT_Contact_new(uri, request->rcv.bind_address);
00978 if (contact) {
00979 SIP_Registration_update(contact, expire);
00980 contact->next = nat_table->slots[h].head;
00981 nat_table->slots[h].head = contact;
00982 } else {
00983 LM_ERR("cannot allocate shared memory for new NAT contact\n");
00984 }
00985 }
00986
00987 lock_release(&nat_table->slots[h].lock);
00988 }
00989
00990
00991 static void
00992 keepalive_subscription(struct sip_msg *request, time_t expire)
00993 {
00994 NAT_Contact *contact;
00995 unsigned h;
00996 char *uri;
00997
00998 uri = get_source_uri(request);
00999
01000 h = HASH(nat_table, uri);
01001 lock_get(&nat_table->slots[h].lock);
01002
01003 contact = HashTable_search(nat_table, uri, h);
01004 if (contact) {
01005 SIP_Subscription_update(contact, expire);
01006 } else {
01007 contact = NAT_Contact_new(uri, request->rcv.bind_address);
01008 if (contact) {
01009 SIP_Subscription_update(contact, expire);
01010 contact->next = nat_table->slots[h].head;
01011 nat_table->slots[h].head = contact;
01012 } else {
01013 LM_ERR("cannot allocate shared memory for new NAT contact\n");
01014 }
01015 }
01016
01017 lock_release(&nat_table->slots[h].lock);
01018 }
01019
01020
01021 static void
01022 __dialog_early(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
01023 {
01024 Dialog_Param *param = (Dialog_Param*)*_params->param;
01025 NAT_Contact *contact;
01026 SIP_Dialog *dialog;
01027 unsigned h;
01028 char *uri;
01029
01030 lock_get(¶m->lock);
01031
01032 if (param->confirmed) {
01033
01034 lock_release(¶m->lock);
01035 return;
01036 }
01037
01038 uri = get_source_uri(_params->rpl);
01039 if (!Dialog_Param_has_candidate(param, uri)) {
01040 if (!Dialog_Param_add_candidate(param, uri)) {
01041 LM_ERR("cannot add callee candidate uri to the list\n");
01042 } else {
01043 h = HASH(nat_table, uri);
01044 lock_get(&nat_table->slots[h].lock);
01045
01046 contact = HashTable_search(nat_table, uri, h);
01047 if (contact) {
01048 dialog = NAT_Contact_get_dialog(contact, dlg);
01049 if (!dialog) {
01050 dialog = SIP_Dialog_new(dlg, param->expire);
01051 if (dialog) {
01052 dialog->next = contact->dialogs;
01053 contact->dialogs = dialog;
01054 } else {
01055 LM_ERR("cannot allocate shared memory for new SIP dialog\n");
01056 }
01057 }
01058 }
01059
01060 lock_release(&nat_table->slots[h].lock);
01061 }
01062 }
01063
01064 lock_release(¶m->lock);
01065 }
01066
01067
01068 static void
01069 __dialog_confirmed(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
01070 {
01071 Dialog_Param *param = (Dialog_Param*)*_params->param;
01072 NAT_Contact *contact;
01073 SIP_Dialog *dialog;
01074 char *callee_uri, *uri;
01075 unsigned h;
01076 int i;
01077
01078 lock_get(¶m->lock);
01079
01080 param->confirmed = True;
01081
01082 callee_uri = get_source_uri(_params->rpl);
01083
01084
01085 for (i=0; i<param->callee_candidates.count; i++) {
01086 uri = param->callee_candidates.uri[i];
01087
01088 if (strcmp(uri, callee_uri) != 0) {
01089
01090 h = HASH(nat_table, uri);
01091 lock_get(&nat_table->slots[h].lock);
01092
01093 contact = HashTable_search(nat_table, uri, h);
01094 if (contact) {
01095 dialog = NAT_Contact_get_dialog(contact, dlg);
01096 if (dialog) {
01097 SIP_Dialog_end(dialog);
01098 }
01099 }
01100
01101 lock_release(&nat_table->slots[h].lock);
01102 }
01103
01104 shm_free(param->callee_candidates.uri[i]);
01105 param->callee_candidates.uri[i] = NULL;
01106 }
01107
01108 param->callee_candidates.count = 0;
01109
01110
01111 h = HASH(nat_table, callee_uri);
01112 lock_get(&nat_table->slots[h].lock);
01113
01114 contact = HashTable_search(nat_table, callee_uri, h);
01115 if (contact) {
01116 dialog = NAT_Contact_get_dialog(contact, dlg);
01117 if (!dialog) {
01118 dialog = SIP_Dialog_new(dlg, param->expire);
01119 if (dialog) {
01120 dialog->next = contact->dialogs;
01121 contact->dialogs = dialog;
01122 } else {
01123 LM_ERR("cannot allocate shared memory for new SIP dialog\n");
01124 }
01125 }
01126
01127 if (param->callee_uri)
01128 shm_free(param->callee_uri);
01129 param->callee_uri = shm_strdup(callee_uri);
01130 if (!param->callee_uri) {
01131 LM_ERR("cannot allocate shared memory for callee_uri in dialog param\n");
01132 }
01133 }
01134
01135 lock_release(&nat_table->slots[h].lock);
01136
01137 lock_release(¶m->lock);
01138 }
01139
01140
01141 static void
01142 __dialog_destroy(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
01143 {
01144 Dialog_Param *param = (Dialog_Param*)*_params->param;
01145 NAT_Contact *contact;
01146 SIP_Dialog *dialog;
01147 unsigned h;
01148 int i;
01149
01150 if (!param)
01151 return;
01152
01153
01154
01155
01156 if (!nat_table) {
01157 Dialog_Param_del(param);
01158 *_params->param = NULL;
01159 return;
01160 }
01161
01162 if (param->caller_uri) {
01163 h = HASH(nat_table, param->caller_uri);
01164 lock_get(&nat_table->slots[h].lock);
01165
01166 contact = HashTable_search(nat_table, param->caller_uri, h);
01167 if (contact) {
01168 dialog = NAT_Contact_get_dialog(contact, dlg);
01169 if (dialog) {
01170 SIP_Dialog_end(dialog);
01171 }
01172 }
01173
01174 lock_release(&nat_table->slots[h].lock);
01175 }
01176
01177 if (param->callee_uri) {
01178 h = HASH(nat_table, param->callee_uri);
01179 lock_get(&nat_table->slots[h].lock);
01180
01181 contact = HashTable_search(nat_table, param->callee_uri, h);
01182 if (contact) {
01183 dialog = NAT_Contact_get_dialog(contact, dlg);
01184 if (dialog) {
01185 SIP_Dialog_end(dialog);
01186 }
01187 }
01188
01189 lock_release(&nat_table->slots[h].lock);
01190 }
01191
01192 lock_get(¶m->lock);
01193
01194
01195
01196 for (i=0; i<param->callee_candidates.count; i++) {
01197 h = HASH(nat_table, param->callee_candidates.uri[i]);
01198 lock_get(&nat_table->slots[h].lock);
01199
01200 contact = HashTable_search(nat_table, param->callee_candidates.uri[i], h);
01201 if (contact) {
01202 dialog = NAT_Contact_get_dialog(contact, dlg);
01203 if (dialog) {
01204 SIP_Dialog_end(dialog);
01205 }
01206 }
01207
01208 lock_release(&nat_table->slots[h].lock);
01209
01210 shm_free(param->callee_candidates.uri[i]);
01211 param->callee_candidates.uri[i] = NULL;
01212 }
01213
01214 param->callee_candidates.count = 0;
01215
01216 lock_release(¶m->lock);
01217
01218 Dialog_Param_del(param);
01219
01220 *_params->param = NULL;
01221 }
01222
01223
01224 static void
01225 __dialog_created(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
01226 {
01227 struct sip_msg *request = _params->req;
01228 NAT_Contact *contact;
01229 SIP_Dialog *dialog;
01230 Dialog_Param *param;
01231 unsigned h;
01232 char *uri;
01233
01234 if (request->REQ_METHOD != METHOD_INVITE)
01235 return;
01236
01237 param = Dialog_Param_new();
01238 if (!param) {
01239 LM_ERR("cannot create dialog callback param\n");
01240 return;
01241 }
01242
01243 if (dlg_api.register_dlgcb(dlg, DLGCB_DESTROY, __dialog_destroy, param, NULL) != 0) {
01244 LM_ERR("cannot register callback for dialog destruction\n");
01245 Dialog_Param_del(param);
01246 return;
01247 }
01248
01249 if (dlg_api.register_dlgcb(dlg, DLGCB_EARLY, __dialog_early, param, NULL) != 0)
01250 LM_ERR("cannot register callback for dialog early replies\n");
01251 if (dlg_api.register_dlgcb(dlg, DLGCB_CONFIRMED_NA, __dialog_confirmed, param, NULL) != 0)
01252 LM_ERR("cannot register callback for dialog confirmation\n");
01253
01254 if ((request->msg_flags & FL_DO_KEEPALIVE) == 0)
01255 return;
01256
01257 uri = get_source_uri(request);
01258 param->caller_uri = shm_strdup(uri);
01259 if (!param->caller_uri) {
01260 LM_ERR("cannot allocate shared memory for caller_uri in dialog param\n");
01261 return;
01262 }
01263
01264 h = HASH(nat_table, uri);
01265 lock_get(&nat_table->slots[h].lock);
01266
01267 contact = HashTable_search(nat_table, uri, h);
01268 if (contact) {
01269 dialog = SIP_Dialog_new(dlg, param->expire);
01270 if (dialog) {
01271 dialog->next = contact->dialogs;
01272 contact->dialogs = dialog;
01273 } else {
01274 LM_ERR("cannot allocate shared memory for new SIP dialog\n");
01275 }
01276 } else {
01277 contact = NAT_Contact_new(uri, request->rcv.bind_address);
01278 if (contact) {
01279 contact->dialogs = SIP_Dialog_new(dlg, param->expire);
01280 if (contact->dialogs) {
01281 contact->next = nat_table->slots[h].head;
01282 nat_table->slots[h].head = contact;
01283 } else {
01284 LM_ERR("cannot allocate shared memory for new SIP dialog\n");
01285 NAT_Contact_del(contact);
01286 }
01287 } else {
01288 LM_ERR("cannot allocate shared memory for new NAT contact\n");
01289 }
01290 }
01291
01292 lock_release(&nat_table->slots[h].lock);
01293 }
01294
01295
01296
01297
01298 static void
01299 __sl_reply_out(sl_cbp_t *slcbp)
01300 {
01301 struct sip_msg reply;
01302 struct sip_msg *request;
01303 time_t expire;
01304
01305 request = slcbp->req;
01306 if (request->REQ_METHOD == METHOD_INVITE)
01307 return;
01308
01309 if ((request->msg_flags & FL_DO_KEEPALIVE) == 0)
01310 return;
01311
01312 if (slcbp->code >= 200 && slcbp->code < 300) {
01313 memset(&reply, 0, sizeof(struct sip_msg));
01314 reply.buf = slcbp->reply->s;
01315 reply.len = slcbp->reply->len;
01316
01317 if (parse_msg(reply.buf, reply.len, &reply) != 0) {
01318 LM_ERR("cannot parse outgoing SL reply for keepalive"
01319 " information\n");
01320 return;
01321 }
01322
01323 switch (request->REQ_METHOD) {
01324 case METHOD_SUBSCRIBE:
01325 expire = get_expires(&reply);
01326 if (expire > 0)
01327 keepalive_subscription(request, expire);
01328 break;
01329 case METHOD_REGISTER:
01330 expire = get_register_expire(request, &reply);
01331 if (expire > 0)
01332 keepalive_registration(request, expire);
01333 break;
01334 default:
01335 LM_ERR("called with keepalive flag set for unsupported method\n");
01336 break;
01337 }
01338
01339 free_sip_msg(&reply);
01340 }
01341 }
01342
01343
01344
01345
01346 static void
01347 __tm_reply_in(struct cell *trans, int type, struct tmcb_params *param)
01348 {
01349 time_t expire;
01350
01351 if (param->req==NULL || param->rpl==NULL)
01352 return;
01353
01354 if (param->code >= 200 && param->code < 300) {
01355 switch (param->req->REQ_METHOD) {
01356 case METHOD_SUBSCRIBE:
01357 expire = get_expires(param->rpl);
01358 if (expire > 0)
01359 keepalive_subscription(param->req, expire);
01360 break;
01361 case METHOD_REGISTER:
01362 expire = get_register_expire(param->req, param->rpl);
01363 if (expire > 0)
01364 keepalive_registration(param->req, expire);
01365 break;
01366 }
01367 }
01368 }
01369
01370
01371
01372
01373 static int
01374 NAT_Keepalive(struct sip_msg *msg)
01375 {
01376
01377 if (keepalive_disabled)
01378 return -1;
01379
01380
01381 if (msg->rcv.proto!=PROTO_UDP)
01382 return -1;
01383
01384 switch (msg->REQ_METHOD) {
01385
01386 case METHOD_REGISTER:
01387
01388 if (parse_headers(msg, HDR_EOH_F, 0) < 0) {
01389 LM_ERR("failed to parse headers in REGISTER request\n");
01390 return -1;
01391 }
01392
01393 case METHOD_SUBSCRIBE:
01394 msg->msg_flags |= FL_DO_KEEPALIVE;
01395 if (tm_api.register_tmcb(msg, 0, TMCB_RESPONSE_IN, __tm_reply_in, 0, 0) <= 0) {
01396 LM_ERR("cannot register TM callback for incoming replies\n");
01397 return -1;
01398 }
01399 return 1;
01400
01401 case METHOD_INVITE:
01402 if (!have_dlg_api) {
01403 LM_ERR("cannot keep alive dialog without the dialog module being loaded\n");
01404 return -1;
01405 }
01406 msg->msg_flags |= FL_DO_KEEPALIVE;
01407 setflag(msg, dialog_flag);
01408 return 1;
01409
01410 default:
01411 LM_ERR("unsupported method for keepalive\n");
01412 return -1;
01413 }
01414
01415 }
01416
01417
01418
01419 static int
01420 FixContact(struct sip_msg *msg)
01421 {
01422 str before_host, after, newip;
01423 unsigned short port, newport;
01424 contact_t* contact;
01425 struct lump* anchor;
01426 struct sip_uri uri;
01427 int len, offset;
01428 char *buf;
01429
01430 if (!get_contact_uri(msg, &uri, &contact))
01431 return -1;
01432
01433 newip.s = ip_addr2a(&msg->rcv.src_ip);
01434 newip.len = strlen(newip.s);
01435 newport = msg->rcv.src_port;
01436
01437 port = uri.port_no ? uri.port_no : 5060;
01438
01439
01440 if (STR_MATCH_STR(uri.host, newip) && port==newport)
01441 return 1;
01442
01443 if (uri.port.len == 0)
01444 uri.port.s = uri.host.s + uri.host.len;
01445
01446 before_host.s = contact->uri.s;
01447 before_host.len = uri.host.s - contact->uri.s;
01448 after.s = uri.port.s + uri.port.len;
01449 after.len = contact->uri.s + contact->uri.len - after.s;
01450
01451 len = before_host.len + newip.len + after.len + 20;
01452
01453
01454
01455 buf = pkg_malloc(len);
01456 if (buf == NULL) {
01457 LM_ERR("out of memory\n");
01458 return -1;
01459 }
01460
01461 offset = contact->uri.s - msg->buf;
01462 anchor = del_lump(msg, offset, contact->uri.len, HDR_CONTACT_F);
01463
01464 if (!anchor) {
01465 pkg_free(buf);
01466 return -1;
01467 }
01468
01469 len = sprintf(buf, "%.*s%s:%d%.*s", before_host.len, before_host.s,
01470 newip.s, newport, after.len, after.s);
01471
01472 if (insert_new_lump_after(anchor, buf, len, HDR_CONTACT_F) == 0) {
01473 pkg_free(buf);
01474 return -1;
01475 }
01476
01477 contact->uri.s = buf;
01478 contact->uri.len = len;
01479
01480 return 1;
01481 }
01482
01483
01484 static int
01485 ClientNatTest(struct sip_msg *msg, unsigned int tests)
01486 {
01487 int i;
01488
01489 for (i=0; NAT_Tests[i].test!=NTNone; i++) {
01490 if ((tests & NAT_Tests[i].test)!=0 && NAT_Tests[i].proc(msg)) {
01491 return 1;
01492 }
01493 }
01494
01495 return -1;
01496 }
01497
01498
01499 #define FROM_PREFIX "sip:keepalive@"
01500
01501 static void
01502 send_keepalive(NAT_Contact *contact)
01503 {
01504 char buffer[8192], *from_uri, *ptr;
01505 static char from[64] = FROM_PREFIX;
01506 static char *from_ip = from + sizeof(FROM_PREFIX) - 1;
01507 static struct socket_info *last_socket = NULL;
01508 struct hostent* hostent;
01509 struct dest_info dst;
01510 int nat_port, len;
01511 str nat_ip;
01512
01513 if (keepalive_params.from == NULL) {
01514 if (contact->socket != last_socket) {
01515 memcpy(from_ip, contact->socket->address_str.s, contact->socket->address_str.len);
01516 from_ip[contact->socket->address_str.len] = 0;
01517 last_socket = contact->socket;
01518 }
01519 from_uri = from;
01520 } else {
01521 from_uri = keepalive_params.from;
01522 }
01523
01524 len = snprintf(buffer, sizeof(buffer),
01525 "%s %s SIP/2.0\r\n"
01526 "Via: SIP/2.0/UDP %.*s:%d;branch=0\r\n"
01527 "From: %s;tag=%x\r\n"
01528 "To: %s\r\n"
01529 "Call-ID: %s-%x-%x@%.*s\r\n"
01530 "CSeq: 1 %s\r\n"
01531 "%s%s"
01532 "Content-Length: 0\r\n\r\n",
01533 keepalive_params.method, contact->uri,
01534 contact->socket->address_str.len,
01535 contact->socket->address_str.s, contact->socket->port_no,
01536 from_uri, keepalive_params.from_tag++,
01537 contact->uri, keepalive_params.callid_prefix,
01538 keepalive_params.callid_counter++, get_ticks(),
01539 contact->socket->address_str.len,
01540 contact->socket->address_str.s,
01541 keepalive_params.method,
01542 keepalive_params.event_header,
01543 keepalive_params.extra_headers);
01544
01545 if (len >= sizeof(buffer)) {
01546 LM_ERR("keepalive message is longer than %lu bytes\n", (unsigned long)sizeof(buffer));
01547 return;
01548 }
01549
01550 init_dest_info(&dst);
01551
01552 nat_ip.s = &contact->uri[4];
01553 ptr = strchr(nat_ip.s, ':');
01554 nat_ip.len = ptr - nat_ip.s;
01555 nat_port = strtol(ptr+1, NULL, 10);
01556 hostent = sip_resolvehost(&nat_ip, NULL, NULL);
01557 hostent2su(&dst.to, hostent, 0, nat_port);
01558 dst.proto=PROTO_UDP;
01559 dst.send_sock=contact->socket;
01560 udp_send(&dst, buffer, len);
01561 }
01562
01563
01564 static void
01565 keepalive_timer(unsigned int ticks, void *data)
01566 {
01567 static unsigned iteration = 0;
01568 NAT_Contact *contact;
01569 HashSlot *slot;
01570 time_t now;
01571 int i;
01572
01573 now = time(NULL);
01574
01575 for (i=0; i<nat_table->size; i++) {
01576
01577 if ((i % keepalive_interval) != iteration)
01578 continue;
01579
01580 slot = &nat_table->slots[i];
01581
01582 lock_get(&slot->lock);
01583
01584 slot->head = NAT_Contact_purge_expired(slot->head, now);
01585 contact = slot->head;
01586
01587 lock_release(&slot->lock);
01588
01589 while (contact) {
01590 send_keepalive(contact);
01591 contact = contact->next;
01592 }
01593 }
01594
01595 iteration = (iteration+1) % keepalive_interval;
01596 }
01597
01598
01599
01600
01601
01602
01603 #define STATE_FILE_HEADER "# Automatically generated file from internal keepalive state. Do NOT modify!\n"
01604
01605 static void
01606 save_keepalive_state(void)
01607 {
01608 NAT_Contact *contact;
01609 FILE *f;
01610 int i;
01611
01612 if (!keepalive_state_file)
01613 return;
01614
01615 f = fopen(keepalive_state_file, "w");
01616 if (!f) {
01617 LM_ERR("failed to open keepalive state file for writing: %s\n", strerror(errno));
01618 return;
01619 }
01620
01621 fprintf(f, STATE_FILE_HEADER);
01622
01623 for (i=0; i<nat_table->size; i++) {
01624 contact = nat_table->slots[i].head;
01625 while (contact) {
01626 fprintf(f, "%s %.*s %ld %ld\n",
01627 contact->uri,
01628 contact->socket->sock_str.len, contact->socket->sock_str.s,
01629 (long int)contact->registration_expire,
01630 (long int)contact->subscription_expire);
01631 contact = contact->next;
01632 }
01633 }
01634
01635 if (ferror(f))
01636 LM_ERR("couldn't write keepalive state file: %s\n", strerror(errno));
01637
01638 fclose(f);
01639 }
01640
01641
01642 static void
01643 restore_keepalive_state(void)
01644 {
01645 char uri[64], socket[64];
01646 time_t rtime, stime, now;
01647 NAT_Contact *contact;
01648 struct socket_info *sock;
01649 int port, proto, res;
01650 unsigned h;
01651 str host;
01652 FILE *f;
01653
01654 if (!keepalive_state_file)
01655 return;
01656
01657 f = fopen(keepalive_state_file, "r");
01658 if (!f) {
01659 if (errno != ENOENT)
01660 LM_ERR("failed to open keepalive state file for reading: %s\n", strerror(errno));
01661 return;
01662 }
01663
01664 now = time(NULL);
01665
01666 res = fscanf(f, STATE_FILE_HEADER);
01667
01668 while (True) {
01669 res = fscanf(f, "%63s %63s %ld %ld", uri, socket, &rtime, &stime);
01670 if (res == EOF) {
01671 if (ferror(f))
01672 LM_ERR("error while reading keepalive state file: %s\n", strerror(errno));
01673 break;
01674 } else if (res != 4) {
01675 LM_ERR("invalid/corrupted keepalive state file. ignoring remaining entries.\n");
01676 break;
01677 } else {
01678 if (now > rtime && now > stime)
01679 continue;
01680
01681 if (parse_phostport(socket, &host.s, &host.len, &port, &proto) < 0)
01682 continue;
01683
01684 sock = grep_sock_info(&host, (unsigned short)port, (unsigned short)proto);
01685 if (!sock)
01686 continue;
01687
01688 h = HASH(nat_table, uri);
01689 contact = NAT_Contact_new(uri, sock);
01690 if (contact) {
01691 SIP_Registration_update(contact, rtime);
01692 SIP_Subscription_update(contact, stime);
01693 contact->next = nat_table->slots[h].head;
01694 nat_table->slots[h].head = contact;
01695 } else {
01696 LM_ERR("cannot allocate shared memory for new NAT contact\n");
01697 break;
01698 }
01699 }
01700 }
01701
01702 fclose(f);
01703 }
01704
01705
01706
01707
01708
01709 static int
01710 mod_init(void)
01711 {
01712 sl_cbelem_t slcb;
01713 int *param;
01714 modparam_t type;
01715
01716 if (keepalive_interval <= 0) {
01717 LM_NOTICE("keepalive functionality is disabled from the configuration\n");
01718 keepalive_disabled = True;
01719 return 0;
01720 }
01721
01722
01723 if (sl_load_api(&slb)!=0) {
01724 LM_ERR("cannot bind to SL API\n");
01725 return -1;
01726 }
01727
01728 memset(&slcb, 0, sizeof(sl_cbelem_t));
01729 slcb.type = SLCB_REPLY_READY;
01730 slcb.cbf = __sl_reply_out;
01731 if (slb.register_cb(&slcb) != 0) {
01732 LM_ERR("cannot register callback for stateless outgoing replies\n");
01733 return -1;
01734 }
01735
01736
01737 if (load_tm_api(&tm_api)!=0) {
01738 LM_ERR("cannot load the tm module API\n");
01739 return -1;
01740 }
01741
01742
01743 if (load_dlg_api(&dlg_api)==0) {
01744 have_dlg_api = True;
01745
01746
01747 param = find_param_export(find_module_by_name("dialog"),
01748 "dlg_flag", INT_PARAM, &type);
01749 if (!param) {
01750 LM_ERR("cannot find dlg_flag parameter in the dialog module\n");
01751 return -1;
01752 }
01753 dialog_flag = *param;
01754
01755 param = find_param_export(find_module_by_name("dialog"),
01756 "default_timeout", INT_PARAM, &type);
01757 if (!param) {
01758 LM_ERR("cannot find default_timeout parameter in the dialog module\n");
01759 return -1;
01760 }
01761 dialog_default_timeout = *param;
01762
01763
01764 if (dlg_api.register_dlgcb(NULL, DLGCB_CREATED, __dialog_created, NULL, NULL) != 0) {
01765 LM_ERR("cannot register callback for dialog creation\n");
01766 return -1;
01767 }
01768
01769
01770 if (register_script_cb(preprocess_request, PRE_SCRIPT_CB|REQUEST_CB, 0)!=0) {
01771 LM_ERR("could not register request preprocessing callback\n");
01772 return -1;
01773 }
01774
01775 } else {
01776 LM_NOTICE("keeping alive dialogs is disabled because the dialog module is not loaded\n");
01777 }
01778
01779
01780 if (keepalive_params.from!=NULL && *(keepalive_params.from)==0) {
01781 LM_WARN("ignoring empty keepalive_from parameter\n");
01782 keepalive_params.from = NULL;
01783 }
01784 if (strcasecmp(keepalive_params.method, "NOTIFY")==0)
01785 keepalive_params.event_header = "Event: keep-alive\r\n";
01786 snprintf(keepalive_params.callid_prefix, 20, "%x", rand());
01787 keepalive_params.callid_counter = rand();
01788 keepalive_params.from_tag = rand();
01789
01790 #ifdef STATISTICS
01791
01792 if (register_module_stats(exports.name, statistics) < 0) {
01793 LM_ERR("failed to initialize module statistics\n");
01794 return -1;
01795 }
01796 #endif
01797
01798
01799 nat_table = HashTable_new();
01800 if (!nat_table) {
01801 LM_ERR("cannot create hash table to store NAT endpoints\n");
01802 return -1;
01803 }
01804 restore_keepalive_state();
01805
01806
01807 if (keepalive_interval < 10) {
01808 LM_WARN("keepalive_interval should be at least 10 seconds\n");
01809 LM_NOTICE("using 10 seconds for keepalive_interval\n");
01810 keepalive_interval = 10;
01811 }
01812 register_dummy_timers(1);
01813
01814 return 0;
01815 }
01816
01817 static int
01818 child_init(int rank)
01819 {
01820 if (rank==PROC_MAIN) {
01821 if(fork_dummy_timer(PROC_TIMER, "TIMER NT", 1 ,
01822 keepalive_timer, NULL, 1 )<0) {
01823 LM_ERR("failed to register keepalive timer process\n");
01824 return -1;
01825 }
01826 }
01827 return 0;
01828 }
01829
01830 static void
01831 mod_destroy(void)
01832 {
01833 if (nat_table) {
01834 save_keepalive_state();
01835 HashTable_del(nat_table);
01836 nat_table = NULL;
01837 }
01838 }
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850 static int
01851 preprocess_request(struct sip_msg *msg, unsigned int flags, void *_param)
01852 {
01853 str totag;
01854
01855 if (msg->first_line.u.request.method_value!=METHOD_INVITE)
01856 return 1;
01857
01858 if (parse_headers(msg, HDR_TO_F, 0) == -1) {
01859 LM_ERR("failed to parse To header\n");
01860 return -1;
01861 }
01862 if (!msg->to) {
01863 LM_ERR("missing To header\n");
01864 return -1;
01865 }
01866 totag = get_to(msg)->tag_value;
01867 if (totag.s==0 || totag.len==0) {
01868 setflag(msg, dialog_flag);
01869 }
01870
01871 return 1;
01872 }
01873
01874
01875
01876
01877 static int
01878 reply_filter(struct sip_msg *reply)
01879 {
01880 struct cseq_body *cseq;
01881 static str prefix = {NULL, 0};
01882 str call_id;
01883
01884 parse_headers(reply, HDR_VIA2_F, 0);
01885 if (reply->via2)
01886 return 1;
01887
01888
01889 if (!reply->cseq && parse_headers(reply, HDR_CSEQ_F, 0) < 0) {
01890 LM_ERR("failed to parse the CSeq header\n");
01891 return -1;
01892 }
01893 if (!reply->cseq) {
01894 LM_ERR("missing CSeq header\n");
01895 return -1;
01896 }
01897 cseq = reply->cseq->parsed;
01898 if (!STR_MATCH(cseq->method, keepalive_params.method))
01899 return 1;
01900
01901
01902 if (!reply->callid && parse_headers(reply, HDR_CALLID_F, 0) < 0) {
01903 LM_ERR("failed to parse the Call-ID header\n");
01904 return -1;
01905 }
01906 if (!reply->callid) {
01907 LM_ERR("missing Call-ID header\n");
01908 return -1;
01909 }
01910 call_id = reply->callid->body;
01911 if (prefix.s == NULL) {
01912 prefix.s = keepalive_params.callid_prefix;
01913 prefix.len = strlen(prefix.s);
01914 }
01915 if (!STR_HAS_PREFIX(call_id, prefix) || call_id.s[prefix.len]!='-')
01916 return 1;
01917
01918 return 0;
01919 }
01920
01921
01922
01923
01924
01925 static int
01926 pv_parse_nat_contact_name(pv_spec_p sp, str *in)
01927 {
01928 char *p;
01929 char *s;
01930 pv_spec_p nsp = 0;
01931
01932 if(in==NULL || in->s==NULL || sp==NULL)
01933 return -1;
01934 p = in->s;
01935 if (*p==PV_MARKER) {
01936 nsp = (pv_spec_p)pkg_malloc(sizeof(pv_spec_t));
01937 if (nsp==NULL) {
01938 LM_ERR("cannot allocate private memory\n");
01939 return -1;
01940 }
01941 s = pv_parse_spec(in, nsp);
01942 if (s==NULL) {
01943 LM_ERR("invalid name [%.*s]\n", in->len, in->s);
01944 pv_spec_free(nsp);
01945 return -1;
01946 }
01947 sp->pvp.pvn.type = PV_NAME_PVAR;
01948 sp->pvp.pvn.u.dname = (void*)nsp;
01949 return 0;
01950 }
01951
01952 sp->pvp.pvn.type = PV_NAME_INTSTR;
01953 sp->pvp.pvn.u.isname.type = AVP_NAME_STR;
01954 sp->pvp.pvn.u.isname.name.s = *in;
01955
01956 return 0;
01957 }
01958
01959
01960 static int
01961 pv_get_keepalive_socket(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
01962 {
01963 static char uri[128];
01964 NAT_Contact *contact;
01965 pv_value_t tv;
01966 unsigned h;
01967
01968 if (msg==NULL || param==NULL || res==NULL)
01969 return -1;
01970
01971 if (pv_get_spec_name(msg, param, &tv)!=0 || (!(tv.flags&PV_VAL_STR))) {
01972 LM_ERR("invalid NAT contact uri\n");
01973 return -1;
01974 }
01975
01976 if (tv.rs.len > sizeof(uri)-1) {
01977 LM_ERR("NAT contact uri too long\n");
01978 return -1;
01979 }
01980
01981 strncpy(uri, tv.rs.s, tv.rs.len);
01982 uri[tv.rs.len] = 0;
01983
01984 h = HASH(nat_table, uri);
01985 lock_get(&nat_table->slots[h].lock);
01986
01987 contact = HashTable_search(nat_table, uri, h);
01988 if (!contact) {
01989 lock_release(&nat_table->slots[h].lock);
01990 return pv_get_null(msg, param, res);
01991 }
01992
01993 res->rs = contact->socket->sock_str;
01994 res->flags = PV_VAL_STR;
01995
01996 lock_release(&nat_table->slots[h].lock);
01997
01998 return 0;
01999 }
02000
02001
02002 static int
02003 pv_get_source_uri(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
02004 {
02005 static char uri[128];
02006
02007 if (msg==NULL || res==NULL)
02008 return -1;
02009
02010 snprintf(uri, 64, "sip:%s:%d", ip_addr2a(&msg->rcv.src_ip), msg->rcv.src_port);
02011
02012 switch (msg->rcv.proto) {
02013 case PROTO_TCP:
02014 strcat(uri, ";transport=tcp");
02015 break;
02016 case PROTO_TLS:
02017 strcat(uri, ";transport=tls");
02018 break;
02019 case PROTO_SCTP:
02020 strcat(uri, ";transport=sctp");
02021 break;
02022 }
02023
02024 res->rs.s = uri;
02025 res->rs.len = strlen(uri);
02026 res->flags = PV_VAL_STR;
02027
02028 return 0;
02029 }
02030
02031