nat_traversal.c

Go to the documentation of this file.
00001 /* $Id: nat_traversal.c 5753 2009-03-23 13:03:34Z henningw $
00002  *
00003  * Copyright (C) 2007-2008 Dan Pascu
00004  *
00005  * This file is part of Kamailio, a free SIP server.
00006  *
00007  * Kamailio is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2 of the License, or
00010  * (at your option) any later version
00011  *
00012  * Kamailio is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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;  // pointer to the head of the linked list stored in this slot
00129     gen_lock_t lock;
00130 } HashSlot;
00131 
00132 
00133 typedef struct HashTable {
00134     HashSlot *slots;
00135     unsigned size;      // table size (number of slots)
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 // Module parameters
00157 //
00158 typedef struct Keepalive_Params {
00159     // user specified
00160     char *method;
00161     char *from;
00162     char *extra_headers;
00163 
00164     // internally generated
00165     char callid_prefix[20];
00166     unsigned callid_counter;
00167     unsigned from_tag;
00168     char *event_header; // this will be set if method is NOTIFY
00169 } Keepalive_Params;
00170 
00171 
00172 // Function prototypes
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 // Module global variables and state
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;  // 12 hours
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, &registered_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", // module name
00265     DEFAULT_DLFLAGS, // dlopen flags
00266     commands,        // exported functions
00267     parameters,      // exported parameters
00268     NULL,            // exported statistics (initialized early in mod_init)
00269     NULL,            // exported MI functions
00270     pvars,           // exported pseudo-variables
00271     NULL,            // extra processes
00272     mod_init,        // module init function (before fork. kids will inherit)
00273     reply_filter,    // reply processing function
00274     mod_destroy,     // destroy function
00275     0                // child init function
00276 };
00277 
00278 
00279 
00280 // SIP_Dialog structure handling functions
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     // we assume expire is always strictly positive on new dialogs
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 // Purge expired dialogs from the linked list pointed by dialog
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 // Helpers to handle registration and subscription timeouts for NAT_Contacts
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 // NAT_Contact structure handling functions
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 // HashTable structure manipulation
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 // This function assumes that the caller has locked the slot already
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 // Dialog_Param structure handling functions
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(&param->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(&param->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 // This function assumes the caller has locked the Dialog_Param while operating on it
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 // This function assumes the caller has locked the Dialog_Param while operating on it
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 // Miscellaneous helper functions
00701 //
00702 
00703 // returns str with leading whitespace removed
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 // returns str with trailing whitespace removed
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 // returns str with leading and trailing whitespace removed
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 // Test if IP in `address' belongs to a RFC1918 network
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; // invalid address to test
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 // Test if address of signaling is different from address in 1st Via field
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 // Test if Contact field contains a private IP address as defined in RFC1918
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 // Test if top Via field contains a private IP address as defined in RFC1918
00835 static Bool
00836 test_private_via(struct sip_msg *msg)
00837 {
00838     return is_private_address(&(msg->via1->host));
00839 }
00840 
00841 
00842 // return the Expires header value (converted to an UNIX timestamp if > 0)
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 // return the highest expire value from all registered contacts in the request
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     // request may be R/O (if we are called from the TM callback),
00892     // thus we copy the hdr_field structures before parsing them
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(&param->lock);
01021 
01022     if (param->confirmed) {
01023         // this 1xx is late; dialog already confirmed by 200 OK; ignore it
01024         lock_release(&param->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(&param->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(&param->lock);
01069 
01070     param->confirmed = True;
01071 
01072     callee_uri = get_source_uri(_params->msg);
01073 
01074     // remove all keepalives on unanswered branches
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             // this is an unanswered branch
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     // add dialog keepalive for answered branch, if needed and not already there
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         // free old uri in case this callback is called more than once (shouldn't normally happen)
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(&param->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     // If nat_table is NULL, it's because it was already removed during
01144     // shutdown by mod_destroy. However we can still receive dialog destroy
01145     // notifications when the dialog module removes dialogs on shutdown.
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(&param->lock);
01183 
01184     // remove all keepalives on unanswered branches. this is neded because
01185     // we may transit from early to ended without going through confirmed
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(&param->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 // callback to handle all SL generated replies
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 // callback to handle incoming replies for the request's transactions
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 // Keepalive NAT for an UA while it has registered contacts or active dialogs
01359 //
01360 static int
01361 NAT_Keepalive(struct sip_msg *msg)
01362 {
01363 
01364     if (keepalive_disabled)
01365         return -1;
01366 
01367     // keepalive is only supported for UDP dialogs
01368     if (msg->rcv.proto!=PROTO_UDP)
01369         return -1;
01370 
01371     switch (msg->REQ_METHOD) {
01372 
01373     case METHOD_REGISTER:
01374         // make the expires & contact headers available later in the TM cloned msg
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         // fallthrough
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); // have the dialog module trace this dialog
01395         return 1;
01396 
01397     default:
01398         LM_ERR("unsupported method for keepalive\n");
01399         return -1;
01400     }
01401 
01402 }
01403 
01404 
01405 // Replace IP:Port in Contact field with the source address of the packet.
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     // Don't do anything if the IP's are the same, just return success.
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     // first try to alloc mem. if we fail we don't want to have the lump
01438     // deleted and not replaced. at least this way we keep the original.
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; // all failed
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     //nat_ip.s = strchr(contact->uri, ':') + 1;
01509     nat_ip.s = &contact->uri[4]; // skip over "sip:"
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 // Functions to save and restore the keepalive NAT table. They should only be
01555 // called from mod_init/mod_destroy as they access shm memory without locking
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); // skip 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; // expired entry
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; // socket no longer available since last time. ignore.
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 // Module management: initialization/destroy/function-parameter-fixing/...
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     // get SL module callback registration function
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     // bind to the TM API
01688     if (load_tm_api(&tm_api)!=0) {
01689         LM_ERR("cannot load the tm module API\n");
01690         return -1;
01691     }
01692 
01693     // bind to the dialog API
01694     if (load_dlg_api(&dlg_api)==0) {
01695         have_dlg_api = True;
01696 
01697         // load dlg_flag and default_timeout parameters from the dialog module
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         // register dialog creation callback
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         // register a pre-script callback to automatically enable dialog tracing
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     // initialize the keepalive message parameters
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     // we need the statistics initialized before restoring the keepalive state
01740     if (register_module_stats(exports.name, statistics) < 0) {
01741         LM_ERR("failed to initialize module statistics\n");
01742         return -1;
01743     }
01744 
01745     // create hash table to hold NAT contacts
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     // check keepalive interval and add keepalive timer process
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 // Preprocess a request before it is processed in the main script route
01780 //
01781 // Here we enable dialog tracing to be able to automatically extend an
01782 // existing registration keepalive to a destination, for the duration of
01783 // the dialog, even if the dialog source is not kept alive by explicitly
01784 // calling nat_keepalive(). This is needed to still be able to forward
01785 // messages to the callee, even if the registration keepalive expires
01786 // during the dialog and it is not renewed.
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 // Filter out replies to keepalive messages
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     // check if the method from CSeq header matches our method
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     // check if callid_prefix matches
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 // Pseudo variable management
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 

Generated on Wed May 23 20:00:28 2012 for Kamailio - The Open Source SIP Server by  doxygen 1.5.6