/*
* Asterisk -- An open source telephony toolkit.
*
* Copyright (C) 1999 - 2006, Digium, Inc.
*
* Mark Spencer <markster@digium.com>
*
* See http://www.asterisk.org for more information about
* the Asterisk project. Please do not directly contact
* any of the maintainers of this project for assistance;
* the project provides a web site, mailing lists and IRC
* channels for your use.
*
* This program is free software, distributed under the terms of
* the GNU General Public License Version 2. See the LICENSE file
* at the top of the source tree.
*/
/*!
* \file
* \brief Implementation of Session Initiation Protocol
*
* \author Mark Spencer <markster@digium.com>
*
* See Also:
* \arg \ref AstCREDITS
*
* Implementation of RFC 3261 - without S/MIME, and experimental TCP and TLS support
* Configuration file \link Config_sip sip.conf \endlink
*
* ********** IMPORTANT *
* \note TCP/TLS support is EXPERIMENTAL and WILL CHANGE. This applies to configuration
* settings, dialplan commands and dialplans apps/functions
*
*
* TODO:s
* \todo Better support of forking
* \todo VIA branch tag transaction checking
* \todo Transaction support
* \todo We need to test TCP sessions with SIP proxies and in regards
* to the SIP outbound specs.
* \todo Fix TCP/TLS handling in dialplan, SRV records, transfers and much more
* \todo Save TCP/TLS sessions in registry
* \todo Add TCP/TLS information to function SIPPEER and SIPCHANINFO
*
* \ingroup channel_drivers
*
* \par Overview of the handling of SIP sessions
* The SIP channel handles several types of SIP sessions, or dialogs,
* not all of them being "telephone calls".
* - Incoming calls that will be sent to the PBX core
* - Outgoing calls, generated by the PBX
* - SIP subscriptions and notifications of states and voicemail messages
* - SIP registrations, both inbound and outbound
* - SIP peer management (peerpoke, OPTIONS)
* - SIP text messages
*
* In the SIP channel, there's a list of active SIP dialogs, which includes
* all of these when they are active. "sip show channels" in the CLI will
* show most of these, excluding subscriptions which are shown by
* "sip show subscriptions"
*
* \par incoming packets
* Incoming packets are received in the monitoring thread, then handled by
* sipsock_read(). This function parses the packet and matches an existing
* dialog or starts a new SIP dialog.
*
* sipsock_read sends the packet to handle_incoming(), that parses a bit more.
* If it is a response to an outbound request, the packet is sent to handle_response().
* If it is a request, handle_incoming() sends it to one of a list of functions
* depending on the request type - INVITE, OPTIONS, REFER, BYE, CANCEL etc
* sipsock_read locks the ast_channel if it exists (an active call) and
* unlocks it after we have processed the SIP message.
*
* A new INVITE is sent to handle_request_invite(), that will end up
* starting a new channel in the PBX, the new channel after that executing
* in a separate channel thread. This is an incoming "call".
* When the call is answered, either by a bridged channel or the PBX itself
* the sip_answer() function is called.
*
* The actual media - Video or Audio - is mostly handled by the RTP subsystem
* in rtp.c
*
* \par Outbound calls
* Outbound calls are set up by the PBX through the sip_request_call()
* function. After that, they are activated by sip_call().
*
* \par Hanging up
* The PBX issues a hangup on both incoming and outgoing calls through
* the sip_hangup() function
*/
/*** MODULEINFO
<depend>chan_local</depend>
***/
/*! \page sip_session_timers SIP Session Timers in Asterisk Chan_sip
The SIP Session-Timers is an extension of the SIP protocol that allows end-points and proxies to
refresh a session periodically. The sessions are kept alive by sending a RE-INVITE or UPDATE
request at a negotiated interval. If a session refresh fails then all the entities that support Session-
Timers clear their internal session state. In addition, UAs generate a BYE request in order to clear
the state in the proxies and the remote UA (this is done for the benefit of SIP entities in the path
that do not support Session-Timers).
The Session-Timers can be configured on a system-wide, per-user, or per-peer basis. The peruser/
per-peer settings override the global settings. The following new parameters have been
added to the sip.conf file.
session-timers=["accept", "originate", "refuse"]
session-expires=[integer]
session-minse=[integer]
session-refresher=["uas", "uac"]
The session-timers parameter in sip.conf defines the mode of operation of SIP session-timers feature in
Asterisk. The Asterisk can be configured in one of the following three modes:
1. Accept :: In the "accept" mode, the Asterisk server honors session-timers requests
made by remote end-points. A remote end-point can request Asterisk to engage
session-timers by either sending it an INVITE request with a "Supported: timer"
header in it or by responding to Asterisk's INVITE with a 200 OK that contains
Session-Expires: header in it. In this mode, the Asterisk server does not
request session-timers from remote end-points. This is the default mode.
2. Originate :: In the "originate" mode, the Asterisk server requests the remote
end-points to activate session-timers in addition to honoring such requests
made by the remote end-pints. In order to get as much protection as possible
against hanging SIP channels due to network or end-point failures, Asterisk
resends periodic re-INVITEs even if a remote end-point does not support
the session-timers feature.
3. Refuse :: In the "refuse" mode, Asterisk acts as if it does not support session-
timers for inbound or outbound requests. If a remote end-point requests
session-timers in a dialog, then Asterisk ignores that request unless it's
noted as a requirement (Require: header), in which case the INVITE is
rejected with a 420 Bad Extension response.
*/
#include "asterisk.h"
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include <ctype.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/signal.h>
#include <regex.h>
#include <time.h>
#include "asterisk/network.h"
#include "asterisk/paths.h" /* need ast_config_AST_SYSTEM_NAME */
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/pbx.h"
#include "asterisk/sched.h"
#include "asterisk/io.h"
#include "asterisk/rtp.h"
#include "asterisk/udptl.h"
#include "asterisk/acl.h"
#include "asterisk/manager.h"
#include "asterisk/callerid.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/musiconhold.h"
#include "asterisk/dsp.h"
#include "asterisk/features.h"
#include "asterisk/srv.h"
#include "asterisk/astdb.h"
#include "asterisk/causes.h"
#include "asterisk/utils.h"
#include "asterisk/file.h"
#include "asterisk/astobj.h"
/*
Uncomment the define below, if you are having refcount related memory leaks.
With this uncommented, this module will generate a file, /tmp/refs, which contains
a history of the ao2_ref() calls. To be useful, all calls to ao2_* functions should
be modified to ao2_t_* calls, and include a tag describing what is happening with
enough detail, to make pairing up a reference count increment with its corresponding decrement.
The refcounter program in utils/ can be invaluable in highlighting objects that are not
balanced, along with the complete history for that object.
In normal operation, the macros defined will throw away the tags, so they do not
affect the speed of the program at all. They can be considered to be documentation.
*/
/* #define REF_DEBUG 1 */
#include "asterisk/astobj2.h"
#include "asterisk/dnsmgr.h"
#include "asterisk/devicestate.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/monitor.h"
#include "asterisk/netsock.h"
#include "asterisk/localtime.h"
#include "asterisk/abstract_jb.h"
#include "asterisk/threadstorage.h"
#include "asterisk/translate.h"
#include "asterisk/ast_version.h"
#include "asterisk/event.h"
#include "asterisk/tcptls.h"
#ifndef FALSE
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE 1
#endif
#define SIPBUFSIZE 512
/* Arguments for find_peer */
#define FINDUSERS (1 << 0)
#define FINDPEERS (1 << 1)
#define FINDALLDEVICES (FINDUSERS | FINDPEERS)
#define XMIT_ERROR -2
#define SIP_RESERVED ";/?:@&=+$,# "
/* #define VOCAL_DATA_HACK */
#define DEFAULT_DEFAULT_EXPIRY 120
#define DEFAULT_MIN_EXPIRY 60
#define DEFAULT_MAX_EXPIRY 3600
#define DEFAULT_REGISTRATION_TIMEOUT 20
#define DEFAULT_MAX_FORWARDS "70"
/* guard limit must be larger than guard secs */
/* guard min must be < 1000, and should be >= 250 */
#define EXPIRY_GUARD_SECS 15 /*!< How long before expiry do we reregister */
#define EXPIRY_GUARD_LIMIT 30 /*!< Below here, we use EXPIRY_GUARD_PCT instead of
EXPIRY_GUARD_SECS */
#define EXPIRY_GUARD_MIN 500 /*!< This is the minimum guard time applied. If
GUARD_PCT turns out to be lower than this, it
will use this time instead.
This is in milliseconds. */
#define EXPIRY_GUARD_PCT 0.20 /*!< Percentage of expires timeout to use when
below EXPIRY_GUARD_LIMIT */
#define DEFAULT_EXPIRY 900 /*!< Expire slowly */
static int min_expiry = DEFAULT_MIN_EXPIRY; /*!< Minimum accepted registration time */
static int max_expiry = DEFAULT_MAX_EXPIRY; /*!< Maximum accepted registration time */
static int default_expiry = DEFAULT_DEFAULT_EXPIRY;
#define CALLERID_UNKNOWN "Anonymous"
#define FROMDOMAIN_INVALID "anonymous.invalid"
#define DEFAULT_MAXMS 2000 /*!< Qualification: Must be faster than 2 seconds by default */
#define DEFAULT_QUALIFYFREQ 60 * 1000 /*!< Qualification: How often to check for the host to be up */
#define DEFAULT_FREQ_NOTOK 10 * 1000 /*!< Qualification: How often to check, if the host is down... */
#define DEFAULT_RETRANS 1000 /*!< How frequently to retransmit Default: 2 * 500 ms in RFC 3261 */
#define MAX_RETRANS 6 /*!< Try only 6 times for retransmissions, a total of 7 transmissions */
#define SIP_TIMER_T1 500 /* SIP timer T1 (according to RFC 3261) */
#define SIP_TRANS_TIMEOUT 64 * SIP_TIMER_T1/*!< SIP request timeout (rfc 3261) 64*T1
\todo Use known T1 for timeout (peerpoke)
*/
#define DEFAULT_TRANS_TIMEOUT -1 /* Use default SIP transaction timeout */
#define PROVIS_KEEPALIVE_TIMEOUT 60000 /*!< How long to wait before retransmitting a provisional response (rfc 3261 13.3.1.1) */
#define MAX_AUTHTRIES 3 /*!< Try authentication three times, then fail */
#define SIP_MAX_HEADERS 64 /*!< Max amount of SIP headers to read */
#define SIP_MAX_LINES 64 /*!< Max amount of lines in SIP attachment (like SDP) */
#define SIP_MAX_PACKET 4096 /*!< Also from RFC 3261 (2543), should sub headers tho */
#define SIP_MIN_PACKET 1024 /*!< Initialize size of memory to allocate for packets */
#define INITIAL_CSEQ 101 /*!< our initial sip sequence number */
#define DEFAULT_MAX_SE 1800 /*!< Session-Timer Default Session-Expires period (RFC 4028) */
#define DEFAULT_MIN_SE 90 /*!< Session-Timer Default Min-SE period (RFC 4028) */
#define SDP_MAX_RTPMAP_CODECS 32 /*!< Maximum number of codecs allowed in received SDP */
/*! \brief Global jitterbuffer configuration - by default, jb is disabled */
static struct ast_jb_conf default_jbconf =
{
.flags = 0,
.max_size = -1,
.resync_threshold = -1,
.impl = "",
.target_extra = -1,
};
static struct ast_jb_conf global_jbconf; /*!< Global jitterbuffer configuration */
static const char config[] = "sip.conf"; /*!< Main configuration file */
static const char notify_config[] = "sip_notify.conf"; /*!< Configuration file for sending Notify with CLI commands to reconfigure or reboot phones */
#define RTP 1
#define NO_RTP 0
/*! \brief Authorization scheme for call transfers
\note Not a bitfield flag, since there are plans for other modes,
like "only allow transfers for authenticated devices" */
enum transfermodes {
TRANSFER_OPENFORALL, /*!< Allow all SIP transfers */
TRANSFER_CLOSED, /*!< Allow no SIP transfers */
};
/*! \brief The result of a lot of functions */
enum sip_result {
AST_SUCCESS = 0, /*! FALSE means success, funny enough */
AST_FAILURE = -1,
};
/*! \brief States for the INVITE transaction, not the dialog
\note this is for the INVITE that sets up the dialog
*/
enum invitestates {
INV_NONE = 0, /*!< No state at all, maybe not an INVITE dialog */
INV_CALLING = 1, /*!< Invite sent, no answer */
INV_PROCEEDING = 2, /*!< We got/sent 1xx message */
INV_EARLY_MEDIA = 3, /*!< We got 18x message with to-tag back */
INV_COMPLETED = 4, /*!< Got final response with error. Wait for ACK, then CONFIRMED */
INV_CONFIRMED = 5, /*!< Confirmed response - we've got an ack (Incoming calls only) */
INV_TERMINATED = 6, /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done
The only way out of this is a BYE from one side */
INV_CANCELLED = 7, /*!< Transaction cancelled by client or server in non-terminated state */
};
/*! \brief Readable descriptions of device states.
\note Should be aligned to above table as index */
static const struct invstate2stringtable {
const enum invitestates state;
const char *desc;
} invitestate2string[] = {
{INV_NONE, "None" },
{INV_CALLING, "Calling (Trying)"},
{INV_PROCEEDING, "Proceeding "},
{INV_EARLY_MEDIA, "Early media"},
{INV_COMPLETED, "Completed (done)"},
{INV_CONFIRMED, "Confirmed (up)"},
{INV_TERMINATED, "Done"},
{INV_CANCELLED, "Cancelled"}
};
/*! \brief When sending a SIP message, we can send with a few options, depending on
type of SIP request. UNRELIABLE is moslty used for responses to repeated requests,
where the original response would be sent RELIABLE in an INVITE transaction */
enum xmittype {
XMIT_CRITICAL = 2, /*!< Transmit critical SIP message reliably, with re-transmits.
If it fails, it's critical and will cause a teardown of the session */
XMIT_RELIABLE = 1, /*!< Transmit SIP message reliably, with re-transmits */
XMIT_UNRELIABLE = 0, /*!< Transmit SIP message without bothering with re-transmits */
};
enum parse_register_result {
PARSE_REGISTER_DENIED,
PARSE_REGISTER_FAILED,
PARSE_REGISTER_UPDATE,
PARSE_REGISTER_QUERY,
};
/*! \brief Type of subscription, based on the packages we do support */
enum subscriptiontype {
NONE = 0,
XPIDF_XML,
DIALOG_INFO_XML,
CPIM_PIDF_XML,
PIDF_XML,
MWI_NOTIFICATION
};
/*! \brief Subscription types that we support. We support
- dialoginfo updates (really device status, not dialog info as was the original intent of the standard)
- SIMPLE presence used for device status
- Voicemail notification subscriptions
*/
static const struct cfsubscription_types {
enum subscriptiontype type;
const char * const event;
const char * const mediatype;
const char * const text;
} subscription_types[] = {
{ NONE, "-", "unknown", "unknown" },
/* RFC 4235: SIP Dialog event package */
{ DIALOG_INFO_XML, "dialog", "application/dialog-info+xml", "dialog-info+xml" },
{ CPIM_PIDF_XML, "presence", "application/cpim-pidf+xml", "cpim-pidf+xml" }, /* RFC 3863 */
{ PIDF_XML, "presence", "application/pidf+xml", "pidf+xml" }, /* RFC 3863 */
{ XPIDF_XML, "presence", "application/xpidf+xml", "xpidf+xml" }, /* Pre-RFC 3863 with MS additions */
{ MWI_NOTIFICATION, "message-summary", "application/simple-message-summary", "mwi" } /* RFC 3842: Mailbox notification */
};
/*! \brief Authentication types - proxy or www authentication
\note Endpoints, like Asterisk, should always use WWW authentication to
allow multiple authentications in the same call - to the proxy and
to the end point.
*/
enum sip_auth_type {
PROXY_AUTH = 407,
WWW_AUTH = 401,
};
/*! \brief Authentication result from check_auth* functions */
enum check_auth_result {
AUTH_DONT_KNOW = -100, /*!< no result, need to check further */
/* XXX maybe this is the same as AUTH_NOT_FOUND */
AUTH_SUCCESSFUL = 0,
AUTH_CHALLENGE_SENT = 1,
AUTH_SECRET_FAILED = -1,
AUTH_USERNAME_MISMATCH = -2,
AUTH_NOT_FOUND = -3, /*!< returned by register_verify */
AUTH_FAKE_AUTH = -4,
AUTH_UNKNOWN_DOMAIN = -5,
AUTH_PEER_NOT_DYNAMIC = -6,
AUTH_ACL_FAILED = -7,
AUTH_BAD_TRANSPORT = -8,
};
/*! \brief States for outbound registrations (with register= lines in sip.conf */
enum sipregistrystate {
REG_STATE_UNREGISTERED = 0, /*!< We are not registered
* \note Initial state. We should have a timeout scheduled for the initial
* (or next) registration transmission, calling sip_reregister
*/
REG_STATE_REGSENT, /*!< Registration request sent
* \note sent initial request, waiting for an ack or a timeout to
* retransmit the initial request.
*/
REG_STATE_AUTHSENT, /*!< We have tried to authenticate
* \note entered after transmit_register with auth info,
* waiting for an ack.
*/
REG_STATE_REGISTERED, /*!< Registered and done */
REG_STATE_REJECTED, /*!< Registration rejected *
* \note only used when the remote party has an expire larger than
* our max-expire. This is a final state from which we do not
* recover (not sure how correctly).
*/
REG_STATE_TIMEOUT, /*!< Registration timed out *
* \note XXX unused */
REG_STATE_NOAUTH, /*!< We have no accepted credentials
* \note fatal - no chance to proceed */
REG_STATE_FAILED, /*!< Registration failed after several tries
* \note fatal - no chance to proceed */
};
/*! \brief Modes in which Asterisk can be configured to run SIP Session-Timers */
enum st_mode {
SESSION_TIMER_MODE_INVALID = 0, /*!< Invalid value */
SESSION_TIMER_MODE_ACCEPT, /*!< Honor inbound Session-Timer requests */
SESSION_TIMER_MODE_ORIGINATE, /*!< Originate outbound and honor inbound requests */
SESSION_TIMER_MODE_REFUSE /*!< Ignore inbound Session-Timers requests */
};
/*! \brief The entity playing the refresher role for Session-Timers */
enum st_refresher {
SESSION_TIMER_REFRESHER_AUTO, /*!< Negotiated */
SESSION_TIMER_REFRESHER_UAC, /*!< Session is refreshed by the UAC */
SESSION_TIMER_REFRESHER_UAS /*!< Session is refreshed by the UAS */
};
/*! \brief Define some implemented SIP transports
\note Asterisk does not support SCTP or UDP/DTLS
*/
enum sip_transport {
SIP_TRANSPORT_UDP = 1, /*!< Unreliable transport for SIP, needs retransmissions */
SIP_TRANSPORT_TCP = 1 << 1, /*!< Reliable, but unsecure */
SIP_TRANSPORT_TLS = 1 << 2, /*!< TCP/TLS - reliable and secure transport for signalling */
};
/*! \brief definition of a sip proxy server
*
* For outbound proxies, this is allocated in the SIP peer dynamically or
* statically as the global_outboundproxy. The pointer in a SIP message is just
* a pointer and should *not* be de-allocated.
*/
struct sip_proxy {
char name[MAXHOSTNAMELEN]; /*!< DNS name of domain/host or IP */
struct sockaddr_in ip; /*!< Currently used IP address and port */
time_t last_dnsupdate; /*!< When this was resolved */
enum sip_transport transport;
int force; /*!< If it's an outbound proxy, Force use of this outbound proxy for all outbound requests */
/* Room for a SRV record chain based on the name */
};
/*! \brief argument for the 'show channels|subscriptions' callback. */
struct __show_chan_arg {
int fd;
int subscriptions;
int numchans; /* return value */
};
/*! \brief States whether a SIP message can create a dialog in Asterisk. */
enum can_create_dialog {
CAN_NOT_CREATE_DIALOG,
CAN_CREATE_DIALOG,
CAN_CREATE_DIALOG_UNSUPPORTED_METHOD,
};
/*! \brief SIP Request methods known by Asterisk
\note Do _NOT_ make any changes to this enum, or the array following it;
if you think you are doing the right thing, you are probably
not doing the right thing. If you think there are changes
needed, get someone else to review them first _before_
submitting a patch. If these two lists do not match properly
bad things will happen.
*/
enum sipmethod {
SIP_UNKNOWN, /*!< Unknown response */
SIP_RESPONSE, /*!< Not request, response to outbound request */
SIP_REGISTER, /*!< Registration to the mothership, tell us where you are located */
SIP_OPTIONS, /*!< Check capabilities of a device, used for "ping" too */
SIP_NOTIFY, /*!< Status update, Part of the event package standard, result of a SUBSCRIBE or a REFER */
SIP_INVITE, /*!< Set up a session */
SIP_ACK, /*!< End of a three-way handshake started with INVITE. */
SIP_PRACK, /*!< Reliable pre-call signalling. Not supported in Asterisk. */
SIP_BYE, /*!< End of a session */
SIP_REFER, /*!< Refer to another URI (transfer) */
SIP_SUBSCRIBE, /*!< Subscribe for updates (voicemail, session status, device status, presence) */
SIP_MESSAGE, /*!< Text messaging */
SIP_UPDATE, /*!< Update a dialog. We can send UPDATE; but not accept it */
SIP_INFO, /*!< Information updates during a session */
SIP_CANCEL, /*!< Cancel an INVITE */
SIP_PUBLISH, /*!< Not supported in Asterisk */
SIP_PING, /*!< Not supported at all, no standard but still implemented out there */
};
/*! \brief The core structure to setup dialogs. We parse incoming messages by using
structure and then route the messages according to the type.
\note Note that sip_methods[i].id == i must hold or the code breaks */
static const struct cfsip_methods {
enum sipmethod id;
int need_rtp; /*!< when this is the 'primary' use for a pvt structure, does it need RTP? */
char * const text;
enum can_create_dialog can_create;
} sip_methods[] = {
{ SIP_UNKNOWN, RTP, "-UNKNOWN-", CAN_CREATE_DIALOG },
{ SIP_RESPONSE, NO_RTP, "SIP/2.0", CAN_NOT_CREATE_DIALOG },
{ SIP_REGISTER, NO_RTP, "REGISTER", CAN_CREATE_DIALOG },
{ SIP_OPTIONS, NO_RTP, "OPTIONS", CAN_CREATE_DIALOG },
{ SIP_NOTIFY, NO_RTP, "NOTIFY", CAN_CREATE_DIALOG },
{ SIP_INVITE, RTP, "INVITE", CAN_CREATE_DIALOG },
{ SIP_ACK, NO_RTP, "ACK", CAN_NOT_CREATE_DIALOG },
{ SIP_PRACK, NO_RTP, "PRACK", CAN_NOT_CREATE_DIALOG },
{ SIP_BYE, NO_RTP, "BYE", CAN_NOT_CREATE_DIALOG },
{ SIP_REFER, NO_RTP, "REFER", CAN_CREATE_DIALOG },
{ SIP_SUBSCRIBE, NO_RTP, "SUBSCRIBE", CAN_CREATE_DIALOG },
{ SIP_MESSAGE, NO_RTP, "MESSAGE", CAN_CREATE_DIALOG },
{ SIP_UPDATE, NO_RTP, "UPDATE", CAN_NOT_CREATE_DIALOG },
{ SIP_INFO, NO_RTP, "INFO", CAN_NOT_CREATE_DIALOG },
{ SIP_CANCEL, NO_RTP, "CANCEL", CAN_NOT_CREATE_DIALOG },
{ SIP_PUBLISH, NO_RTP, "PUBLISH", CAN_CREATE_DIALOG_UNSUPPORTED_METHOD },
{ SIP_PING, NO_RTP, "PING", CAN_CREATE_DIALOG_UNSUPPORTED_METHOD }
};
static unsigned int chan_idx;
/*! Define SIP option tags, used in Require: and Supported: headers
We need to be aware of these properties in the phones to use
the replace: header. We should not do that without knowing
that the other end supports it...
This is nothing we can configure, we learn by the dialog
Supported: header on the REGISTER (peer) or the INVITE
(other devices)
We are not using many of these today, but will in the future.
This is documented in RFC 3261
*/
#define SUPPORTED 1
#define NOT_SUPPORTED 0
/* SIP options */
#define SIP_OPT_REPLACES (1 << 0)
#define SIP_OPT_100REL (1 << 1)
#define SIP_OPT_TIMER (1 << 2)
#define SIP_OPT_EARLY_SESSION (1 << 3)
#define SIP_OPT_JOIN (1 << 4)
#define SIP_OPT_PATH (1 << 5)
#define SIP_OPT_PREF (1 << 6)
#define SIP_OPT_PRECONDITION (1 << 7)
#define SIP_OPT_PRIVACY (1 << 8)
#define SIP_OPT_SDP_ANAT (1 << 9)
#define SIP_OPT_SEC_AGREE (1 << 10)
#define SIP_OPT_EVENTLIST (1 << 11)
#define SIP_OPT_GRUU (1 << 12)
#define SIP_OPT_TARGET_DIALOG (1 << 13)
#define SIP_OPT_NOREFERSUB (1 << 14)
#define SIP_OPT_HISTINFO (1 << 15)
#define SIP_OPT_RESPRIORITY (1 << 16)
#define SIP_OPT_FROMCHANGE (1 << 17)
#define SIP_OPT_RECLISTINV (1 << 18)
#define SIP_OPT_RECLISTSUB (1 << 19)
#define SIP_OPT_UNKNOWN (1 << 20)
/*! \brief List of well-known SIP options. If we get this in a require,
we should check the list and answer accordingly. */
static const struct cfsip_options {
int id; /*!< Bitmap ID */
int supported; /*!< Supported by Asterisk ? */
char * const text; /*!< Text id, as in standard */
} sip_options[] = { /* XXX used in 3 places */
/* RFC3262: PRACK 100% reliability */
{ SIP_OPT_100REL, NOT_SUPPORTED, "100rel" },
/* RFC3959: SIP Early session support */
{ SIP_OPT_EARLY_SESSION, NOT_SUPPORTED, "early-session" },
/* SIMPLE events: RFC4662 */
{ SIP_OPT_EVENTLIST, NOT_SUPPORTED, "eventlist" },
/* RFC 4916- Connected line ID updates */
{ SIP_OPT_FROMCHANGE, NOT_SUPPORTED, "from-change" },
/* GRUU: Globally Routable User Agent URI's */
{ SIP_OPT_GRUU, NOT_SUPPORTED, "gruu" },
/* RFC4244 History info */
{ SIP_OPT_HISTINFO, NOT_SUPPORTED, "histinfo" },
/* RFC3911: SIP Join header support */
{ SIP_OPT_JOIN, NOT_SUPPORTED, "join" },
/* Disable the REFER subscription, RFC 4488 */
{ SIP_OPT_NOREFERSUB, NOT_SUPPORTED, "norefersub" },
/* RFC3327: Path support */
{ SIP_OPT_PATH, NOT_SUPPORTED, "path" },
/* RFC3840: Callee preferences */
{ SIP_OPT_PREF, NOT_SUPPORTED, "pref" },
/* RFC3312: Precondition support */
{ SIP_OPT_PRECONDITION, NOT_SUPPORTED, "precondition" },
/* RFC3323: Privacy with proxies*/
{ SIP_OPT_PRIVACY, NOT_SUPPORTED, "privacy" },
/* RFC-ietf-sip-uri-list-conferencing-02.txt conference invite lists */
{ SIP_OPT_RECLISTINV, NOT_SUPPORTED, "recipient-list-invite" },
/* RFC-ietf-sip-uri-list-subscribe-02.txt - subscription lists */
{ SIP_OPT_RECLISTSUB, NOT_SUPPORTED, "recipient-list-subscribe" },
/* RFC3891: Replaces: header for transfer */
{ SIP_OPT_REPLACES, SUPPORTED, "replaces" },
/* One version of Polycom firmware has the wrong label */
{ SIP_OPT_REPLACES, SUPPORTED, "replace" },
/* RFC4412 Resource priorities */
{ SIP_OPT_RESPRIORITY, NOT_SUPPORTED, "resource-priority" },
/* RFC3329: Security agreement mechanism */
{ SIP_OPT_SEC_AGREE, NOT_SUPPORTED, "sec_agree" },
/* RFC4092: Usage of the SDP ANAT Semantics in the SIP */
{ SIP_OPT_SDP_ANAT, NOT_SUPPORTED, "sdp-anat" },
/* RFC4028: SIP Session-Timers */
{ SIP_OPT_TIMER, SUPPORTED, "timer" },
/* RFC4538: Target-dialog */
{ SIP_OPT_TARGET_DIALOG,NOT_SUPPORTED, "tdialog" },
};
/*! \brief SIP Methods we support
\todo This string should be set dynamically. We only support REFER and SUBSCRIBE is we have
allowsubscribe and allowrefer on in sip.conf.
*/
#define ALLOWED_METHODS "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO"
/*! \brief SIP Extensions we support
\note This should be generated based on the previous array
in combination with settings.
\todo We should not have "timer" if it's disabled in the configuration file.
*/
#define SUPPORTED_EXTENSIONS "replaces, timer"
/*! \brief Standard SIP unsecure port for UDP and TCP from RFC 3261. DO NOT CHANGE THIS */
#define STANDARD_SIP_PORT 5060
/*! \brief Standard SIP TLS port for sips: from RFC 3261. DO NOT CHANGE THIS */
#define STANDARD_TLS_PORT 5061
/*! \note in many SIP headers, absence of a port number implies port 5060,
* and this is why we cannot change the above constant.
* There is a limited number of places in asterisk where we could,
* in principle, use a different "default" port number, but
* we do not support this feature at the moment.
* You can run Asterisk with SIP on a different port with a configuration
* option. If you change this value, the signalling will be incorrect.
*/
/*! \name DefaultValues Default values, set and reset in reload_config before reading configuration
These are default values in the source. There are other recommended values in the
sip.conf.sample for new installations. These may differ to keep backwards compatibility,
yet encouraging new behaviour on new installations
*/
/*@{*/
#define DEFAULT_CONTEXT "default"
#define DEFAULT_MOHINTERPRET "default"
#define DEFAULT_MOHSUGGEST ""
#define DEFAULT_VMEXTEN "asterisk"
#define DEFAULT_CALLERID "asterisk"
#define DEFAULT_NOTIFYMIME "application/simple-message-summary"
#define DEFAULT_ALLOWGUEST TRUE
#define DEFAULT_CALLCOUNTER FALSE
#define DEFAULT_SRVLOOKUP TRUE /*!< Recommended setting is ON */
#define DEFAULT_COMPACTHEADERS FALSE
#define DEFAULT_TOS_SIP 0 /*!< Call signalling packets should be marked as DSCP CS3, but the default is 0 to be compatible with previous versions. */
#define DEFAULT_TOS_AUDIO 0 /*!< Audio packets should be marked as DSCP EF (Expedited Forwarding), but the default is 0 to be compatible with previous versions. */
#define DEFAULT_TOS_VIDEO 0 /*!< Video packets should be marked as DSCP AF41, but the default is 0 to be compatible with previous versions. */
#define DEFAULT_TOS_TEXT 0 /*!< Text packets should be marked as XXXX XXXX, but the default is 0 to be compatible with previous versions. */
#define DEFAULT_COS_SIP 4 /*!< Level 2 class of service for SIP signalling */
#define DEFAULT_COS_AUDIO 5 /*!< Level 2 class of service for audio media */
#define DEFAULT_COS_VIDEO 6 /*!< Level 2 class of service for video media */
#define DEFAULT_COS_TEXT 5 /*!< Level 2 class of service for text media (T.140) */
#define DEFAULT_ALLOW_EXT_DOM TRUE /*!< Allow external domains */
#define DEFAULT_REALM "asterisk" /*!< Realm for HTTP digest authentication */
#define DEFAULT_NOTIFYRINGING TRUE
#define DEFAULT_PEDANTIC FALSE
#define DEFAULT_AUTOCREATEPEER FALSE
#define DEFAULT_QUALIFY FALSE
#define DEFAULT_REGEXTENONQUALIFY FALSE
#define DEFAULT_T1MIN 100 /*!< 100 MS for minimal roundtrip time */
#define DEFAULT_MAX_CALL_BITRATE (384) /*!< Max bitrate for video */
#ifndef DEFAULT_USERAGENT
#define DEFAULT_USERAGENT "Asterisk PBX" /*!< Default Useragent: header unless re-defined in sip.conf */
#define DEFAULT_SDPSESSION "Asterisk PBX" /*!< Default SDP session name, (s=) header unless re-defined in sip.conf */
#define DEFAULT_SDPOWNER "root" /*!< Default SDP username field in (o=) header unless re-defined in sip.conf */
#endif
/*@}*/
/*! \name DefaultSettings
Default setttings are used as a channel setting and as a default when
configuring devices
*/
/*@{*/
static char default_context[AST_MAX_CONTEXT];
static char default_subscribecontext[AST_MAX_CONTEXT];
static char default_language[MAX_LANGUAGE];
static char default_callerid[AST_MAX_EXTENSION];
static char default_fromdomain[AST_MAX_EXTENSION];
static char default_notifymime[AST_MAX_EXTENSION];
static int default_qualify; /*!< Default Qualify= setting */
static char default_vmexten[AST_MAX_EXTENSION];
static char default_mohinterpret[MAX_MUSICCLASS]; /*!< Global setting for moh class to use when put on hold */
static char default_mohsuggest[MAX_MUSICCLASS]; /*!< Global setting for moh class to suggest when putting
* a bridged channel on hold */
static char default_parkinglot[AST_MAX_CONTEXT]; /*!< Parkinglot */
static int default_maxcallbitrate; /*!< Maximum bitrate for call */
static struct ast_codec_pref default_prefs; /*!< Default codec prefs */
/*! \brief a place to store all global settings for the sip channel driver */
struct sip_settings {
int peer_rtupdate; /*!< G: Update database with registration data for peer? */
int rtsave_sysname; /*!< G: Save system name at registration? */
int ignore_regexpire; /*!< G: Ignore expiration of peer */
};
static struct sip_settings sip_cfg;
/*@}*/
/*! \name GlobalSettings
Global settings apply to the channel (often settings you can change in the general section
of sip.conf
*/
/*@{*/
static int global_directrtpsetup; /*!< Enable support for Direct RTP setup (no re-invites) */
static int global_rtautoclear; /*!< Realtime ?? */
static int global_notifyringing; /*!< Send notifications on ringing */
static int global_notifyhold; /*!< Send notifications on hold */
static int global_alwaysauthreject; /*!< Send 401 Unauthorized for all failing requests */
static int global_srvlookup; /*!< SRV Lookup on or off. Default is on */
static int pedanticsipchecking; /*!< Extra checking ? Default off */
static int autocreatepeer; /*!< Auto creation of peers at registration? Default off. */
static int global_match_auth_username; /*!< Match auth username if available instead of From: Default off. */
static int global_relaxdtmf; /*!< Relax DTMF */
static int global_prematuremediafilter; /*!< Enable/disable premature frames in a call (causing 183 early media) */
static int global_relaxdtmf; /*!< Relax DTMF */
static int global_rtptimeout; /*!< Time out call if no RTP */
static int global_rtpholdtimeout; /*!< Time out call if no RTP during hold */
static int global_rtpkeepalive; /*!< Send RTP keepalives */
static int global_reg_timeout;
static int global_regattempts_max; /*!< Registration