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