Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:00:56 2007

Asterisk developer's documentation :: Codename Pineapple


sip3_dialog.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2007, Digium, Inc.
00005  * and Edvina AB, Sollentuna, Sweden (chan_sip3 changes/additions)
00006  *
00007  * Mark Spencer <markster@digium.com>
00008  *
00009  * See http://www.asterisk.org for more information about
00010  * the Asterisk project. Please do not directly contact
00011  * any of the maintainers of this project for assistance;
00012  * the project provides a web site, mailing lists and IRC
00013  * channels for your use.
00014  *
00015  * This program is free software, distributed under the terms of
00016  * the GNU General Public License Version 2. See the LICENSE file
00017  * at the top of the source tree.
00018  */
00019 
00020 /*!
00021  * \file
00022  * \brief Various SIP dialog handlers
00023  * Version 3 of chan_sip
00024  *
00025  * \author Mark Spencer <markster@digium.com>
00026  * \author Olle E. Johansson <oej@edvina.net> (all the chan_sip3 changes)
00027  *
00028  * See Also:
00029  * \arg \ref AstCREDITS
00030  *
00031  */
00032 
00033 #include "asterisk.h"
00034 
00035 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 53128 $")
00036 
00037 #include <stdio.h>
00038 #include <ctype.h>
00039 #include <string.h>
00040 #include <unistd.h>
00041 #include <sys/socket.h>
00042 #include <sys/ioctl.h>
00043 #include <net/if.h>
00044 #include <errno.h>
00045 #include <stdlib.h>
00046 #include <fcntl.h>
00047 #include <netdb.h>
00048 #include <signal.h>
00049 #include <sys/signal.h>
00050 #include <netinet/in.h>
00051 #include <netinet/in_systm.h>
00052 #include <arpa/inet.h>
00053 #include <netinet/ip.h>
00054 #include <regex.h>
00055 
00056 #include "asterisk/lock.h"
00057 #include "asterisk/channel.h"
00058 #include "asterisk/config.h"
00059 #include "asterisk/logger.h"
00060 #include "asterisk/module.h"
00061 #include "asterisk/pbx.h"
00062 #include "asterisk/options.h"
00063 #include "asterisk/sched.h"
00064 #include "asterisk/io.h"
00065 #include "asterisk/rtp.h"
00066 #include "asterisk/udptl.h"
00067 #include "asterisk/acl.h"
00068 #include "asterisk/manager.h"
00069 #include "asterisk/callerid.h"
00070 #include "asterisk/cli.h"
00071 #include "asterisk/app.h"
00072 #include "asterisk/musiconhold.h"
00073 #include "asterisk/dsp.h"
00074 #include "asterisk/features.h"
00075 #include "asterisk/srv.h"
00076 #include "asterisk/astdb.h"
00077 #include "asterisk/causes.h"
00078 #include "asterisk/utils.h"
00079 #include "asterisk/file.h"
00080 #include "asterisk/astobj.h"
00081 #include "asterisk/dnsmgr.h"
00082 #include "asterisk/devicestate.h"
00083 #include "asterisk/linkedlists.h"
00084 #include "asterisk/stringfields.h"
00085 #include "asterisk/monitor.h"
00086 #include "asterisk/localtime.h"
00087 #include "asterisk/abstract_jb.h"
00088 #include "asterisk/compiler.h"
00089 #include "asterisk/threadstorage.h"
00090 #include "sip3.h"
00091 #include "sip3funcs.h"
00092 
00093 /*! \page chan_sip3_dialogs Chan_sip3: The dialog list
00094    \par The dialog list
00095    The dialog list contains all active dialogs in various states.
00096    A dialog can be 
00097    - an active call
00098    - a call in hangup state - waiting for cleanup
00099    - a subscription
00100    - an inbound or outbound registration
00101    
00102    \ref dialoglist
00103 
00104    \par Dialog states
00105    Dialog states affect operation, especially in an INVITE
00106    dialog. We now try to change dialog state in a clear way
00107    \ref enum dialogstate
00108 
00109 */
00110 
00111 /* Forward declaration */
00112 static int temp_pvt_init(void *data);
00113 static void temp_pvt_cleanup(void *data);
00114 
00115 /*! \brief A per-thread temporary pvt structure */
00116 AST_THREADSTORAGE_CUSTOM(ts_temp_pvt, temp_pvt_init, temp_pvt_cleanup);
00117 
00118 /*! \brief Protect the SIP dialog list (of sip_dialog's) */
00119 AST_MUTEX_DEFINE_STATIC(dialoglock);
00120 
00121 /*! \brief Lock list of active SIP dialogs */
00122 void dialoglist_lock(void)
00123 {
00124    int counter = 0;
00125    while (ast_mutex_trylock(&dialoglock) && counter < 100) {
00126       if (option_debug > 4)
00127          ast_log(LOG_DEBUG, "---Trying to lock dialoglist -- %d \n", ++counter);
00128    } 
00129    if (counter == 100)
00130       ast_mutex_lock(&dialoglock);
00131    if (sipdebug && option_debug > 4)
00132       ast_log(LOG_DEBUG, "=== SIP dialog list: LOCKED\n");
00133 }
00134 
00135 /*! \brief Unlock list of active SIP dialogs */
00136 void dialoglist_unlock(void)
00137 {
00138    ast_mutex_unlock(&dialoglock);
00139    if (sipdebug && option_debug > 4)
00140       ast_log(LOG_DEBUG, "=== SIP dialog list: UNLOCKED\n");
00141 }
00142 
00143 /*! \brief Helper function to lock and unlock, hiding the underlying locking mechanism. 
00144    \param state TRUE for lock, FALSE for unlock
00145 */
00146 void dialog_lock(struct sip_dialog *dialog, int state)
00147 {
00148    if (!dialog) {
00149       ast_log(LOG_ERROR, "-DIALOGLOCK- Trying to %s non-existing dialog. Giving up.\n", state ? "lock" : "unlock");
00150       return;
00151    }
00152    if (sipdebug && option_debug > 4)
00153       ast_log(LOG_DEBUG, "-DIALOGLOCK- %s dialog %s\n", state ? "  locking" : "unlocking", dialog->callid ? dialog->callid : "<no callid>");
00154 
00155    if (state)
00156       ast_mutex_lock(&dialog->lock);
00157    else
00158       ast_mutex_unlock(&dialog->lock);
00159 }
00160 
00161 /*! \brief Convert SIP dialog states to string */
00162 const char *dialogstate2str(const enum dialogstate state)
00163 {
00164    const char *reply = "<unknown>";
00165    switch (state) {
00166    case DIALOG_STATE_TRYING:
00167       reply = "Trying";
00168       break;
00169    case DIALOG_STATE_PROCEEDING:
00170       reply = "Proceeding";
00171       break;
00172    case DIALOG_STATE_EARLY:
00173       reply = "Early";
00174       break;
00175    case DIALOG_STATE_CONFIRMED:
00176       reply = "Confirmed";
00177       break;
00178    case DIALOG_STATE_CONFIRMED_HOLD:
00179       reply = "Confirmed, on hold";
00180       break;
00181    case DIALOG_STATE_TERMINATED:
00182       reply = "Terminated";
00183       break;
00184    case DIALOG_STATE_TERMINATED_AUTH:
00185       reply = "Terminated, auth";
00186       break;
00187    }
00188    return reply;
00189 }
00190 
00191 /*! \brief Change dialog state for a SIP dialog and output to debug */
00192 void dialogstatechange(struct sip_dialog *dialog, enum dialogstate newstate)
00193 {
00194    if (dialog->state == newstate) {
00195       if (option_debug > 3)
00196          ast_log(LOG_DEBUG, "Asked to change state to dialog that already has requested state: %s State %s\n", dialog->callid, dialogstate2str(newstate));
00197    } else {
00198       dialog->state = newstate;
00199       if (sipdebug && option_debug > 1)
00200          ast_log(LOG_DEBUG, "-- Dialog %s changed state to %s\n", dialog->callid, dialogstate2str(newstate));
00201       if (global.recordhistory)
00202          append_history(dialog, "DialogState", "New state: %s O-Cseq %d I-Cseq %d", dialogstate2str(newstate), dialog->ocseq, dialog->icseq);
00203    }
00204    /* When state is terminated, keep it for 32 secs to allow for retransmits 
00205     */
00206 }
00207 
00208 
00209 /*! \brief Transmit final response to a request and close dialog 
00210    Set dialog state to TERMINATED to avoid problems
00211    At some point, after debugging, we can remove the reliable flag. Only responses to INVITEs are sent reliably 
00212  */
00213 int transmit_final_response(struct sip_dialog *dialog, const char *msg, struct sip_request *req, enum xmittype reliable)
00214 {
00215    int res;
00216 
00217    /* If this is a final response to an INVITE */
00218    if (reliable == XMIT_RELIABLE && req->method != SIP_INVITE)
00219       ast_log(LOG_WARNING, "Transmitting RELIABLE response to %s - Call ID %s (?? BUG ?? ) \n", sip_method2txt(req->method), dialog->callid);
00220    res = __transmit_response(dialog, msg, req, reliable);
00221    sip_scheddestroy(dialog, -1); /* Destroy by using T1 timer if available */
00222    dialogstatechange(dialog, DIALOG_STATE_TERMINATED);
00223    return res;
00224 }
00225 
00226 /*! \brief Set packet to initreq status. Set flag to avoid 
00227    de-allocation until dialog is destroyed 
00228 */
00229 void set_initreq(struct sip_dialog *dialog, struct sip_request *req)
00230 {
00231    dialog->initreq = req;
00232    ast_set_flag(dialog->initreq, SIP_PKT_INITREQ);
00233    
00234 }
00235 
00236 /*! \brief Initialize the initital request packet in the pvt structure.
00237    This packet is used for creating replies and future requests in
00238    a dialog */
00239 GNURK void initialize_initreq(struct sip_dialog *dialog, struct sip_request *req)
00240 {
00241    /* If we already have an initial req, free it if it's not waiting for an ACK */
00242    if (dialog->initreq) {
00243       if (option_debug > 2)
00244          ast_log(LOG_DEBUG, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", dialog->callid);
00245       if (!ast_test_flag(dialog->initreq, SIP_PKT_CONNECTED))
00246          siprequest_free(dialog->initreq);
00247    }
00248    /* Use this as the basis */
00249    set_initreq(dialog, req);
00250    //parse_request(dialog->initreq);
00251    if (ast_test_flag(req, SIP_PKT_DEBUG))
00252       ast_verbose("Initreq: %d headers, %d lines\n", dialog->initreq->headers, dialog->initreq->lines);
00253 }
00254 
00255 
00256 /*! \brief For a reliable transmission, we need to get an reply to stop retransmission. 
00257    Acknowledges receipt of a packet and stops retransmission 
00258    \note Assume that the dialog is locked. 
00259  */
00260 /* We need a method for responses too ... */
00261 void __sip_ack(struct sip_dialog *dialog, int seqno, int resp, int sipmethod, int reset)
00262 {
00263    struct sip_request *cur, *prev = NULL;
00264    int res = FALSE;
00265 
00266    if (option_debug) {
00267       if (!resp)
00268          ast_log(LOG_DEBUG, "Trying to confirm pending invite %d Call ID %s\n", dialog->pendinginvite, dialog->callid);
00269       else
00270          ast_log(LOG_DEBUG, "Trying to confirm pending response on Call ID %s\n", dialog->callid);
00271    }
00272 
00273    dialog_lock(dialog, TRUE);
00274 
00275    /* Find proper transaction */
00276    for (cur = dialog->packets; cur; prev = cur, cur = cur->next) {
00277       if (option_debug > 2)
00278          ast_log(LOG_DEBUG, "--Checking packet with seqno %d against response with seqno %d\n", cur->seqno, seqno);
00279       /* Match on seqno AND req/resp AND method? */
00280       if ((cur->seqno == seqno) && ((ast_test_flag(cur, SIP_PKT_RESPONSE)) == resp) &&
00281          ((ast_test_flag(cur, SIP_PKT_RESPONSE)) || (cur->method == sipmethod))) {
00282          if (!resp && (seqno == dialog->pendinginvite)) {
00283             if (sipdebug && option_debug && !reset)
00284                ast_log(LOG_DEBUG, "Got reply to pending invite %d - Call Id %s\n", dialog->pendinginvite, dialog->callid);
00285             dialog->pendinginvite = 0;
00286          } else {
00287             if (sipdebug && option_debug && !reset)
00288                ast_log(LOG_DEBUG, "Got ACK on INVITE response Cseq %d Call Id %s\n", cur->seqno, dialog->callid);
00289          }
00290          /* this is our baby */
00291          res = TRUE;
00292          UNLINK(cur, dialog->packets, prev);
00293          if (cur->retransid > -1) {
00294             if (sipdebug && option_debug > 3 && !reset)
00295                ast_log(LOG_DEBUG, "Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid);
00296             ast_sched_del(sched, cur->retransid);
00297             cur->retransid = -1;
00298          }
00299          if (!reset) {
00300             if (!ast_test_flag(cur, SIP_PKT_INITREQ)) 
00301                siprequest_free(cur);   /* We might want to keep this somewhere else */
00302             else {
00303                if (sipdebug && option_debug > 3 && !reset)
00304                   ast_log(LOG_DEBUG, "This is the initial request, keeping it in memory - Cseq %d\n", cur->seqno);
00305                ast_clear_flag(cur, SIP_PKT_CONNECTED);
00306                if (!ast_test_flag(cur, SIP_PKT_PARSED))
00307                   parse_request(cur);  /* Parse initreq now, after we have answer */
00308             }
00309          }
00310          break;
00311       }
00312    }
00313    dialog_lock(dialog, FALSE);
00314    if (option_debug && sipdebug)
00315       ast_log(LOG_DEBUG, "Stopping retransmission on '%s' of %s %d: Match %s\n", dialog->callid, resp ? "Response" : "Request", seqno, res ? "Found" : "Not Found");
00316 }
00317 
00318 /*! \brief Pretend to ack all packets - nothing to do with SIP_ACK (the method)
00319  *   maybe the lock on p is not strictly necessary but there might be a race */
00320 GNURK void __sip_pretend_ack(struct sip_dialog *dialog)
00321 {
00322    struct sip_request *cur = NULL;
00323 
00324    while (dialog->packets) {
00325       int method;
00326       if (cur == dialog->packets) {
00327          ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_method2txt(cur->method));
00328          return;
00329       }
00330       cur = dialog->packets;
00331       method = (cur->method) ? cur->method : find_sip_method(cur->data);
00332       __sip_ack(dialog, cur->seqno, ast_test_flag(cur, SIP_PKT_RESPONSE), method, FALSE);
00333    }
00334 }
00335 
00336 /*! \brief Acks receipt of packet, keep it around (used for provisional responses) 
00337    \note Assume that the dialog is locked.
00338  */
00339 int __sip_semi_ack(struct sip_dialog *dialog, int seqno, int resp, int sipmethod)
00340 {
00341    struct sip_request *cur;
00342    int res = -1;
00343 
00344    for (cur = dialog->packets; cur; cur = cur->next) {
00345       if (option_debug > 2)
00346          ast_log(LOG_DEBUG, "--Checking packet with seqno %d against response with seqno %d\n", cur->seqno, seqno);
00347       if (cur->seqno == seqno && ast_test_flag(cur, SIP_PKT_RESPONSE) == resp &&
00348          (ast_test_flag(cur, SIP_PKT_RESPONSE) || method_match(sipmethod, cur->data))) {
00349          /* this is our baby */
00350          if (cur->retransid > -1) {
00351             if (option_debug > 3 && sipdebug)
00352                ast_log(LOG_DEBUG, "Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_method2txt(sipmethod));
00353             ast_sched_del(sched, cur->retransid);
00354          }
00355          cur->retransid = -1;
00356          res = 0;
00357          break;
00358       }
00359    }
00360    if (option_debug)
00361       ast_log(LOG_DEBUG, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", dialog->callid, resp ? "Response" : "Request", seqno, res ? "Not Found" : "Found");
00362    return res;
00363 }
00364 
00365 /*! \brief Execute destruction of SIP dialog structure, release memory */
00366 void __sip_destroy(struct sip_dialog *dialog, int lockowner, int lockdialoglist)
00367 {
00368    struct sip_dialog *cur, *prev = NULL;
00369    struct sip_request *cp;
00370 
00371    if (ast_test_flag(&dialog->flags[0], SIP_INC_COUNT))        /* This dialog has incremented call count */
00372       update_call_counter(dialog, DEC_CALL_LIMIT);          /* Since it was forgotten, decrement call count */
00373 
00374    if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_INC_RINGING))         /* This dialog has incremented ring count */
00375       update_call_counter(dialog, DEC_CALL_RINGING);           /* Since it was forgotten, decrement ring count */
00376 
00377    if (sip_debug_test_pvt(dialog) || option_debug > 2)
00378       ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", dialog->callid, sip_method2txt(dialog->method));
00379 
00380 
00381    /* Remove link from peer to subscription of MWI */
00382    if (dialog->relatedpeer && dialog->relatedpeer->mailbox.mwipvt)
00383       dialog->relatedpeer->mailbox.mwipvt = NULL;
00384 
00385    if (global.dumphistory)
00386       sip_dump_history(dialog);
00387 
00388 
00389    if (dialog->stateid > -1)
00390       ast_extension_state_del(dialog->stateid, NULL);
00391    if (dialog->initid > -1)
00392       ast_sched_del(sched, dialog->initid);
00393    if (dialog->autokillid > -1)
00394       ast_sched_del(sched, dialog->autokillid);
00395 
00396    if (dialog->inviteoptions)
00397       free(dialog->inviteoptions);
00398 
00399    if (dialog->rtp)
00400       ast_rtp_destroy(dialog->rtp);
00401    if (dialog->vrtp)
00402       ast_rtp_destroy(dialog->vrtp);
00403    if (dialog->udptl)
00404       ast_udptl_destroy(dialog->udptl);
00405    if (dialog->refer)
00406       free(dialog->refer);
00407    if (dialog->route) {
00408       free_old_route(dialog->route);
00409       dialog->route = NULL;
00410    }
00411    if (dialog->registry) {
00412       if (dialog->registry->call == dialog)
00413          dialog->registry->call = NULL;
00414       ASTOBJ_UNREF(dialog->registry, sip_registry_destroy);
00415    }
00416 
00417    /* Unlink us from the owner if we have one */
00418    if (dialog->owner) {
00419       if (lockowner)
00420          ast_channel_lock(dialog->owner);
00421       if (option_debug)
00422          ast_log(LOG_DEBUG, "Detaching from %s\n", dialog->owner->name);
00423       dialog->owner->tech_pvt = NULL;
00424       if (lockowner)
00425          ast_channel_unlock(dialog->owner);
00426    }
00427    /* Clear history */
00428    if (dialog->history) {
00429       struct sip_history *hist;
00430       while( (hist = AST_LIST_REMOVE_HEAD(dialog->history, list)) )
00431          free(hist);
00432       free(dialog->history);
00433       dialog->history = NULL;
00434    }
00435 
00436 
00437    /* Unlink us from the dialog list */
00438    if (lockdialoglist)
00439       dialoglist_lock();
00440    for (prev = NULL, cur = dialoglist; cur; prev = cur, cur = cur->next) {
00441       if (cur == dialog) {
00442          UNLINK(cur, dialoglist, prev);
00443          break;
00444       }
00445    }
00446    if (lockdialoglist)
00447       dialoglist_unlock();
00448 
00449    if (!cur) {
00450       ast_log(LOG_WARNING, "Trying to destroy \"%s\", not found in dialog list?!?! \n", dialog->callid);
00451       return;
00452    } 
00453 
00454    /* remove all current packets in this dialog */
00455    while((cp = dialog->packets)) {
00456       /* If one of the records in the packet list is the initreq, then release it */
00457       if (cp == dialog->initreq)
00458          dialog->initreq = NULL;
00459 
00460       dialog->packets = dialog->packets->next;
00461       if (cp->retransid > -1)
00462          ast_sched_del(sched, cp->retransid);
00463       free(cp);
00464    }
00465 
00466    if (dialog->initreq)
00467       siprequest_free(dialog->initreq);
00468 
00469    if (dialog->chanvars) {
00470       ast_variables_destroy(dialog->chanvars);
00471       dialog->chanvars = NULL;
00472    }
00473    ast_mutex_destroy(&dialog->lock);
00474 
00475    ast_string_field_free_pools(dialog);
00476 
00477    /* Finally, release the dialog */
00478    free(dialog);
00479 
00480    sipcounters.dialog_objects--;
00481    if (option_debug > 3)
00482       ast_log(LOG_DEBUG, "--DIALOGS-- Counter %d\n", sipcounters.dialog_objects);
00483 }
00484 
00485 /*! \brief Destroy SIP call structure */
00486 void sip_destroy(struct sip_dialog *dialog)
00487 {
00488    if (option_debug > 2)
00489       ast_log(LOG_DEBUG, "Destroying SIP dialog %s\n", dialog->callid);
00490    __sip_destroy(dialog, TRUE, TRUE);
00491 }
00492 
00493 
00494 /*! \brief Kill a SIP dialog (called by scheduler) 
00495  */
00496 static int __sip_autodestruct(void *data)
00497 {
00498    struct sip_dialog *dialog = data;
00499 
00500    /* If this is a subscription, tell the phone that we got a timeout */
00501    if (dialog->subscribed) {
00502       transmit_state_notify(dialog, AST_EXTENSION_DEACTIVATED, 1, TRUE);   /* Send last notification */
00503       dialog->subscribed = NONE;
00504       append_history(dialog, "Subscribestatus", "timeout");
00505       if (option_debug > 2)
00506          ast_log(LOG_DEBUG, "Re-scheduled destruction of SIP subsription %s\n", dialog->callid ? dialog->callid : "<unknown>");
00507       return 10000;  /* Reschedule this destruction so that we know that it's gone */
00508    }
00509 
00510    if (dialog->subscribed == MWI_NOTIFICATION && dialog->relatedpeer)
00511       device_unref(dialog->relatedpeer);
00512 
00513    /* Reset schedule ID */
00514    dialog->autokillid = -1;
00515 
00516    append_history(dialog, "AutoDestroy", "%s", dialog->callid);
00517    if (dialog->owner) {
00518       ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", dialog->callid, sip_method2txt(dialog->method));
00519       ast_queue_hangup(dialog->owner);
00520    } else if (dialog->refer) {
00521       if (option_debug > 2)
00522          ast_log(LOG_DEBUG, "Finally hanging up channel after transfer: %s\n", dialog->callid);
00523       transmit_request_with_auth(dialog, SIP_BYE, 0, XMIT_RELIABLE, 1);
00524       append_history(dialog, "ReferBYE", "Sending BYE on transferer call leg %s", dialog->callid);
00525       sip_scheddestroy(dialog, DEFAULT_TRANS_TIMEOUT);
00526    } else  {
00527       append_history(dialog, "AutoDestroy", "%s", dialog->callid);
00528       if (option_debug)
00529          ast_log(LOG_DEBUG, "Auto destroying SIP dialog '%s'\n", dialog->callid);
00530       sip_destroy(dialog);
00531    }
00532    return 0;
00533 }
00534 
00535 /*! \brief Schedule destruction of SIP dialog */
00536 GNURK void sip_scheddestroy(struct sip_dialog *p, int ms)
00537 {
00538    if (ms < 0) {
00539       if (p->timer_t1 == 0)
00540          p->timer_t1 = 500;   /* Set timer T1 if not set (RFC 3261) */
00541       ms = p->timer_t1 * 64;
00542    }
00543    if (sip_debug_test_pvt(p))
00544       ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_method2txt(p->method));
00545    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY))
00546       append_history(p, "SchedDestroy", "%d ms", ms);
00547 
00548    if (p->autokillid > -1)
00549       ast_sched_del(sched, p->autokillid);
00550    p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, p);
00551 }
00552 
00553 /*! \brief Cancel destruction of SIP dialog */
00554 GNURK void sip_cancel_destroy(struct sip_dialog *p)
00555 {
00556    if (p->autokillid > -1) {
00557       ast_sched_del(sched, p->autokillid);
00558       append_history(p, "CancelDestroy", "");
00559       p->autokillid = -1;
00560    }
00561 }
00562 
00563 /*! \brief Convert SIP hangup causes to Asterisk hangup causes */
00564 /* \page SIP_isdn2sip Conversion from ISDN to SIP codes
00565    - see function \ref hangup_sip2cause()
00566 */
00567 int hangup_sip2cause(int cause)
00568 {
00569    /* Possible values taken from causes.h */
00570 
00571    switch(cause) {
00572       case 401:   /* Unauthorized */
00573          return AST_CAUSE_CALL_REJECTED;
00574       case 403:   /* Not found */
00575          return AST_CAUSE_CALL_REJECTED;
00576       case 404:   /* Not found */
00577          return AST_CAUSE_UNALLOCATED;
00578       case 405:   /* Method not allowed */
00579          return AST_CAUSE_INTERWORKING;
00580       case 407:   /* Proxy authentication required */
00581          return AST_CAUSE_CALL_REJECTED;
00582       case 408:   /* No reaction */
00583          return AST_CAUSE_NO_USER_RESPONSE;
00584       case 409:   /* Conflict */
00585          return AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
00586       case 410:   /* Gone */
00587          return AST_CAUSE_UNALLOCATED;
00588       case 411:   /* Length required */
00589          return AST_CAUSE_INTERWORKING;
00590       case 413:   /* Request entity too large */
00591          return AST_CAUSE_INTERWORKING;
00592       case 414:   /* Request URI too large */
00593          return AST_CAUSE_INTERWORKING;
00594       case 415:   /* Unsupported media type */
00595          return AST_CAUSE_INTERWORKING;
00596       case 420:   /* Bad extension */
00597          return AST_CAUSE_NO_ROUTE_DESTINATION;
00598       case 480:   /* No answer */
00599          return AST_CAUSE_NO_ANSWER;
00600       case 481:   /* No answer */
00601          return AST_CAUSE_INTERWORKING;
00602       case 482:   /* Loop detected */
00603          return AST_CAUSE_INTERWORKING;
00604       case 483:   /* Too many hops */
00605          return AST_CAUSE_NO_ANSWER;
00606       case 484:   /* Address incomplete */
00607          return AST_CAUSE_INVALID_NUMBER_FORMAT;
00608       case 485:   /* Ambigous */
00609          return AST_CAUSE_UNALLOCATED;
00610       case 486:   /* Busy everywhere */
00611          return AST_CAUSE_BUSY;
00612       case 487:   /* Request terminated */
00613          return AST_CAUSE_INTERWORKING;
00614       case 488:   /* No codecs approved */
00615          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
00616       case 491:   /* Request pending */
00617          return AST_CAUSE_INTERWORKING;
00618       case 493:   /* Undecipherable */
00619          return AST_CAUSE_INTERWORKING;
00620       case 500:   /* Server internal failure */
00621          return AST_CAUSE_FAILURE;
00622       case 501:   /* Call rejected */
00623          return AST_CAUSE_FACILITY_REJECTED;
00624       case 502:   
00625          return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
00626       case 503:   /* Service unavailable */
00627          return AST_CAUSE_CONGESTION;
00628       case 504:   /* Gateway timeout */
00629          return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
00630       case 505:   /* SIP version not supported */
00631          return AST_CAUSE_INTERWORKING;
00632       case 600:   /* Busy everywhere */
00633          return AST_CAUSE_USER_BUSY;
00634       case 603:   /* Decline */
00635          return AST_CAUSE_CALL_REJECTED;
00636       case 604:   /* Does not exist anywhere */
00637          return AST_CAUSE_UNALLOCATED;
00638       case 606:   /* Not acceptable */
00639          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
00640       default:
00641          return AST_CAUSE_NORMAL;
00642    }
00643    /* Never reached */
00644    return 0;
00645 }
00646 
00647 /*! \brief Convert Asterisk hangup causes to SIP codes 
00648 \page SIP_isdn2sip Conversion from ISDN to SIP codes
00649 \verbatim
00650  Possible values from causes.h
00651         AST_CAUSE_NOTDEFINED    AST_CAUSE_NORMAL        AST_CAUSE_BUSY
00652         AST_CAUSE_FAILURE       AST_CAUSE_CONGESTION    AST_CAUSE_UNALLOCATED
00653 
00654    In addition to these, a lot of PRI codes is defined in causes.h 
00655    ...should we take care of them too ?
00656    
00657    Quote RFC 3398
00658 
00659    ISUP Cause value                        SIP response
00660    ----------------                        ------------
00661    1  unallocated number                   404 Not Found
00662    2  no route to network                  404 Not found
00663    3  no route to destination              404 Not found
00664    16 normal call clearing                 --- (*)
00665    17 user busy                            486 Busy here
00666    18 no user responding                   408 Request Timeout
00667    19 no answer from the user              480 Temporarily unavailable
00668    20 subscriber absent                    480 Temporarily unavailable
00669    21 call rejected                        403 Forbidden (+)
00670    22 number changed (w/o diagnostic)      410 Gone
00671    22 number changed (w/ diagnostic)       301 Moved Permanently
00672    23 redirection to new destination       410 Gone
00673    26 non-selected user clearing           404 Not Found (=)
00674    27 destination out of order             502 Bad Gateway
00675    28 address incomplete                   484 Address incomplete
00676    29 facility rejected                    501 Not implemented
00677    31 normal unspecified                   480 Temporarily unavailable
00678 \endverbatim
00679 Also see \ref SIP_sip2isdn
00680 */
00681 const char *hangup_cause2sip(int cause)
00682 {
00683    switch (cause) {
00684       case AST_CAUSE_UNALLOCATED:      /* 1 */
00685       case AST_CAUSE_NO_ROUTE_DESTINATION:   /* 3 IAX2: Can't find extension in context */
00686       case AST_CAUSE_NO_ROUTE_TRANSIT_NET:   /* 2 */
00687          return "404 Not Found";
00688       case AST_CAUSE_CONGESTION:    /* 34 */
00689       case AST_CAUSE_SWITCH_CONGESTION:   /* 42 */
00690          return "503 Service Unavailable";
00691       case AST_CAUSE_NO_USER_RESPONSE: /* 18 */
00692          return "408 Request Timeout";
00693       case AST_CAUSE_NO_ANSWER:     /* 19 */
00694          return "480 Temporarily unavailable";
00695       case AST_CAUSE_CALL_REJECTED:    /* 21 */
00696          return "403 Forbidden";
00697       case AST_CAUSE_NUMBER_CHANGED:      /* 22 */
00698          return "410 Gone";
00699       case AST_CAUSE_NORMAL_UNSPECIFIED:  /* 31 */
00700          return "480 Temporarily unavailable";
00701       case AST_CAUSE_INVALID_NUMBER_FORMAT:
00702          return "484 Address incomplete";
00703       case AST_CAUSE_USER_BUSY:
00704          return "486 Busy here";
00705       case AST_CAUSE_FAILURE:
00706          return "500 Server internal failure";
00707       case AST_CAUSE_FACILITY_REJECTED:   /* 29 */
00708          return "501 Not Implemented";
00709       case AST_CAUSE_CHAN_NOT_IMPLEMENTED:
00710          return "503 Service Unavailable";
00711       /* Used in chan_iax2 */
00712       case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
00713          return "502 Bad Gateway";
00714       case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */
00715          return "488 Not Acceptable Here";
00716          
00717       case AST_CAUSE_NOTDEFINED:
00718       default:
00719          if (option_debug)
00720             ast_log(LOG_DEBUG, "AST hangup cause %d (no match found in SIP)\n", cause);
00721          return NULL;
00722    }
00723 
00724    /* Never reached */
00725    return 0;
00726 }
00727 
00728 /*! \brief Make our SIP dialog tag */
00729 GNURK void make_our_tag(char *tagbuf, size_t len)
00730 {
00731    if (sipdebug)
00732       snprintf(tagbuf, len, "asterisk%08lx", ast_random());
00733    else
00734       snprintf(tagbuf, len, "%08lx", ast_random());
00735 }
00736 
00737 /*! \brief Activate media streams - Audio, Video and T.38 UDPTL if needed */
00738 static int dialog_activate_media(struct sip_dialog *dialog, struct sip_network *sipnet)
00739 {
00740    /* Audio channel is always activated */
00741    dialog->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, sipnet->bindaddr.sin_addr);
00742 
00743    /* If the global videosupport flag is on, we always create a RTP interface for video */
00744    if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT)) {
00745       if (option_debug > 3)
00746          ast_log(LOG_DEBUG, "Creating video interface for %s\n", dialog->callid);
00747       dialog->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, sipnet->bindaddr.sin_addr);
00748    }
00749 
00750    /* T.38 support UDPTL stream */
00751    if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) {
00752       if (option_debug > 3)
00753          ast_log(LOG_DEBUG, "Creating UDPTL interface for %s\n", dialog->callid);
00754       dialog->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, sipnet->bindaddr.sin_addr);
00755       if (!dialog->udptl)
00756          ast_log(LOG_WARNING, "Unable to create T.38 UDPTL interface for session: %s\n", dialog->callid);
00757    }
00758 
00759    /* Do we have channels? */
00760    if (!dialog->rtp || (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !dialog->vrtp)) {
00761       ast_log(LOG_WARNING, "Unable to create RTP audio %s session: %s\n",
00762       ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video" : "", strerror(errno));
00763       return FALSE;
00764    }
00765 
00766    /* Fine tune audio RTP settings */
00767    ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) != SIP_DTMF_INFO);
00768    ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
00769    ast_rtp_settos(dialog->rtp, global.tos_audio);
00770    ast_rtp_set_rtptimeout(dialog->rtp, global.rtptimer.rtptimeout);
00771    ast_rtp_set_rtpholdtimeout(dialog->rtp, global.rtptimer.rtpholdtimeout);
00772    ast_rtp_set_rtpkeepalive(dialog->rtp, global.rtptimer.rtpkeepalive);
00773 
00774    /* If we have video, fine tune RTP settings */
00775    if (dialog->vrtp) {
00776       ast_rtp_settos(dialog->vrtp, global.tos_video);
00777       ast_rtp_setdtmf(dialog->vrtp, 0);
00778       ast_rtp_setdtmfcompensate(dialog->vrtp, 0);
00779       ast_rtp_set_rtptimeout(dialog->vrtp, global.rtptimer.rtptimeout);
00780       ast_rtp_set_rtpholdtimeout(dialog->vrtp, global.rtptimer.rtpholdtimeout);
00781       ast_rtp_set_rtpkeepalive(dialog->vrtp, global.rtptimer.rtpkeepalive);
00782    }
00783 
00784    /* Finally, T.38 settings */
00785    if (dialog->udptl) {
00786       ast_udptl_settos(dialog->udptl, global.tos_audio);
00787       dialog->t38.capability = global.t38_capability;
00788       if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_REDUNDANCY)
00789          dialog->t38.capability |= T38FAX_UDP_EC_REDUNDANCY;
00790       else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_FEC)
00791          dialog->t38.capability |= T38FAX_UDP_EC_FEC;
00792       else if (ast_udptl_get_error_correction_scheme(dialog->udptl) == UDPTL_ERROR_CORRECTION_NONE)
00793          dialog->t38.capability |= T38FAX_UDP_EC_NONE;
00794       dialog->t38.capability |= T38FAX_RATE_MANAGEMENT_TRANSFERED_TCF;
00795       dialog->t38.jointcapability = dialog->t38.capability;
00796    }
00797 
00798    dialog->maxcallbitrate = global.default_maxcallbitrate;
00799    return TRUE;
00800 }
00801 
00802 /*! \brief Allocate SIP dialog structure and set defaults */
00803 struct sip_dialog *sip_alloc(ast_string_field callid, struct sockaddr_in *sin,
00804              int useglobal_nat, const int intended_method)
00805 {
00806    struct sip_dialog *dialog;
00807 
00808    if (!(dialog = ast_calloc(1, sizeof(*dialog))))
00809       return NULL;
00810 
00811    if (ast_string_field_init(dialog, 512)) {
00812       free(dialog);
00813       return NULL;
00814    }
00815    sipcounters.dialog_objects++;
00816    if (option_debug > 3)
00817       ast_log(LOG_DEBUG, "--DIALOGS-- Counter %d\n", sipcounters.dialog_objects);
00818 
00819       ast_mutex_init(&dialog->lock);
00820 
00821    dialog->method = intended_method;
00822    dialog->initid = -1;
00823    dialog->autokillid = -1;
00824    dialog->subscribed = NONE;
00825    dialog->stateid = -1;
00826    dialog->prefs = global.default_prefs;     /* Set default codecs for this call */
00827 
00828    if (intended_method != SIP_OPTIONS) /* Peerpoke has it's own system */
00829       dialog->timer_t1 = global.t1default;   /* 500 ms Default SIP retransmission timer T1 (RFC 3261) */
00830 
00831    if (sin) {
00832       dialog->sa = *sin;
00833       if (sip_ouraddrfor(&dialog->sa.sin_addr, &dialog->ourip))
00834          dialog->ourip = sipnet.__ourip;
00835    } else
00836       dialog->ourip = sipnet.__ourip;
00837 
00838    /* Copy global flags to this PVT at setup. */
00839    ast_copy_flags(&dialog->flags[0], &global.flags[0], SIP_FLAGS_TO_COPY);
00840    ast_copy_flags(&dialog->flags[1], &global.flags[1], SIP_PAGE2_FLAGS_TO_COPY);
00841 
00842    ast_set2_flag(&dialog->flags[0], !global.recordhistory, SIP_NO_HISTORY);
00843 
00844    make_our_tag(dialog->tag, sizeof(dialog->tag));
00845    dialog->ocseq = INITIAL_CSEQ;
00846 
00847    /* Activate media streams */
00848    if (sip_method_needrtp(intended_method)) {
00849       if (!dialog_activate_media(dialog, &sipnet)) {
00850          ast_mutex_destroy(&dialog->lock);
00851          if (dialog->chanvars) {
00852             ast_variables_destroy(dialog->chanvars);
00853             dialog->chanvars = NULL;
00854          }
00855          free(dialog);
00856          return NULL;
00857       }
00858    }
00859 
00860    if (useglobal_nat && sin) {
00861       /* Setup NAT structure according to global settings if we have an address */
00862       ast_copy_flags(&dialog->flags[0], &global.flags[0], SIP_NAT);
00863       dialog->recv = *sin;
00864       do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
00865    }
00866 
00867    if (dialog->method != SIP_REGISTER)
00868       ast_string_field_set(dialog, fromdomain, global.default_fromdomain);
00869 
00870    build_via(dialog, TRUE);
00871    if (!callid)               /* Make sure we have a unique call ID */
00872       build_callid_pvt(dialog);
00873    else
00874       ast_string_field_set(dialog, callid, callid);
00875 
00876    dialogstatechange(dialog, DIALOG_STATE_TRYING); /* Set dialog state */
00877 
00878                      /* Assign default music on hold class */
00879    ast_string_field_set(dialog, mohinterpret, global.default_mohinterpret);
00880    ast_string_field_set(dialog, mohsuggest, global.default_mohsuggest);
00881    
00882    dialog->capability = global.capability;      /* Set default codec settings */
00883 
00884    if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
00885        (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
00886       dialog->noncodeccapability |= AST_RTP_DTMF;
00887 
00888    ast_string_field_set(dialog, context, global.default_context);
00889    dialog->allowtransfer = global.allowtransfer;   /* Default transfer mode */
00890 
00891    /* Add to active dialog list */
00892    dialoglist_lock();
00893    dialog->next = dialoglist;
00894    dialoglist = dialog;
00895    dialoglist_unlock();
00896    if (option_debug)
00897       ast_log(LOG_DEBUG, "Allocating new SIP dialog for %s - %s (%s)\n", callid ? callid : "(No Call-ID)", sip_method2txt(intended_method), dialog->rtp ? "With RTP" : "No RTP");
00898    return dialog;
00899 }
00900 
00901 /*! \brief Initialize temporary PVT */
00902 static int temp_pvt_init(void *data)
00903 {
00904    struct sip_dialog *p = data;
00905 
00906    ast_set_flag(&p->flags[0], SIP_NO_HISTORY);
00907    return ast_string_field_init(p, 512);
00908 }
00909 
00910 /*! \brief Cleanup temporary PVT */
00911 static void temp_pvt_cleanup(void *data)
00912 {
00913    struct sip_dialog *p = data;
00914 
00915    ast_string_field_free_pools(p);
00916 
00917    free(data);
00918 }
00919 
00920 /*! \brief Transmit response, no retransmits, using a temporary pvt structure */
00921 static int transmit_response_using_temp(ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, struct sip_request *req, const char *msg)
00922 {
00923    struct sip_dialog *p = NULL;
00924 
00925    if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) {
00926       ast_log(LOG_NOTICE, "Failed to get temporary pvt\n");
00927       return -1;
00928    }
00929 
00930    /* if the structure was just allocated, initialize it */
00931    if (!ast_test_flag(&p->flags[0], SIP_NO_HISTORY)) {
00932       ast_set_flag(&p->flags[0], SIP_NO_HISTORY);
00933       if (ast_string_field_init(p, 512))
00934          return -1;
00935    }
00936 
00937    /* Initialize the bare minimum */
00938    p->method = intended_method;
00939 
00940    if (sin) {
00941       p->sa = *sin;
00942       if (sip_ouraddrfor(&p->sa.sin_addr, &p->ourip))
00943          p->ourip = sipnet.__ourip;
00944    } else
00945       p->ourip = sipnet.__ourip;
00946 
00947    make_our_tag(p->tag, sizeof(p->tag));
00948    p->ocseq = INITIAL_CSEQ;
00949 
00950    if (useglobal_nat && sin) {
00951       ast_copy_flags(&p->flags[0], &global.flags[0], SIP_NAT);
00952       p->recv = *sin;
00953       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
00954    }
00955 
00956    ast_string_field_set(p, fromdomain, global.default_fromdomain);
00957    build_via(p, TRUE);
00958    ast_string_field_set(p, callid, callid);
00959 
00960    /* Use this temporary pvt structure to send the message */
00961    __transmit_response(p, msg, req, XMIT_UNRELIABLE);
00962 
00963    /* Free the string fields, but not the pool space */
00964    ast_string_field_free_all(p);
00965 
00966    return 0;
00967 }
00968 
00969 /*! \brief Connect incoming SIP message to current dialog or create new dialog structure
00970    \note Called by handle_request, sipsock_read 
00971 
00972    \page sip3_dialog_match chan_sip3:: Dialog matching and scenarios
00973    \par Dialog matching
00974 
00975    SIP can be forked, so we need to separate dialogs from each other in a 
00976    good way.
00977 
00978    \par 1. Calling out, getting the same call back
00979    An OUTBOUND INVITE can be sent to a SiP proxy and come back twice. We
00980    separate the two different calls by branch tag in the topmost via header.
00981       Asterisk1 ----> INVITE ---> PROXY
00982                 PROXY --> INVITE branch 1 ---> Asterisk1
00983                 PROXY --> INVITE branch 2 ---> Asterisk1
00984                 PROXY --> INVITE branch 3 ---> UA3 (not Asterisk)
00985    We have to treat the two calls as separate calls. But how do we handle
00986    this situation, where we actually can take the media internally somehow?
00987    If the proxy does not add Record-Route, we can just tear down the SIP
00988    signalling and shortcut the call internally. If the proxy Record-Route the
00989    call, we need to keep the SIP signalling or just fake a tear down with
00990    a fake BYE and handle it internally, which wouuld be bad if the proxy
00991    logs are important.
00992    
00993    \par 2. Getting the same INCOMING call multiple times
00994       UAC ----> INVITE ---> PROXY
00995                 PROXY --> INVITE branch 1 ---> Asterisk1
00996                 PROXY --> INVITE branch 2 ---> Asterisk1
00997                 PROXY --> INVITE branch 3 ---> UA3 (not Asterisk)
00998 
00999    \par 3. Sending INVITE, getting many replies
01000             
01001    An OUTBOUND INVITE may be forked to two or more separate UA's. If there's
01002    a stateless SIP proxy between us and the UA's, we get multiple replies.
01003    In a worst case scenario, we get multiple 200 OK at the same time.
01004    Since we don't know about the fork, we won't send CANCEL.
01005       INVITE -->
01006          <--- 100 trying from UA1
01007          <--- 100 trying from UA2
01008          <--- 200 OK from UA1
01009          <--- 200 OK from UA2
01010    in this case
01011 
01012    If it's a secondary 200 OK to a current
01013    INVITE, we're in interesting waters.
01014    In this case, we have to copy the current dialog, create
01015    a new and send ACK, then immediately BYE since there's
01016    no call to bridge it with.
01017    of course, there's a usability issue here. how do you
01018    tell the person that answers the forked call that someone
01019    else answered already? Too late to cancel the call...
01020 
01021    Scenarios:
01022    INVITE
01023       100 from first device
01024       100 from second device
01025       183 from first device
01026       183 from second device
01027          - provisional responses, don't create new dialog, 
01028            just ignore the secondary answers and be happy
01029    --- 2. Double 200 OKs
01030       200 OK from first device
01031       200 OK from second
01032          - Creates new branch
01033    --- 3. Error and 200 OK from different devices
01034       200 OK from first device response
01035       603 Declined from secondary device response
01036          - Sorry, just ACK the 603 and close
01037 
01038       603 declined from first response
01039       200 OK from second response
01040          - In this case, the call failed. We can't wait
01041             for the possibility that we get a 200 OK
01042             from a device we don't know about.  
01043          - But we might be clever, if we get two 100 trying
01044            then we know that something's going on.
01045          - Without trickery, the second 200 OK will have to
01046            get an ACK, then a BYE
01047 
01048    \par 4. How do we handle this in Asterisk chan_sip3 ???
01049    \todo Add text here!
01050 
01051    
01052 */
01053 struct sip_dialog *match_or_create_dialog(struct sip_request *req, struct sockaddr_in *sin, const int intended_method)
01054 {
01055    struct sip_dialog *cur = NULL;
01056    char *tag = "";   /* note, tag is never NULL */
01057    char totag[128];
01058    char fromtag[128];
01059    char branch[128];
01060 
01061    if (ast_strlen_zero(req->callid))
01062       req->callid = get_header(req, "Call-ID");
01063    if (ast_strlen_zero(req->from))
01064       req->from = get_header(req, "From");
01065    if (ast_strlen_zero(req->to))
01066       req->to = get_header(req, "To");
01067    if (ast_strlen_zero(req->cseqheader))
01068       req->cseqheader = get_header(req, "Cseq");
01069 
01070    /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */
01071    /* get_header always returns non-NULL so we must use ast_strlen_zero() */
01072    if (ast_strlen_zero(req->callid) || ast_strlen_zero(req->to) ||
01073          ast_strlen_zero(req->from) || ast_strlen_zero(req->cseqheader))
01074       return NULL;   /* Invalid packet */
01075 
01076    /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy
01077       we need more to identify a branch - so we have to check branch, from
01078       and to tags to identify a call leg.
01079       */
01080    if (gettag(req->to, totag, sizeof(totag)))
01081       ast_set_flag(req, SIP_PKT_WITH_TOTAG); /* Used in handle_request/response */
01082    gettag(req->from, fromtag, sizeof(fromtag));
01083 
01084    tag = (req->method == SIP_RESPONSE) ? totag : fromtag;
01085 
01086    /* All messages must always have From: tag */
01087    if (ast_strlen_zero(fromtag)) {
01088       if (option_debug > 4 ) 
01089          ast_log(LOG_DEBUG, "%s request has no from tag, dropping callid: %s from: %s\n", sip_methods[req->method].text, req->callid, req->from );
01090       return NULL;
01091    }
01092    /* reject requests that must always have a To: tag */
01093    if (ast_strlen_zero(totag) && (req->method == SIP_ACK || req->method == SIP_BYE || req->method == SIP_INFO )) {
01094       if (option_debug > 4) 
01095          ast_log(LOG_DEBUG, "%s must have a to tag. dropping callid: %s from: %s\n", sip_methods[req->method].text, req->callid, req->from );
01096       return NULL;
01097    }
01098  
01099    dialoglist_lock();
01100 
01101    if (option_debug > 4 )
01102       ast_log(LOG_DEBUG, "= Looking for  Call ID: %s (Checking %s) --From tag %s --To-tag %s  \n", req->callid, req->method==SIP_RESPONSE ? "To" : "From", fromtag, totag);
01103 
01104    find_via_branch(req, branch, sizeof(branch));
01105    for (cur = dialoglist; cur; cur = cur->next) {
01106       /* we do not want packets with bad syntax to be connected to a PVT */
01107       int found = FALSE;
01108       if (req->method == SIP_REGISTER)
01109          found = (!strcmp(cur->callid, req->callid));
01110       else 
01111          found = (!strcmp(cur->callid, req->callid) && 
01112          (!tag || ast_strlen_zero(cur->theirtag) || !strcmp(cur->theirtag, tag))) ;
01113 
01114       if (option_debug > 4)
01115          ast_log(LOG_DEBUG, "= %s Their Call ID: %s Their Tag %s Our tag: %s\n", found ? "Found" : "No match", cur->callid, cur->theirtag, cur->tag);
01116 
01117       /* If we get a new request within an existing to-tag - check the to tag as well */
01118       if (found  && req->method != SIP_RESPONSE) { /* SIP Request */
01119          if (cur->tag[0] == '\0' && totag[0]) {
01120             /* We have no to tag, but they have. Wrong dialog */
01121             found = FALSE;
01122          } else if (totag[0]) {        /* Both have tags, compare them */
01123             if (strcmp(totag, cur->tag)) {
01124                found = FALSE;    /* This is not our dialog */
01125             }
01126          }
01127          if (!found && option_debug > 4)
01128             ast_log(LOG_DEBUG, "= Being pedantic: This is not our match on request: Call ID: %s Ourtag <null> Totag %s Method %s\n", cur->callid, totag, sip_method2txt(req->method));
01129       }
01130       
01131       /* We need to check the branch too, to make sure this is the proper reply */
01132       /* If it is an INVITE from us coming back with a new branch, we need to
01133          do some masquerading trickery with the audio.
01134          We might also get several INVITEs with different branches
01135          and have to treat them as several calls 
01136        */
01137       if (found) {
01138          if (!strcmp(cur->ourbranch, branch)) {
01139             /* This is our own request coming back to us strangely enough */
01140             /* Propably through DNS, but not a proxy */
01141             /* Bad dialplan design... ; -) */
01142             /* Any way we can handle this??? */
01143          }
01144          /* If we have a remote branch already, and get a new branch with the
01145             same call ID, then something is happening.
01146             For responses - we might have a forking proxy and get responses
01147             from several UAs on one request.
01148             For requests, we might be getting a statelessly forked call to us. 
01149          */
01150          if (!ast_strlen_zero(cur->remotebranch) && strcmp(cur->remotebranch, branch)) {
01151             /* XXX What do we do here ? */
01152             
01153          }
01154       }
01155 
01156 
01157       if (found) {
01158          /* Found the dialog */
01159          dialog_lock(cur, TRUE); /* Lock the dialog */
01160          dialoglist_unlock(); /* Unlock the list */
01161          return cur;
01162       }
01163    }
01164    dialoglist_unlock();
01165    if (sip_methods[intended_method].creates_dialog != CAN_CREATE_DIALOG) {
01166       if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK)
01167          transmit_response_using_temp(req->callid, sin, TRUE, intended_method, req, "481 Call leg/transaction does not exist");
01168       else
01169          logdebug(2, "Got response or ACK to non-existing transaction. No action taken. Call-ID: %s\n", req->callid);
01170       return cur;
01171    }
01172    switch (intended_method) {
01173    case SIP_REFER:
01174       /* We do not support out-of-dialog REFERs yet */
01175       transmit_response_using_temp(req->callid, sin, TRUE, intended_method, req, "603 Declined (no dialog)");
01176       break;
01177    case SIP_NOTIFY:
01178       /* We do not support out-of-dialog NOTIFY either,
01179         like voicemail notification, so cancel that early */
01180       transmit_response_using_temp(req->callid, sin, TRUE, intended_method, req, "489 Bad event");
01181       break;
01182    default:
01183       /* ready to create a new dialog. */
01184       if ((cur = sip_alloc(req->callid, sin, TRUE, intended_method))) {
01185          /* This method creates dialog */
01186          /* Ok,   we've created a dialog, let's go and process it */
01187          dialog_lock(cur, TRUE);
01188       }
01189       break;
01190    }
01191 
01192    return cur;
01193 }
01194 
01195 /*! \brief Find via branch parameter */
01196 GNURK void find_via_branch(struct sip_request *req, char *viabuf, size_t vialen)
01197 {
01198    char *dupvia;
01199    char *viabranch;
01200    char *sep;
01201 
01202    if (ast_strlen_zero(req->via))
01203       return;
01204    dupvia = ast_strdupa(req->via);
01205    if (!(viabranch = strcasestr(dupvia, ";branch=")))
01206       return;
01207    viabranch += 8;
01208    if ((sep = strchr(viabranch, ';')))
01209       *sep = '\0';
01210    if (ast_test_flag(req, SIP_PKT_DEBUG) && option_debug > 3)
01211       ast_log(LOG_DEBUG, "* Found via branch %s\n", viabranch);
01212    strncpy(viabuf, viabranch, vialen);
01213 }
01214 
01215 
01216 /*! \brief Make branch tag for via header if it does not exist yet */
01217 static char *ourdialogbranch(struct sip_dialog *dialog, int forcenewbranch)
01218 {
01219    char branch[20];
01220    int seed = 0;
01221 
01222    if (forcenewbranch || ast_strlen_zero(dialog->ourbranch)) {
01223       if (forcenewbranch)
01224          seed ^= ast_random();
01225       else
01226          seed = ast_random();
01227       snprintf(branch, sizeof(branch), "z9hG4bk%08x", seed);
01228       ast_string_field_set(dialog, ourbranch, branch);
01229    }
01230 
01231    return((char *) dialog->ourbranch);
01232    
01233 }
01234 
01235 /*! \brief Build a Via header for a request */
01236 GNURK void build_via(struct sip_dialog *dialog, int forcenewbranch)
01237 {
01238    /* Work around buggy UNIDEN UIP200 firmware */
01239    const char *rport = ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : "";
01240 
01241    /* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
01242    ast_string_field_build(dialog, via, "SIP/2.0/UDP %s:%d;branch=%s%s",
01243          ast_inet_ntoa(dialog->ourip), sipnet_ourport(&sipnet), 
01244          ourdialogbranch(dialog, forcenewbranch), rport);
01245 }
01246 

Asterisk is a trademark for Digium, inc.. | Edvina.net | Asterisk.org | This documentation was generated with Doxygen