Wed Aug 18 22:34:11 2010

Asterisk developer's documentation


chan_sip.c File Reference

Implementation of Session Initiation Protocol. More...

#include "asterisk.h"
#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"
#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"
#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"

Go to the source code of this file.

Data Structures

struct  __show_chan_arg
 argument for the 'show channels|subscriptions' callback. More...
struct  _map_x_s
 generic struct to map between strings and integers. Fill it with x-s pairs, terminate with an entry with s = NULL; Then you can call map_x_s(...) to map an integer to a string, and map_s_x() for the string -> integer mapping. More...
struct  ast_register_list
 The register list: Other SIP proxies we register with and place calls to. More...
struct  cfsip_methods
 The core structure to setup dialogs. We parse incoming messages by using structure and then route the messages according to the type. More...
struct  cfsip_options
 List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly. More...
struct  cfsubscription_types
 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.
More...
struct  domain
 Domain data structure. More...
struct  domain_list
struct  find_call_cb_arg
 argument to the helper function to identify a call More...
struct  invstate2stringtable
 Readable descriptions of device states. More...
struct  offered_media
struct  peer_finding_info
struct  sip_auth
 sip_auth: Credentials for authentication to other SIP services More...
struct  sip_dual
 structure used in transfers More...
struct  sip_history
 sip_history: Structure for saving transactions within a SIP dialog More...
struct  sip_history_head
struct  sip_invite_param
 Parameters to the transmit_invite function. More...
struct  sip_mailbox
 A peer's mailbox. More...
struct  sip_peer
 Structure for SIP peer data, we place calls to peers if registered or fixed IP address (host). More...
struct  sip_pkt
 sip packet - raw format for outbound packets that are sent or scheduled for transmission Packets are linked in a list, whose head is in the struct sip_pvt they belong to. Each packet holds a reference to the parent struct sip_pvt. This structure is allocated in __sip_reliable_xmit() and only for packets that require retransmissions. More...
struct  sip_proxy
 definition of a sip proxy server More...
struct  sip_pvt
 Structure used for each SIP dialog, ie. a call, a registration, a subscribe. Created and initialized by sip_alloc(), the descriptor goes into the list of descriptors (dialoglist). More...
struct  sip_pvt::request_queue
struct  sip_refer
 Structure to handle SIP transfers. Dynamically allocated when needed. More...
struct  sip_registry
 Registrations with other SIP proxies. More...
struct  sip_request
 sip_request: The data grabbed from the UDP socket More...
struct  sip_route
 Structure to save routing information for a SIP session. More...
struct  sip_settings
 a place to store all global settings for the sip channel driver More...
struct  sip_socket
 The SIP socket definition. More...
struct  sip_st_cfg
 Structure that encapsulates all attributes related to configuration of SIP Session-Timers feature on a per user/peer basis. More...
struct  sip_st_dlg
 Structure that encapsulates all attributes related to running SIP Session-Timers feature on a per dialog basis. More...
struct  sip_threadinfo
 Definition of a thread that handles a socket. More...
struct  t38properties
 T.38 channel settings (at some point we need to make this alloc'ed. More...
struct  tcptls_packet

Object counters @{

Bug:
These counters are not handled in a thread-safe way ast_atomic_fetchadd_int() should be used to modify these values.


#define DEC_CALL_LIMIT   0
#define DEC_CALL_RINGING   2
#define INC_CALL_LIMIT   1
#define INC_CALL_RINGING   3
#define REQ_OFFSET_TO_STR(req, offset)   ((req)->data->str + ((req)->offset))
enum  domain_mode { SIP_DOMAIN_AUTO, SIP_DOMAIN_CONFIG }
 Modes for SIP domain handling in the PBX. More...
static int apeerobjs = 0
static struct ast_flags global_flags [2] = {{0}}
static int global_t38_maxdatagram
static struct io_contextio
static pthread_t monitor_thread = AST_PTHREADT_NULL
 This is the thread for the monitor which checks for input on the channels which are not currently in use.
static ast_mutex_t monlock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP )
 Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.
static ast_mutex_t netlock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP )
static int regobjs = 0
static int rpeerobjs = 0
static struct sched_contextsched
static ast_mutex_t sip_reload_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP )
static int sip_reloading = FALSE
static enum channelreloadreason sip_reloadreason
static int * sipsock_read_id
static int speerobjs = 0
static char used_context [AST_MAX_CONTEXT]

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_ALLOW_EXT_DOM   TRUE
#define DEFAULT_ALLOWGUEST   TRUE
#define DEFAULT_AUTOCREATEPEER   FALSE
#define DEFAULT_CALLCOUNTER   FALSE
#define DEFAULT_CALLERID   "asterisk"
#define DEFAULT_COMPACTHEADERS   FALSE
#define DEFAULT_CONTEXT   "default"
#define DEFAULT_COS_AUDIO   5
#define DEFAULT_COS_SIP   4
#define DEFAULT_COS_TEXT   5
#define DEFAULT_COS_VIDEO   6
#define DEFAULT_MAX_CALL_BITRATE   (384)
#define DEFAULT_MOHINTERPRET   "default"
#define DEFAULT_MOHSUGGEST   ""
#define DEFAULT_NOTIFYMIME   "application/simple-message-summary"
#define DEFAULT_NOTIFYRINGING   TRUE
#define DEFAULT_PEDANTIC   FALSE
#define DEFAULT_QUALIFY   FALSE
#define DEFAULT_REALM   "asterisk"
#define DEFAULT_REGEXTENONQUALIFY   FALSE
#define DEFAULT_SDPOWNER   "root"
#define DEFAULT_SDPSESSION   "Asterisk PBX"
#define DEFAULT_SRVLOOKUP   TRUE
#define DEFAULT_T1MIN   100
#define DEFAULT_TOS_AUDIO   0
#define DEFAULT_TOS_SIP   0
#define DEFAULT_TOS_TEXT   0
#define DEFAULT_TOS_VIDEO   0
#define DEFAULT_USERAGENT   "Asterisk PBX"
#define DEFAULT_VMEXTEN   "asterisk"

SIPflags

Various flags for the flags field in the pvt structure Trying to sort these up (one or more of the following): D: Dialog P: Peer/user G: Global flag When flags are used by multiple structures, it is important that they have a common layout so it is easy to copy them.

#define SIP_CALL_LIMIT   (1 << 7)
#define SIP_CAN_REINVITE   (1 << 20)
#define SIP_CAN_REINVITE_NAT   (2 << 20)
#define SIP_DEFER_BYE_ON_TRANSFER   (1 << 10)
#define SIP_DTMF   (7 << 15)
#define SIP_DTMF_AUTO   (3 << 15)
#define SIP_DTMF_INBAND   (1 << 15)
#define SIP_DTMF_INFO   (2 << 15)
#define SIP_DTMF_RFC2833   (0 << 15)
#define SIP_DTMF_SHORTINFO   (4 << 15)
#define SIP_FLAGS_TO_COPY
 Flags to copy from peer/user to dialog.
#define SIP_G726_NONSTANDARD   (1 << 31)
#define SIP_GOTREFER   (1 << 6)
#define SIP_INC_COUNT   (1 << 8)
#define SIP_INC_RINGING   (1 << 9)
#define SIP_INSECURE   (3 << 23)
#define SIP_INSECURE_INVITE   (1 << 24)
#define SIP_INSECURE_NONE   (0 << 23)
#define SIP_INSECURE_PORT   (1 << 23)
#define SIP_NAT   (3 << 18)
#define SIP_NAT_ALWAYS   (3 << 18)
#define SIP_NAT_NEVER   (0 << 18)
#define SIP_NAT_RFC3581   (1 << 18)
#define SIP_NAT_ROUTE   (2 << 18)
#define SIP_NEEDREINVITE   (1 << 4)
#define SIP_OUTGOING   (1 << 0)
#define SIP_PENDINGBYE   (1 << 5)
#define SIP_PROG_INBAND   (3 << 25)
#define SIP_PROG_INBAND_NEVER   (0 << 25)
#define SIP_PROG_INBAND_NO   (1 << 25)
#define SIP_PROG_INBAND_YES   (2 << 25)
#define SIP_PROGRESS_SENT   (1 << 3)
#define SIP_PROMISCREDIR   (1 << 11)
#define SIP_REINVITE   (7 << 20)
#define SIP_REINVITE_NONE   (0 << 20)
#define SIP_REINVITE_UPDATE   (4 << 20)
#define SIP_RINGING   (1 << 2)
#define SIP_SENDRPID   (1 << 29)
#define SIP_TRUSTRPID   (1 << 12)
#define SIP_USECLIENTCODE   (1 << 14)
#define SIP_USEREQPHONE   (1 << 13)

SIPflags2

a second page of flags (for flags[1]

#define SIP_PAGE2_ALLOWOVERLAP   (1 << 17)
#define SIP_PAGE2_ALLOWSUBSCRIBE   (1 << 16)
#define SIP_PAGE2_BUGGY_MWI   (1 << 26)
#define SIP_PAGE2_CALL_ONHOLD   (3 << 23)
#define SIP_PAGE2_CALL_ONHOLD_ACTIVE   (1 << 23)
#define SIP_PAGE2_CALL_ONHOLD_INACTIVE   (3 << 23)
#define SIP_PAGE2_CALL_ONHOLD_ONEDIR   (2 << 23)
#define SIP_PAGE2_DIALOG_ESTABLISHED   (1 << 27)
#define SIP_PAGE2_FAX_DETECT   (1 << 28)
#define SIP_PAGE2_FLAGS_TO_COPY
#define SIP_PAGE2_HAVEPEERCONTEXT   (1 << 3)
#define SIP_PAGE2_IGNORESDPVERSION   (1 << 19)
#define SIP_PAGE2_REGISTERTRYING   (1 << 29)
#define SIP_PAGE2_RFC2833_COMPENSATE   (1 << 25)
#define SIP_PAGE2_RPORT_PRESENT   (1 << 10)
#define SIP_PAGE2_RTAUTOCLEAR   (1 << 2)
#define SIP_PAGE2_RTCACHEFRIENDS   (1 << 0)
#define SIP_PAGE2_STATECHANGEQUEUE   (1 << 9)
#define SIP_PAGE2_SUBSCRIBEMWIONLY   (1 << 18)
#define SIP_PAGE2_T38SUPPORT   (3 << 20)
#define SIP_PAGE2_T38SUPPORT_UDPTL   (1 << 20)
#define SIP_PAGE2_T38SUPPORT_UDPTL_FEC   (2 << 20)
#define SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY   (3 << 20)
#define SIP_PAGE2_TEXTSUPPORT   (1 << 15)
#define SIP_PAGE2_UDPTL_DESTINATION   (1 << 30)
#define SIP_PAGE2_VIDEOSUPPORT   (1 << 14)
#define SIP_PAGE2_VIDEOSUPPORT_ALWAYS   (1 << 31)

GlobalSettings

Global settings apply to the channel (often settings you can change in the general section of sip.conf

static int allow_external_domains
static int autocreatepeer
static int compactheaders
static int dumphistory
static int global_allowguest
static int global_allowsubscribe
static enum transfermodes global_allowtransfer
static int global_alwaysauthreject
static int global_authfailureevents
static int global_autoframing
static int global_callcounter
static int global_callevents
static int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263
 Codecs that we support by default:.
static unsigned int global_cos_audio
static unsigned int global_cos_sip
static unsigned int global_cos_text
static unsigned int global_cos_video
static int global_directrtpsetup
static int global_dynamic_exclude_static = 0
static int global_match_auth_username
static int global_matchexterniplocally
static int global_max_se
static int global_min_se
static int global_notifyhold
static int global_notifyringing
static struct sip_proxy global_outboundproxy
static int global_prematuremediafilter
static int global_qualifyfreq
static char global_realm [MAXHOSTNAMELEN]
static int global_reg_timeout
static int global_regattempts_max
static char global_regcontext [AST_MAX_CONTEXT]
static int global_regextenonqualify
static int global_relaxdtmf
static int global_relaxdtmf
static int global_rtautoclear
static int global_rtpholdtimeout
static int global_rtpkeepalive
static int global_rtptimeout
static char global_sdpowner [AST_MAX_EXTENSION]
static char global_sdpsession [AST_MAX_EXTENSION]
static int global_shrinkcallerid
static int global_srvlookup
static enum st_mode global_st_mode
static enum st_refresher global_st_refresher
static int global_t1
static int global_t1min
static int global_timer_b
static unsigned int global_tos_audio
static unsigned int global_tos_sip
static unsigned int global_tos_text
static unsigned int global_tos_video
static char global_useragent [AST_MAX_EXTENSION]
static int pedanticsipchecking
static int recordhistory

DefaultSettings

Default setttings are used as a channel setting and as a default when configuring devices

static char default_callerid [AST_MAX_EXTENSION]
static char default_context [AST_MAX_CONTEXT]
static char default_fromdomain [AST_MAX_EXTENSION]
static char default_language [MAX_LANGUAGE]
static int default_maxcallbitrate
static char default_mohinterpret [MAX_MUSICCLASS]
static char default_mohsuggest [MAX_MUSICCLASS]
static char default_notifymime [AST_MAX_EXTENSION]
static char default_parkinglot [AST_MAX_CONTEXT]
static struct ast_codec_pref default_prefs
static int default_qualify
static char default_subscribecontext [AST_MAX_CONTEXT]
static char default_vmexten [AST_MAX_EXTENSION]
static struct sip_settings sip_cfg

Defines

#define ALLOWED_METHODS   "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO"
 SIP Methods we support.
#define append_history(p, event, fmt, args...)   append_history_full(p, "%-15s " fmt, event, ## args)
 Append to SIP dialog history.
#define CALLERID_UNKNOWN   "Anonymous"
#define CHECK_AUTH_BUF_INITLEN   256
#define check_request_transport(peer, tmpl)
 generic function for determining if a correct transport is being used to contact a peer
#define DEFAULT_DEFAULT_EXPIRY   120
#define DEFAULT_EXPIRY   900
#define DEFAULT_FREQ_NOTOK   10 * 1000
#define DEFAULT_MAX_EXPIRY   3600
#define DEFAULT_MAX_FORWARDS   "70"
#define DEFAULT_MAX_SE   1800
#define DEFAULT_MAXMS   2000
#define DEFAULT_MIN_EXPIRY   60
#define DEFAULT_MIN_SE   90
#define DEFAULT_QUALIFYFREQ   60 * 1000
#define DEFAULT_REGISTRATION_TIMEOUT   20
#define DEFAULT_RETRANS   1000
#define DEFAULT_TRANS_TIMEOUT   -1
#define EXPIRY_GUARD_LIMIT   30
#define EXPIRY_GUARD_MIN   500
#define EXPIRY_GUARD_PCT   0.20
#define EXPIRY_GUARD_SECS   15
#define FALSE   0
#define FINDALLDEVICES   (FINDUSERS | FINDPEERS)
#define FINDPEERS   (1 << 1)
#define FINDUSERS   (1 << 0)
#define FORMAT   "%-15.15s %-15.15s %-15.15s %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n"
#define FORMAT   "%-15.15s %-11.11s %-8.8s %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.6u %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.6u\n"
#define FORMAT   "%-30.30s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n"
#define FORMAT   "%-40.40s %-20.20s %-16.16s\n"
#define FORMAT   "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %s\n"
#define FORMAT   "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n"
#define FORMAT   "%-30.30s %-6d %-9.9s %-6.6s\n"
#define FORMAT   "%-25.25s %-15.15s %-15.15s \n"
#define FORMAT2   "%-15.15s %-15.15s %-15.15s %-15.15s %-7.7s %-15.15s %-6.6s\n"
#define FORMAT2   "%-15.15s %-11.11s %-8.8s %-10.10s %-10.10s ( %%) %-6.6s %-10.10s %-10.10s ( %%) %-6.6s\n"
#define FORMAT2   "%-30.30s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n"
#define FORMAT2   "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %s\n"
#define FORMAT2   "%-30.30s %3.6s %9.9s %6.6s\n"
#define FORMAT2   "%-25.25s %-15.15s %-15.15s \n"
#define FORMAT3   "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6s\n"
#define FORMAT4   "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6d\n"
#define FROMDOMAIN_INVALID   "anonymous.invalid"
#define INITIAL_CSEQ   101
#define IS_SIP_TECH(t)   ((t) == &sip_tech || (t) == &sip_tech_info)
#define MAX_AUTHTRIES   3
#define MAX_HISTORY_ENTRIES   50
#define MAX_RETRANS   6
#define NO_RTP   0
#define NOT_SUPPORTED   0
#define PROVIS_KEEPALIVE_TIMEOUT   60000
#define RTP   1
#define SDP_MAX_RTPMAP_CODECS   32
#define SDP_SAMPLE_RATE(x)   8000
#define SIP_MAX_HEADERS   64
#define SIP_MAX_LINES   256
#define SIP_MAX_PACKET   4096
#define SIP_MIN_PACKET   1024
#define SIP_OPT_100REL   (1 << 1)
#define SIP_OPT_EARLY_SESSION   (1 << 3)
#define SIP_OPT_EVENTLIST   (1 << 11)
#define SIP_OPT_FROMCHANGE   (1 << 17)
#define SIP_OPT_GRUU   (1 << 12)
#define SIP_OPT_HISTINFO   (1 << 15)
#define SIP_OPT_JOIN   (1 << 4)
#define SIP_OPT_NOREFERSUB   (1 << 14)
#define SIP_OPT_PATH   (1 << 5)
#define SIP_OPT_PRECONDITION   (1 << 7)
#define SIP_OPT_PREF   (1 << 6)
#define SIP_OPT_PRIVACY   (1 << 8)
#define SIP_OPT_RECLISTINV   (1 << 18)
#define SIP_OPT_RECLISTSUB   (1 << 19)
#define SIP_OPT_REPLACES   (1 << 0)
#define SIP_OPT_RESPRIORITY   (1 << 16)
#define SIP_OPT_SDP_ANAT   (1 << 9)
#define SIP_OPT_SEC_AGREE   (1 << 10)
#define SIP_OPT_TARGET_DIALOG   (1 << 13)
#define SIP_OPT_TIMER   (1 << 2)
#define SIP_OPT_UNKNOWN   (1 << 20)
#define sip_pvt_lock(x)   ao2_lock(x)
#define sip_pvt_trylock(x)   ao2_trylock(x)
#define sip_pvt_unlock(x)   ao2_unlock(x)
#define SIP_RESERVED   ";/?:@&=+$,# "
#define SIP_TIMER_T1   500
#define SIP_TRANS_TIMEOUT   64 * SIP_TIMER_T1
#define SIPBUFSIZE   512
#define STANDARD_SIP_PORT   5060
 Standard SIP unsecure port for UDP and TCP from RFC 3261. DO NOT CHANGE THIS.
#define STANDARD_TLS_PORT   5061
 Standard SIP TLS port for sips: from RFC 3261. DO NOT CHANGE THIS.
#define SUPPORTED   1
#define SUPPORTED_EXTENSIONS   "replaces, timer"
 SIP Extensions we support.
#define TRUE   1
#define UNLINK(element, head, prev)
#define XMIT_ERROR   -2

Enumerations

enum  can_create_dialog { CAN_NOT_CREATE_DIALOG, CAN_CREATE_DIALOG, CAN_CREATE_DIALOG_UNSUPPORTED_METHOD }
 States whether a SIP message can create a dialog in Asterisk. More...
enum  check_auth_result {
  AUTH_DONT_KNOW = -100, AUTH_SUCCESSFUL = 0, AUTH_CHALLENGE_SENT = 1, AUTH_SECRET_FAILED = -1,
  AUTH_USERNAME_MISMATCH = -2, AUTH_NOT_FOUND = -3, AUTH_FAKE_AUTH = -4, AUTH_UNKNOWN_DOMAIN = -5,
  AUTH_PEER_NOT_DYNAMIC = -6, AUTH_ACL_FAILED = -7, AUTH_BAD_TRANSPORT = -8
}
 Authentication result from check_auth* functions. More...
enum  invitestates {
  INV_NONE = 0, INV_CALLING = 1, INV_PROCEEDING = 2, INV_EARLY_MEDIA = 3,
  INV_COMPLETED = 4, INV_CONFIRMED = 5, INV_TERMINATED = 6, INV_CANCELLED = 7
}
 States for the INVITE transaction, not the dialog. More...
enum  media_type { SDP_AUDIO, SDP_VIDEO, SDP_IMAGE, SDP_TEXT }
enum  parse_register_result { PARSE_REGISTER_DENIED, PARSE_REGISTER_FAILED, PARSE_REGISTER_UPDATE, PARSE_REGISTER_QUERY }
enum  referstatus {
  REFER_IDLE, REFER_SENT, REFER_RECEIVED, REFER_CONFIRMED,
  REFER_ACCEPTED, REFER_RINGING, REFER_200OK, REFER_FAILED,
  REFER_NOAUTH
}
 Parameters to know status of transfer. More...
enum  sip_auth_type { PROXY_AUTH = 407, WWW_AUTH = 401 }
 Authentication types - proxy or www authentication. More...
enum  sip_debug_e { sip_debug_none = 0, sip_debug_config = 1, sip_debug_console = 2 }
 debugging state We store separately the debugging requests from the config file and requests from the CLI. Debugging is enabled if either is set (which means that if sipdebug is set in the config file, we can only turn it off by reloading the config). More...
enum  sip_peer_type { SIP_TYPE_PEER = (1 << 0), SIP_TYPE_USER = (1 << 1) }
enum  sip_result { AST_SUCCESS = 0, AST_FAILURE = -1 }
 The result of a lot of functions. More...
enum  sip_tcptls_alert { TCPTLS_ALERT_DATA, TCPTLS_ALERT_STOP }
enum  sip_transport { SIP_TRANSPORT_UDP = 1, SIP_TRANSPORT_TCP = 1 << 1, SIP_TRANSPORT_TLS = 1 << 2 }
 Define some implemented SIP transports. More...
enum  sipmethod {
  SIP_UNKNOWN, SIP_RESPONSE, SIP_REGISTER, SIP_OPTIONS,
  SIP_NOTIFY, SIP_INVITE, SIP_ACK, SIP_PRACK,
  SIP_BYE, SIP_REFER, SIP_SUBSCRIBE, SIP_MESSAGE,
  SIP_UPDATE, SIP_INFO, SIP_CANCEL, SIP_PUBLISH,
  SIP_PING
}
 SIP Request methods known by Asterisk. More...
enum  sipregistrystate {
  REG_STATE_UNREGISTERED = 0, REG_STATE_REGSENT, REG_STATE_AUTHSENT, REG_STATE_REGISTERED,
  REG_STATE_REJECTED, REG_STATE_TIMEOUT, REG_STATE_NOAUTH, REG_STATE_FAILED
}
 States for outbound registrations (with register= lines in sip.conf. More...
enum  st_mode { SESSION_TIMER_MODE_INVALID = 0, SESSION_TIMER_MODE_ACCEPT, SESSION_TIMER_MODE_ORIGINATE, SESSION_TIMER_MODE_REFUSE }
 Modes in which Asterisk can be configured to run SIP Session-Timers. More...
enum  st_refresher { SESSION_TIMER_REFRESHER_AUTO, SESSION_TIMER_REFRESHER_UAC, SESSION_TIMER_REFRESHER_UAS }
 The entity playing the refresher role for Session-Timers. More...
enum  subscriptiontype {
  NONE = 0, XPIDF_XML, DIALOG_INFO_XML, CPIM_PIDF_XML,
  PIDF_XML, MWI_NOTIFICATION
}
 Type of subscription, based on the packages we do support. More...
enum  t38_action_flag { SDP_T38_NONE = 0, SDP_T38_INITIATE, SDP_T38_ACCEPT }
enum  t38state { T38_DISABLED = 0, T38_LOCAL_REINVITE, T38_PEER_REINVITE, T38_ENABLED }
 T38 States for a call. More...
enum  transfermodes { TRANSFER_OPENFORALL, TRANSFER_CLOSED }
 Authorization scheme for call transfers. More...
enum  xmittype { XMIT_CRITICAL = 2, XMIT_RELIABLE = 1, XMIT_UNRELIABLE = 0 }
 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. More...

Functions

static const char * __get_header (const struct sip_request *req, const char *name, int *start)
static void __init_check_auth_buf (void)
static void __init_ts_temp_pvt (void)
 A per-thread temporary pvt structure.
static void __reg_module (void)
static int __set_address_from_contact (const char *fullcontact, struct sockaddr_in *sin, int tcp)
static int __sip_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod)
 Acknowledges receipt of a packet and stops retransmission called with p locked.
static int __sip_autodestruct (const void *data)
 Kill a SIP dialog (called only by the scheduler) The scheduler has a reference to this dialog when p->autokillid != -1, and we are called using that reference. So if the event is not rescheduled, we need to call dialog_unref().
static void __sip_destroy (struct sip_pvt *p, int lockowner, int lockdialoglist)
 Execute destruction of SIP dialog structure, release memory.
static int __sip_do_register (struct sip_registry *r)
 Register with SIP proxy.
static void __sip_pretend_ack (struct sip_pvt *p)
 Pretend to ack all packets called with p locked.
static int __sip_reliable_xmit (struct sip_pvt *p, int seqno, int resp, struct ast_str *data, int len, int fatal, int sipmethod)
 Transmit packet with retransmits.
static int __sip_semi_ack (struct sip_pvt *p, int seqno, int resp, int sipmethod)
 Acks receipt of packet, keep it around (used for provisional responses).
static int __sip_xmit (struct sip_pvt *p, struct ast_str *data, int len)
 Transmit SIP message Sends a SIP request or response on a given socket (in the pvt) Called by retrans_pkt, send_request, send_response and __sip_reliable_xmit.
static int __transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Base transmit response function.
static void __unreg_module (void)
static char * _sip_qualify_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[])
 Send qualify message to peer from cli or manager. Mostly for debugging.
static char * _sip_show_peer (int type, int fd, struct mansession *s, const struct message *m, int argc, const char *argv[])
 Show one peer in detail (main function).
static char * _sip_show_peers (int fd, int *total, struct mansession *s, const struct message *m, int argc, const char *argv[])
 Execute sip show peers command.
static void * _sip_tcp_helper_thread (struct sip_pvt *pvt, struct ast_tcptls_session_instance *tcptls_session)
 SIP TCP thread management function.
static int acf_channel_read (struct ast_channel *chan, const char *funcname, char *preparse, char *buf, size_t buflen)
static void add_blank (struct sip_request *req)
 add a blank line if no body
static void add_codec_to_sdp (const struct sip_pvt *p, int codec, int sample_rate, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size)
 Add codec offer to SDP offer/answer body in INVITE or 200 OK.
static int add_digit (struct sip_request *req, char digit, unsigned int duration, int mode)
 Add DTMF INFO tone to sip message Mode = 0 for application/dtmf-relay (Cisco) 1 for application/dtmf.
static int add_header (struct sip_request *req, const char *var, const char *value)
 Add header to SIP message.
static int add_header_contentLength (struct sip_request *req, int len)
 Add 'Content-Length' header to SIP message.
static int add_line (struct sip_request *req, const char *line)
 Add content (not header) to SIP message.
static void add_noncodec_to_sdp (const struct sip_pvt *p, int format, int sample_rate, struct ast_str **m_buf, struct ast_str **a_buf, int debug)
 Add RFC 2833 DTMF offer to SDP.
static void add_peer_mailboxes (struct sip_peer *peer, const char *value)
static void add_peer_mwi_subs (struct sip_peer *peer)
static struct sip_authadd_realm_authentication (struct sip_auth *authlist, const char *configuration, int lineno)
 Add realm authentication in list.
static void add_route (struct sip_request *req, struct sip_route *route)
 Add route header into request per learned route.
static enum sip_result add_sdp (struct sip_request *resp, struct sip_pvt *p, int oldsdp, int add_audio, int add_t38)
 Add Session Description Protocol message.
static int add_sip_domain (const char *domain, const enum domain_mode mode, const char *context)
 Add SIP domain to list of domains we are responsible for.
static void add_tcodec_to_sdp (const struct sip_pvt *p, int codec, int sample_rate, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size)
 Add text codec offer to SDP offer/answer body in INVITE or 200 OK.
static int add_text (struct sip_request *req, const char *text)
 Add text body to SIP message.
static struct ast_variableadd_var (const char *buf, struct ast_variable *list)
 implement the setvar config line
static void add_vcodec_to_sdp (const struct sip_pvt *p, int codec, int sample_rate, struct ast_str **m_buf, struct ast_str **a_buf, int debug, int *min_packet_size)
 Add video codec offer to SDP offer/answer body in INVITE or 200 OK.
static int add_vidupdate (struct sip_request *req)
 add XML encoded media control with update
static void append_date (struct sip_request *req)
 Append date to SIP message.
static void append_history_full (struct sip_pvt *p, const char *fmt,...)
 Append to SIP dialog history with arg list.
static void append_history_va (struct sip_pvt *p, const char *fmt, va_list ap)
 Append to SIP dialog history with arg list.
static void ast_quiet_chan (struct ast_channel *chan)
 Turn off generator data XXX Does this function belong in the SIP channel?
static void ast_sip_ouraddrfor (struct in_addr *them, struct sockaddr_in *us, struct sip_pvt *p)
 NAT fix - decide which IP address to use for Asterisk server?
static int attempt_transfer (struct sip_dual *transferer, struct sip_dual *target)
 Attempt transfer of SIP call This fix for attended transfers on a local PBX.
static void auth_headers (enum sip_auth_type code, char **header, char **respheader)
 return the request and response heade for a 401 or 407 code
static int auto_congest (const void *arg)
 Scheduled congestion on a call. Only called by the scheduler, must return the reference when done.
static void build_callid_pvt (struct sip_pvt *pvt)
 Build SIP Call-ID value for a non-REGISTER transaction.
static void build_callid_registry (struct sip_registry *reg, struct in_addr ourip, const char *fromdomain)
 Build SIP Call-ID value for a REGISTER transaction.
static void build_contact (struct sip_pvt *p)
 Build contact header - the contact header we send out.
static struct sip_peerbuild_peer (const char *name, struct ast_variable *v, struct ast_variable *alt, int realtime, int devstate_only)
 Build peer from configuration (file or realtime static/dynamic).
static int build_reply_digest (struct sip_pvt *p, int method, char *digest, int digest_len)
 Build reply digest.
static void build_route (struct sip_pvt *p, struct sip_request *req, int backwards)
 Build route list from Record-Route header.
static void build_rpid (struct sip_pvt *p)
 Build the Remote Party-ID & From using callingpres options.
static void build_via (struct sip_pvt *p)
 Build a Via header for a request.
static int cb_extensionstate (char *context, char *exten, int state, void *data)
 Callback for the devicestate notification (SUBSCRIBE) support subsystem.
static void change_t38_state (struct sip_pvt *p, int state)
 Change the T38 state on a SIP dialog.
static enum check_auth_result check_auth (struct sip_pvt *p, struct sip_request *req, const char *username, const char *secret, const char *md5secret, int sipmethod, char *uri, enum xmittype reliable, int ignore)
 Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set).
static enum check_auth_result check_peer_ok (struct sip_pvt *p, char *of, struct sip_request *req, int sipmethod, struct sockaddr_in *sin, struct sip_peer **authpeer, enum xmittype reliable, char *rpid_num, char *calleridname, char *uri2)
 Validate device authentication.
static void check_pendings (struct sip_pvt *p)
 Check pending actions on SIP call.
static void check_rtp_timeout (struct sip_pvt *dialog, time_t t)
 helper function for the monitoring thread -- seems to be called with the assumption that the dialog is locked
static int check_sip_domain (const char *domain, char *context, size_t len)
 check_sip_domain: Check if domain part of uri is local to our server
static int check_user (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin)
 Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced.
static enum check_auth_result check_user_full (struct sip_pvt *p, struct sip_request *req, int sipmethod, char *uri, enum xmittype reliable, struct sockaddr_in *sin, struct sip_peer **authpeer)
 Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests.
static void check_via (struct sip_pvt *p, struct sip_request *req)
 check Via: header for hostname, port and rport request/answer
static attribute_unused void check_via_response (struct sip_pvt *p, struct sip_request *req)
 check received= and rport= in a SIP response. If we get a response with received= and/or rport= in the Via: line, use them as 'p->ourip' (see RFC 3581 for rport, and RFC 3261 for received). Using these two fields SIP can produce the correct address and port in the SIP headers without the need for STUN. The address part is also reused for the media sessions. Note that ast_sip_ouraddrfor() still rewrites p->ourip if you specify externip/seternaddr/stunaddr.
static void cleanup_stale_contexts (char *new, char *old)
 Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly.
static void clear_peer_mailboxes (struct sip_peer *peer)
static int clear_realm_authentication (struct sip_auth *authlist)
 Clear realm authentication list (at reload).
static void clear_sip_domains (void)
 Clear our domain list (at reload).
static const char * cli_yesno (int x)
 return Yes or No depending on the argument. This is used in many places in CLI command, having a function to generate this helps maintaining a consistent output (and possibly emitting the output in other languages, at some point).
static char * complete_sip_peer (const char *word, int state, int flags2)
 Do completion on peer name.
static char * complete_sip_registered_peer (const char *word, int state, int flags2)
 Do completion on registered peer name.
static char * complete_sip_show_history (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show history' CLI.
static char * complete_sip_show_peer (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show peer' CLI.
static char * complete_sip_show_user (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show user' CLI.
static char * complete_sip_unregister (const char *line, const char *word, int pos, int state)
 Support routine for 'sip unregister' CLI.
static char * complete_sip_user (const char *word, int state)
 Do completion on user name.
static char * complete_sipch (const char *line, const char *word, int pos, int state)
 Support routine for 'sip show channel' and 'sip show history' CLI This is in charge of generating all strings that match a prefix in the given position. As many functions of this kind, each invokation has O(state) time complexity so be careful in using it.
static char * complete_sipnotify (const char *line, const char *word, int pos, int state)
 Support routine for 'sip notify' CLI.
static int copy_all_header (struct sip_request *req, const struct sip_request *orig, const char *field)
 Copy all headers from one request to another.
static int copy_header (struct sip_request *req, const struct sip_request *orig, const char *field)
 Copy one header field from one request to another.
static void copy_request (struct sip_request *dst, const struct sip_request *src)
 copy SIP request (mostly used to save request for responses)
static void copy_socket_data (struct sip_socket *to_sock, const struct sip_socket *from_sock)
static struct ast_variablecopy_vars (struct ast_variable *src)
static int copy_via_headers (struct sip_pvt *p, struct sip_request *req, const struct sip_request *orig, const char *field)
 Copy SIP VIA Headers from the request to the response.
static int create_addr (struct sip_pvt *dialog, const char *opeer, struct sockaddr_in *sin, int newdialog)
 create address structure from device name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success
static int create_addr_from_peer (struct sip_pvt *dialog, struct sip_peer *peer)
 Create address structure from peer reference. This function copies data from peer to the dialog, so we don't have to look up the peer again from memory or database during the life time of the dialog.
static void destroy_association (struct sip_peer *peer)
 Remove registration data from realtime database or AST/DB when registration expires.
static void destroy_mailbox (struct sip_mailbox *mailbox)
static int determine_firstline_parts (struct sip_request *req)
 Parse first line of incoming SIP request.
static int dialog_cmp_cb (void *obj, void *arg, int flags)
static int dialog_dump_func (void *userobj, void *arg, int flags)
static int dialog_hash_cb (const void *obj, const int flags)
static int dialog_needdestroy (void *dialogobj, void *arg, int flags)
static struct sip_pvtdialog_ref (struct sip_pvt *p, char *tag)
 when we create or delete references, make sure to use these functions so we keep track of the refcounts. To simplify the code, we allow a NULL to be passed to dialog_unref().
static void * dialog_unlink_all (struct sip_pvt *dialog, int lockowner, int lockdialoglist)
 Unlink a dialog from the dialogs container, as well as any other places that it may be currently stored.
static struct sip_pvtdialog_unref (struct sip_pvt *p, char *tag)
static void * do_monitor (void *data)
 The SIP monitoring thread.
static int do_proxy_auth (struct sip_pvt *p, struct sip_request *req, enum sip_auth_type code, int sipmethod, int init)
 Add authentication on outbound SIP packet.
static int do_register_auth (struct sip_pvt *p, struct sip_request *req, enum sip_auth_type code)
 Authenticate for outbound registration.
static void do_setnat (struct sip_pvt *p, int natflags)
 Set nat mode on the various data sockets.
static const char * domain_mode_to_text (const enum domain_mode mode)
 Print domain mode to cli.
static const char * dtmfmode2str (int mode)
 Convert DTMF mode to printable string.
static int expire_register (const void *data)
 Expire registration of SIP peer.
static void extract_uri (struct sip_pvt *p, struct sip_request *req)
 Check Contact: URI of SIP message.
static const char * faxec2str (int faxec)
static const char * find_alias (const char *name, const char *_default)
 Find compressed SIP alias.
static int find_by_name (void *obj, void *arg, int flags)
static struct sip_pvtfind_call (struct sip_request *req, struct sockaddr_in *sin, const int intended_method)
 find or create a dialog structure for an incoming SIP message. Connect incoming SIP message to current dialog or create new dialog structure Returns a reference to the sip_pvt object, remember to give it back once done. Called by handle_incoming(), sipsock_read
static int find_call_cb (void *__pvt, void *__arg, int flags)
static const char * find_closing_quote (const char *start, const char *lim)
 Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote.
static struct sip_peerfind_peer (const char *peer, struct sockaddr_in *sin, int realtime, int which_objects, int devstate_only, int transport)
 Locate device by name or ip address.
static struct sip_authfind_realm_authentication (struct sip_auth *authlist, const char *realm)
 Find authentication for a specific realm.
static int find_sdp (struct sip_request *req)
 Determine whether a SIP message contains an SDP in its body.
static int find_sip_method (const char *msg)
 find_sip_method: Find SIP method from header
static struct cfsubscription_typesfind_subscription_type (enum subscriptiontype subtype)
 Find subscription type in array.
static void free_old_route (struct sip_route *route)
 Remove route from route list.
static int func_check_sipdomain (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 Dial plan function to check if domain is local.
static int func_header_read (struct ast_channel *chan, const char *function, char *data, char *buf, size_t len)
 Read SIP header (dialplan function).
static int function_sipchaninfo_read (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 ${SIPCHANINFO()} Dialplan function - reads sip channel data
static int function_sippeer (struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
 ${SIPPEER()} Dialplan function - reads peer data
static char * generate_random_string (char *buf, size_t size)
 Generate 32 byte random string for callid's etc.
static int get_also_info (struct sip_pvt *p, struct sip_request *oreq)
 Call transfer support (old way, deprecated by the IETF)--.
static char * get_body (struct sip_request *req, char *name)
 Get a specific line from the message body.
static char * get_body_by_line (const char *line, const char *name, int nameLen)
 Reads one line of SIP message body.
static int get_cached_mwi (struct sip_peer *peer, int *new, int *old)
 Get cached MWI info.
static char * get_calleridname (const char *input, char *output, size_t outputsize)
 Get caller id name from SIP headers.
static int get_destination (struct sip_pvt *p, struct sip_request *oreq)
 Find out who the call is for. We use the request uri as a destination. This code assumes authentication has been done, so that the device (peer/user) context is already set.
static const char * get_header (const struct sip_request *req, const char *name)
 Get header from SIP request.
static char * get_in_brackets (char *tmp)
 Pick out text in brackets from character string.
static struct ast_variableget_insecure_variable_from_config (struct ast_config *config)
static int get_ip_and_port_from_sdp (struct sip_request *req, const enum media_type media, struct sockaddr_in *sin)
static int get_msg_text (char *buf, int len, struct sip_request *req, int addnewline)
 Get text out of a SIP MESSAGE packet.
static const char * get_name_from_variable (struct ast_variable *var, const char *newpeername)
static void get_our_media_address (struct sip_pvt *p, int needvideo, struct sockaddr_in *sin, struct sockaddr_in *vsin, struct sockaddr_in *tsin, struct sockaddr_in *dest, struct sockaddr_in *vdest)
 Set all IP media addresses for this call.
static int get_rdnis (struct sip_pvt *p, struct sip_request *oreq)
 Get referring dnis.
static int get_refer_info (struct sip_pvt *transferer, struct sip_request *outgoing_req)
 Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure.
static int get_rpid_num (const char *input, char *output, int maxlen)
 Get caller id number from Remote-Party-ID header field Returns true if number should be restricted (privacy setting found) output is set to NULL if no number found.
static const char * get_sdp_iterate (int *start, struct sip_request *req, const char *name)
 Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number.
static char get_sdp_line (int *start, int stop, struct sip_request *req, const char **value)
 Fetches the next valid SDP line between the 'start' line (inclusive) and the 'stop' line (exclusive). Returns the type ('a', 'c', ...) and matching line in reference 'start' is updated with the next line number.
static struct sip_pvtget_sip_pvt_byid_locked (const char *callid, const char *totag, const char *fromtag)
 Lock dialog lock and find matching pvt lock.
static const char * get_transport (enum sip_transport t)
static const char * get_transport_list (struct sip_peer *peer)
static const char * get_transport_pvt (struct sip_pvt *p)
static int get_transport_str2enum (const char *transport)
 Return int representing a bit field of transport types found in const char *transport.
static const char * gettag (const struct sip_request *req, const char *header, char *tagbuf, int tagbufsize)
 Get tag from packet.
static int handle_common_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v)
 Handle flag-type options common to configuration of devices - peers.
static int handle_incoming (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int *recount, int *nounlock)
 Handle incoming SIP requests (methods).
static int handle_invite_replaces (struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *nounlock)
 Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer. Used only once. XXX 'ignore' is unused.
static int handle_request_bye (struct sip_pvt *p, struct sip_request *req)
 Handle incoming BYE request.
static int handle_request_cancel (struct sip_pvt *p, struct sip_request *req)
 Handle incoming CANCEL request.
static int handle_request_do (struct sip_request *req, struct sockaddr_in *sin)
static void handle_request_info (struct sip_pvt *p, struct sip_request *req)
 Receive SIP INFO Message.
static int handle_request_invite (struct sip_pvt *p, struct sip_request *req, int debug, int seqno, struct sockaddr_in *sin, int *recount, char *e, int *nounlock)
 Handle incoming INVITE request.
static int handle_request_message (struct sip_pvt *p, struct sip_request *req)
 Handle incoming MESSAGE request.
static int handle_request_notify (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e)
 Handle incoming notifications.
static int handle_request_options (struct sip_pvt *p, struct sip_request *req)
 Handle incoming OPTIONS request An OPTIONS request should be answered like an INVITE from the same UA, including SDP.
static int handle_request_refer (struct sip_pvt *p, struct sip_request *req, int debug, int seqno, int *nounlock)
static int handle_request_register (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, char *e)
 Handle incoming REGISTER request.
static int handle_request_subscribe (struct sip_pvt *p, struct sip_request *req, struct sockaddr_in *sin, int seqno, char *e)
 Handle incoming SUBSCRIBE request.
static void handle_response (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno)
 Handle SIP response in dialogue.
static void handle_response_invite (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno)
 Handle SIP response to INVITE dialogue.
static void handle_response_notify (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno)
static void handle_response_peerpoke (struct sip_pvt *p, int resp, struct sip_request *req)
 Handle qualification responses (OPTIONS).
static void handle_response_refer (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno)
static int handle_response_register (struct sip_pvt *p, int resp, char *rest, struct sip_request *req, int seqno)
 Handle responses on REGISTER to services.
static int handle_t38_options (struct ast_flags *flags, struct ast_flags *mask, struct ast_variable *v, int *maxdatagram)
 Handle T.38 configuration options common to users and peers.
static const char * hangup_cause2sip (int cause)
 Convert Asterisk hangup causes to SIP codes.
static int hangup_sip2cause (int cause)
 Convert SIP hangup causes to Asterisk hangup causes.
static int init_req (struct sip_request *req, int sipmethod, const char *recip)
 Initialize SIP request.
static int init_resp (struct sip_request *resp, const char *msg)
 Initialize SIP response, based on SIP request.
static void initialize_initreq (struct sip_pvt *p, struct sip_request *req)
 Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog.
static void initreqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod)
 Initiate new SIP request to peer/user.
static const char * insecure2str (int mode)
 Convert Insecure setting to printable string.
static void interpret_t38_parameters (struct sip_pvt *p, const struct ast_control_t38_parameters *parameters)
 Helper function which updates T.38 capability information and triggers a reinvite.
static void list_route (struct sip_route *route)
 List all routes - mostly for debugging.
static int load_module (void)
 PBX load module - initialization.
static int local_attended_transfer (struct sip_pvt *transferer, struct sip_dual *current, struct sip_request *req, int seqno)
 Find all call legs and bridge transferee with target called from handle_request_refer.
static int lws2sws (char *msgbuf, int len)
 Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled.
static void make_our_tag (char *tagbuf, size_t len)
 Make our SIP dialog tag.
static int manager_show_registry (struct mansession *s, const struct message *m)
 Show SIP registrations in the manager API.
static int manager_sip_qualify_peer (struct mansession *s, const struct message *m)
 Qualify SIP peers in the manager API.
static int manager_sip_show_peer (struct mansession *s, const struct message *m)
 Show SIP peers in the manager API.
static int manager_sip_show_peers (struct mansession *s, const struct message *m)
 Show SIP peers in the manager API.
static int manager_sipnotify (struct mansession *s, const struct message *m)
static int map_s_x (const struct _map_x_s *table, const char *s, int errorvalue)
 map from a string to an integer value, case insensitive. If no match is found, return errorvalue.
static const char * map_x_s (const struct _map_x_s *table, int x, const char *errorstring)
 map from an integer value to a string. If no match is found, return errorstring
static int method_match (enum sipmethod id, const char *name)
 returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send
static void mwi_event_cb (const struct ast_event *event, void *userdata)
 Receive MWI events that we have subscribed to.
static const char * nat2str (int nat)
 Convert NAT setting to text string.
static struct sip_proxyobproxy_get (struct sip_pvt *dialog, struct sip_peer *peer)
 Get default outbound proxy or global proxy.
static void parse_copy (struct sip_request *dst, const struct sip_request *src)
 Copy SIP request, parse it.
static int parse_minse (const char *p_hdrval, int *const p_interval)
 Session-Timers: Function for parsing Min-SE header.
static void parse_moved_contact (struct sip_pvt *p, struct sip_request *req)
 Parse 302 Moved temporalily response.
static int parse_ok_contact (struct sip_pvt *pvt, struct sip_request *req)
 Save contact header for 200 OK on INVITE.
static enum parse_register_result parse_register_contact (struct sip_pvt *pvt, struct sip_peer *peer, struct sip_request *req)
 Parse contact header and save registration (peer registration).
static int parse_request (struct sip_request *req)
 Parse a SIP message.
static int parse_session_expires (const char *p_hdrval, int *const p_interval, enum st_refresher *const p_ref)
 Session-Timers: Function for parsing Session-Expires header.
static unsigned int parse_sip_options (struct sip_pvt *pvt, const char *supported)
 Parse supported header in incoming packet.
static int parse_uri (char *uri, const char *scheme, char **ret_name, char **pass, char **domain, char **port, char **options, char **transport)
 * parses a URI in its components.
static int peer_cmp_cb (void *obj, void *arg, int flags)
static int peer_dump_func (void *userobj, void *arg, int flags)
static int peer_hash_cb (const void *obj, const int flags)
static int peer_ipcmp_cb (void *obj, void *arg, int flags)
static int peer_iphash_cb (const void *obj, const int flags)
static int peer_is_marked (void *peerobj, void *arg, int flags)
static void peer_mailboxes_to_str (struct ast_str **mailbox_str, struct sip_peer *peer)
 list peer mailboxes to CLI
static int peer_markall_func (void *device, void *arg, int flags)
static int peer_status (struct sip_peer *peer, char *status, int statuslen)
int peercomparefunc (const void *a, const void *b)
static int port_str2int (const char *pt, unsigned int standard)
 converts ascii port to int representation. If no pt buffer is provided or the pt has errors when being converted to an int value, the port provided as the standard is used.
static void print_codec_to_cli (int fd, struct ast_codec_pref *pref)
 Print codec list from preference to CLI/manager.
static void print_group (int fd, ast_group_t group, int crlf)
 Print call group and pickup group.
static void proc_422_rsp (struct sip_pvt *p, struct sip_request *rsp)
 Handle 422 response to INVITE with session-timer requested.
static int proc_session_timer (const void *vp)
 Session-Timers: Process session refresh timeout event.
static void process_request_queue (struct sip_pvt *p, int *recount, int *nounlock)
static int process_sdp (struct sip_pvt *p, struct sip_request *req, int t38action)
 Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp().
static int process_sdp_a_audio (const char *a, struct sip_pvt *p, struct ast_rtp *newaudiortp, int *last_rtpmap_codec)
static int process_sdp_a_image (const char *a, struct sip_pvt *p)
static int process_sdp_a_sendonly (const char *a, int *sendonly)
static int process_sdp_a_text (const char *a, struct sip_pvt *p, struct ast_rtp *newtextrtp, char *red_fmtp, int *red_num_gen, int *red_data_pt, int *last_rtpmap_codec)
static int process_sdp_a_video (const char *a, struct sip_pvt *p, struct ast_rtp *newvideortp, int *last_rtpmap_codec)
static int process_sdp_c (const char *c, struct ast_hostent *hp)
static int process_sdp_o (const char *o, struct sip_pvt *p)
static struct sip_proxyproxy_allocate (char *name, char *port, int force)
 Allocate and initialize sip proxy.
static int proxy_update (struct sip_proxy *proxy)
static int queue_request (struct sip_pvt *p, const struct sip_request *req)
static struct sip_peerrealtime_peer (const char *newpeername, struct sockaddr_in *sin, int devstate_only)
 realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf Checks the "sipregs" realtime family from extconfig.conf if it's configured. This returns a pointer to a peer and because we use build_peer, we can rest assured that the refcount is bumped.
static void realtime_update_peer (const char *peername, struct sockaddr_in *sin, const char *defaultuser, const char *fullcontact, const char *useragent, int expirey, int deprecated_username, int lastms)
 Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups.
static void receive_message (struct sip_pvt *p, struct sip_request *req)
 Receive SIP MESSAGE method messages.
static struct sip_peerref_peer (struct sip_peer *peer, char *tag)
static struct sip_proxyref_proxy (struct sip_pvt *pvt, struct sip_proxy *proxy)
 maintain proper refcounts for a sip_pvt's outboundproxy
static const char * referstatus2str (enum referstatus rstatus)
 Convert transfer status to string.
static void reg_source_db (struct sip_peer *peer)
 Get registration details from Asterisk DB.
static void register_peer_exten (struct sip_peer *peer, int onoff)
 Automatically add peer extension to dial plan.
static enum check_auth_result register_verify (struct sip_pvt *p, struct sockaddr_in *sin, struct sip_request *req, char *uri)
 Verify registration of user
  • Registration is done in several steps, first a REGISTER without auth to get a challenge (nonce) then a second one with auth
  • Registration requests are only matched with peers that are marked as "dynamic".

static struct sip_registryregistry_addref (struct sip_registry *reg, char *tag)
 Add object reference to SIP registry.
static void * registry_unref (struct sip_registry *reg, char *tag)
static const char * regstate2str (enum sipregistrystate regstate)
 Convert registration state status to string.
static int reload (void)
 Part of Asterisk module interface.
static int reload_config (enum channelreloadreason reason)
 Re-read SIP.conf config file.
static char * remove_uri_parameters (char *uri)
static void replace_cid (struct sip_pvt *p, const char *rpid_num, const char *calleridname)
 helper function for check_{user|peer}_ok()
static int reply_digest (struct sip_pvt *p, struct sip_request *req, char *header, int sipmethod, char *digest, int digest_len)
 reply to authentication for outbound registrations
static int reqprep (struct sip_request *req, struct sip_pvt *p, int sipmethod, int seqno, int newbranch)
 Initialize a SIP request message (not the initial one in a dialog).
static int resp_needs_contact (const char *msg, enum sipmethod method)
 Test if this response needs a contact header.
static int respprep (struct sip_request *resp, struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Prepare SIP response packet.
static int restart_monitor (void)
 Start the channel monitor thread.
static void restart_session_timer (struct sip_pvt *p)
 Session-Timers: Restart session timer.
static int retrans_pkt (const void *data)
 Retransmit SIP message if no answer (Called from scheduler).
static int scheduler_process_request_queue (const void *data)
static int send_provisional_keepalive (const void *data)
static int send_provisional_keepalive_full (struct sip_pvt *pvt, int with_sdp)
static int send_provisional_keepalive_with_sdp (const void *data)
static int send_request (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno)
 Send SIP Request to the other part of the dialogue.
static int send_response (struct sip_pvt *p, struct sip_request *req, enum xmittype reliable, int seqno)
 Transmit response on SIP request.
static int set_address_from_contact (struct sip_pvt *pvt)
 Change the other partys IP address based on given contact.
static void set_destination (struct sip_pvt *p, char *uri)
 Set destination from SIP URI.
static void set_insecure_flags (struct ast_flags *flags, const char *value, int lineno)
 Parse insecure= setting in sip.conf and set flags according to setting.
static void set_nonce_randdata (struct sip_pvt *p, int forceupdate)
 builds the sip_pvt's randdata field which is used for the nonce challenge. When forceupdate is not set, the nonce is only updated if the current one is stale. In this case, a stalenonce is one which has already received a response, if a nonce has not received a response it is not always necessary or beneficial to create a new one.
static void set_peer_defaults (struct sip_peer *peer)
 Set peer defaults before configuring specific configurations.
static void set_socket_transport (struct sip_socket *socket, int transport)
static void set_t38_capabilities (struct sip_pvt *p)
 Set the global T38 capabilities on a SIP dialog structure.
static int show_channels_cb (void *__cur, void *__arg, int flags)
 callback for show channel|subscription
static int show_chanstats_cb (void *__cur, void *__arg, int flags)
 Callback for show_chanstats.
static int sip_addheader (struct ast_channel *chan, void *data)
 Add a SIP header to an outbound INVITE.
static struct sip_pvtsip_alloc (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, struct sip_request *req)
 Allocate sip_pvt structure, set defaults and link in the container. Returns a reference to the object so whoever uses it later must remember to release the reference.
static void sip_alreadygone (struct sip_pvt *dialog)
 Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging.
static int sip_answer (struct ast_channel *ast)
 sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface
static int sip_call (struct ast_channel *ast, char *dest, int timeout)
 Initiate SIP call from PBX used from the dial() application.
static int sip_cancel_destroy (struct sip_pvt *p)
 Cancel destruction of SIP dialog. Be careful as this also absorbs the reference - if you call it from within the scheduler, this might be the last reference.
static char * sip_cli_notify (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Cli command to send SIP notify to peer.
static int sip_debug_test_addr (const struct sockaddr_in *addr)
 See if we pass debug IP filter.
static int sip_debug_test_pvt (struct sip_pvt *p)
 Test PVT for debugging output.
static struct sip_pvtsip_destroy (struct sip_pvt *p)
 Destroy SIP call structure. Make it return NULL so the caller can do things like foo = sip_destroy(foo); and reduce the chance of bugs due to dangling pointers.
static void sip_destroy_fn (void *p)
static void sip_destroy_peer (struct sip_peer *peer)
 Destroy peer object from memory.
static void sip_destroy_peer_fn (void *peer)
static int sip_devicestate (void *data)
 Part of PBX channel interface.
static char * sip_do_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Turn on SIP debugging (CLI command).
static char * sip_do_debug_ip (int fd, char *arg)
 Enable SIP Debugging for a single IP.
static char * sip_do_debug_peer (int fd, char *arg)
 Turn on SIP debugging for a given peer.
static char * sip_do_history_deprecated (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Enable/Disable SIP History logging (CLI) - deprecated. use sip_set_history instead.
static int sip_do_reload (enum channelreloadreason reason)
 Reload module.
static int sip_dtmfmode (struct ast_channel *chan, void *data)
 Set the DTMFmode for an outbound SIP call (application).
static void sip_dump_history (struct sip_pvt *dialog)
 Dump SIP history to debug log file at end of lifespan for SIP dialog.
static int sip_fixup (struct ast_channel *oldchan, struct ast_channel *newchan)
 sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links
static const char * sip_get_callid (struct ast_channel *chan)
 Deliver SIP call ID for the call.
static int sip_get_codec (struct ast_channel *chan)
 Return SIP UA's codec (part of the RTP interface).
static enum ast_rtp_get_result sip_get_rtp_peer (struct ast_channel *chan, struct ast_rtp **rtp)
 Returns null if we can't reinvite audio (part of RTP interface).
static enum ast_rtp_get_result sip_get_trtp_peer (struct ast_channel *chan, struct ast_rtp **rtp)
 Returns null if we can't reinvite text (part of RTP interface).
static struct ast_udptlsip_get_udptl_peer (struct ast_channel *chan)
static enum ast_rtp_get_result sip_get_vrtp_peer (struct ast_channel *chan, struct ast_rtp **rtp)
 Returns null if we can't reinvite video (part of RTP interface).
static int sip_hangup (struct ast_channel *ast)
 sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup
static int sip_indicate (struct ast_channel *ast, int condition, const void *data, size_t datalen)
 Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc.
static const char * sip_nat_mode (const struct sip_pvt *p)
 Display SIP nat mode.
static struct ast_channelsip_new (struct sip_pvt *i, int state, const char *title)
 Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels.
static int sip_park (struct ast_channel *chan1, struct ast_channel *chan2, struct sip_request *req, int seqno)
 Park a call using the subsystem in res_features.c This is executed in a separate thread.
static void * sip_park_thread (void *stuff)
 Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup.
static int sip_parse_host (char *line, int lineno, char **hostname, int *portnum, enum sip_transport *transport)
 Small function to parse a config line for a host with a transport i.e. tls://www.google.com:8056.
static void sip_peer_hold (struct sip_pvt *p, int hold)
 Change onhold state of a peer using a pvt structure.
static void sip_poke_all_peers (void)
 Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions?
static int sip_poke_noanswer (const void *data)
 React to lack of answer to Qualify poke.
static int sip_poke_peer (struct sip_peer *peer, int force)
 Check availability of peer, also keep NAT open.
static int sip_poke_peer_s (const void *data)
 Poke peer (send qualify to check if peer is alive and well).
static int sip_prepare_socket (struct sip_pvt *p)
static char * sip_prune_realtime (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Remove temporary realtime objects from memory (CLI).
static char * sip_qualify_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Send an OPTIONS packet to a SIP peer.
static int sip_queryoption (struct ast_channel *chan, int option, void *data, int *datalen)
 Query an option on a SIP dialog.
static struct ast_framesip_read (struct ast_channel *ast)
 Read SIP RTP from channel.
static struct sockaddr_in * sip_real_dst (const struct sip_pvt *p)
 The real destination address for a write.
static int sip_refer_allocate (struct sip_pvt *p)
 Allocate SIP refer structure.
static int sip_reg_timeout (const void *data)
 Registration timeout, register again Registered as a timeout handler during transmit_register(), to retransmit the packet if a reply does not come back. This is called by the scheduler so the event is not pending anymore when we are called.
static int sip_register (const char *value, int lineno)
 Parse register=> line in sip.conf and add to registry.
static void sip_registry_destroy (struct sip_registry *reg)
 Destroy registry object Objects created with the register= statement in static configuration.
static int sip_reinvite_retry (const void *data)
 Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler.
static char * sip_reload (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Force reload of module from cli.
static struct ast_channelsip_request_call (const char *type, int format, void *data, int *cause)
 PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.
static int sip_reregister (const void *data)
 Update registration with SIP Proxy. Called from the scheduler when the previous registration expires, so we don't have to cancel the pending event. We assume the reference so the sip_registry is valid, since it is stored in the scheduled event anyways.
static struct ast_framesip_rtp_read (struct ast_channel *ast, struct sip_pvt *p, int *faxdetect)
 Read RTP from network.
static void sip_scheddestroy (struct sip_pvt *p, int ms)
 Schedule destruction of SIP dialog.
static void sip_send_all_registers (void)
 Send all known registrations.
static int sip_send_mwi_to_peer (struct sip_peer *peer, const struct ast_event *event, int cache_only)
 Send message waiting indication to alert peer that they've got voicemail.
static int sip_senddigit_begin (struct ast_channel *ast, char digit)
static int sip_senddigit_end (struct ast_channel *ast, char digit, unsigned int duration)
 Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously.
static int sip_sendhtml (struct ast_channel *chan, int subclass, const char *data, int datalen)
 Send message with Access-URL header, if this is an HTML URL only!
static int sip_sendtext (struct ast_channel *ast, const char *text)
 Send SIP MESSAGE text within a call Called from PBX core sendtext() application.
static char * sip_set_history (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Enable/Disable SIP History logging (CLI).
static void sip_set_redirstr (struct sip_pvt *p, char *reason)
 Translate referring cause.
static int sip_set_rtp_peer (struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, struct ast_rtp *trtp, int codecs, int nat_active)
 Set the RTP peer for this call.
static int sip_set_udptl_peer (struct ast_channel *chan, struct ast_udptl *udptl)
static char * sip_show_channel (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show details of one active dialog.
static char * sip_show_channels (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI for show channels or subscriptions. This is a new-style CLI handler so a single function contains the prototype for the function, the 'generator' to produce multiple entries in case it is required, and the actual handler for the command.
static char * sip_show_channelstats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 SIP show channelstats CLI (main function).
static char * sip_show_domains (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI command to list local domains.
static char * sip_show_history (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show history details of one dialog.
static char * sip_show_inuse (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI Command to show calls within limits set by call_limit.
static char * sip_show_objects (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 List all allocated SIP Objects (realtime or static).
static char * sip_show_peer (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show one peer in detail.
static char * sip_show_peers (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI Show Peers command.
static char * sip_show_registry (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show SIP Registry (registrations with other SIP proxies.
static char * sip_show_sched (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static char * sip_show_settings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 List global settings for the SIP channel.
static char * sip_show_tcp (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show active TCP connections.
static char * sip_show_user (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show one user in detail.
static char * sip_show_users (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 CLI Command 'SIP Show Users'.
static int sip_sipredirect (struct sip_pvt *p, const char *dest)
 Transfer call before connect with a 302 redirect.
static struct sip_st_dlgsip_st_alloc (struct sip_pvt *const p)
 Allocate Session-Timers struct w/in dialog.
static int sip_standard_port (enum sip_transport type, int port)
 Returns the port to use for this socket.
static int sip_t38_abort (const void *data)
static struct ast_tcptls_session_instancesip_tcp_locate (struct sockaddr_in *s)
 Find thread for TCP/TLS session (based on IP/Port.
static void * sip_tcp_worker_fn (void *data)
 SIP TCP connection handler.
static void sip_tcptls_client_args_destructor (void *obj)
static int sip_tcptls_write (struct ast_tcptls_session_instance *tcptls_session, const void *buf, size_t len)
 used to indicate to a tcptls thread that data is ready to be written
static struct sip_threadinfosip_threadinfo_create (struct ast_tcptls_session_instance *tcptls_session, int transport)
 creates a sip_threadinfo object and links it into the threadt table.
static void sip_threadinfo_destructor (void *obj)
static int sip_transfer (struct ast_channel *ast, const char *dest)
 Transfer SIP call.
static char * sip_unregister (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Unregister (force expiration) a SIP peer in the registry via CLI.
static int sip_uri_cmp (const char *input1, const char *input2)
static int sip_uri_headers_cmp (const char *input1, const char *input2)
 helper routine for sip_uri_cmp
static int sip_uri_params_cmp (const char *input1, const char *input2)
 helper routine for sip_uri_cmp
static int sip_write (struct ast_channel *ast, struct ast_frame *frame)
 Send frame to media channel (rtp).
static int sipsock_read (int *id, int fd, short events, void *ignore)
 Read data from SIP socket.
static enum st_mode st_get_mode (struct sip_pvt *p)
 Get the session-timer mode.
static enum st_refresher st_get_refresher (struct sip_pvt *p)
 Get the entity (UAC or UAS) that's acting as the session-timer refresher.
static int st_get_se (struct sip_pvt *p, int max)
 Get Max or Min SE (session timer expiry).
static void start_session_timer (struct sip_pvt *p)
 Session-Timers: Start session timer.
static const char * stmode2str (enum st_mode m)
static void stop_media_flows (struct sip_pvt *p)
 Immediately stop RTP, VRTP and UDPTL as applicable.
static void stop_session_timer (struct sip_pvt *p)
 Session-Timers: Stop session timer.
static int str2dtmfmode (const char *str)
 maps a string to dtmfmode, returns -1 on error
static enum st_mode str2stmode (const char *s)
static enum st_refresher str2strefresher (const char *s)
static const char * strefresher2str (enum st_refresher r)
static const char * subscription_type2str (enum subscriptiontype subtype)
 Show subscription type in string format.
static unsigned int t38_get_rate (enum ast_control_t38_rate rate)
 Get Max T.38 Transmission rate from T38 capabilities.
static void tcptls_packet_destructor (void *obj)
static struct sip_peertemp_peer (const char *name)
 Create temporary peer (used in autocreatepeer mode).
static void temp_pvt_cleanup (void *)
static int temp_pvt_init (void *)
static char * terminate_uri (char *uri)
static int threadinfo_locate_cb (void *obj, void *arg, int flags)
static int threadt_cmp_cb (void *obj, void *arg, int flags)
static int threadt_hash_cb (const void *obj, const int flags)
static char * transfermode2str (enum transfermodes mode)
 Convert transfer mode to text string.
static void transmit_fake_auth_response (struct sip_pvt *p, int sipmethod, struct sip_request *req, enum xmittype reliable)
 Send a fake 401 Unauthorized response when the administrator wants to hide the names of local devices from fishers.
static int transmit_info_with_digit (struct sip_pvt *p, const char digit, unsigned int duration)
 Send SIP INFO dtmf message, see Cisco documentation on cisco.com.
static int transmit_info_with_vidupdate (struct sip_pvt *p)
 Send SIP INFO with video update request.
static int transmit_invite (struct sip_pvt *p, int sipmethod, int sdp, int init)
 Build REFER/INVITE/OPTIONS message and transmit it.
static int transmit_message_with_text (struct sip_pvt *p, const char *text)
 Transmit text with SIP MESSAGE method.
static int transmit_notify_custom (struct sip_pvt *p, struct ast_variable *vars)
 Notify device with custom headers from sip_notify.conf.
static int transmit_notify_with_mwi (struct sip_pvt *p, int newmsgs, int oldmsgs, char *vmexten)
 Notify user of messages waiting in voicemail (RFC3842).
static int transmit_notify_with_sipfrag (struct sip_pvt *p, int cseq, char *message, int terminate)
 Notify a transferring party of the status of transfer (RFC3515).
static int transmit_provisional_response (struct sip_pvt *p, const char *msg, const struct sip_request *req, int with_sdp)
static int transmit_refer (struct sip_pvt *p, const char *dest)
 Transmit SIP REFER message (initiated by the transfer() dialplan application.
static int transmit_register (struct sip_registry *r, int sipmethod, const char *auth, const char *authheader)
 Transmit register to SIP proxy or UA auth = NULL on the initial registration (from sip_reregister()).
static int transmit_reinvite_with_sdp (struct sip_pvt *p, int t38version, int oldsdp)
 Transmit reinvite with SDP.
static int transmit_request (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
 Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry).
static int transmit_request_with_auth (struct sip_pvt *p, int sipmethod, int seqno, enum xmittype reliable, int newbranch)
 Transmit SIP request, auth added.
static int transmit_response (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Transmit response, no retransmits.
static int transmit_response_reliable (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK.
static int transmit_response_using_temp (ast_string_field callid, struct sockaddr_in *sin, int useglobal_nat, const int intended_method, const struct sip_request *req, const char *msg)
 Transmit response, no retransmits, using a temporary pvt structure.
static int transmit_response_with_allow (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable)
 Append Accept header, content length before transmitting response.
static int transmit_response_with_auth (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *randdata, enum xmittype reliable, const char *header, int stale)
 Respond with authorization request.
static int transmit_response_with_date (struct sip_pvt *p, const char *msg, const struct sip_request *req)
 Append date and content length before transmitting response.
static int transmit_response_with_minse (struct sip_pvt *p, const char *msg, const struct sip_request *req, int minse_int)
 Transmit 422 response with Min-SE header (Session-Timers).
static int transmit_response_with_sdp (struct sip_pvt *p, const char *msg, const struct sip_request *req, enum xmittype reliable, int oldsdp)
 Used for 200 OK and 183 early media.
static int transmit_response_with_t38_sdp (struct sip_pvt *p, char *msg, struct sip_request *req, int retrans)
 Used for 200 OK and 183 early media.
static int transmit_response_with_unsupported (struct sip_pvt *p, const char *msg, const struct sip_request *req, const char *unsupported)
 Transmit response, no retransmits.
static int transmit_state_notify (struct sip_pvt *p, int state, int full, int timeout)
 Used in the SUBSCRIBE notification subsystem (RFC3265).
static void try_suggested_sip_codec (struct sip_pvt *p)
 Try setting codec suggested by the SIP_CODEC channel variable.
static int unload_module (void)
 PBX unload module API.
static void * unref_peer (struct sip_peer *peer, char *tag)
static int update_call_counter (struct sip_pvt *fup, int event)
 update_call_counter: Handle call_limit for SIP devices Setting a call-limit will cause calls above the limit not to be accepted.
static void update_peer (struct sip_peer *p, int expire)
 Update peer data in database (if used).
static void update_provisional_keepalive (struct sip_pvt *pvt, int with_sdp)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Session Initiation Protocol (SIP)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, }
static char * app_dtmfmode = "SIPDtmfMode"
static char * app_sipaddheader = "SIPAddHeader"
static struct ast_module_infoast_module_info = &__mod_info
static struct sip_authauthl = NULL
 Authentication list for realm authentication.
static struct sockaddr_in bindaddr
static unsigned int chan_idx
static struct ast_threadstorage check_auth_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_check_auth_buf , .custom_init = NULL , }
static struct ast_custom_function checksipdomain_function
static struct ast_cli_entry cli_sip []
 SIP Cli commands definition.
static struct ast_cli_entry cli_sip_do_history_deprecated = { .handler = sip_do_history_deprecated , .summary = "Enable/Disable SIP history" ,__VA_ARGS__ }
static const char config [] = "sip.conf"
static struct sockaddr_in debugaddr
static int default_expiry = DEFAULT_DEFAULT_EXPIRY
static struct ast_jb_conf default_jbconf
 Global jitterbuffer configuration - by default, jb is disabled.
static struct ast_tls_config default_tls_cfg
 Default TLS connection configuration.
static char * descrip_dtmfmode = " SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n"
static char * descrip_sipaddheader
ao2_containerdialogs
 Here we implement the container for dialogs (sip_pvt), defining generic wrapper functions to ease the transition from the current implementation (a single linked list) to a different container. In addition to a reference to the container, we need functions to lock/unlock the container and individual items, and functions to add/remove references to the individual items.
static struct _map_x_s dtmfstr []
 mapping between dtmf flags and strings
static time_t externexpire
static char externhost [MAXHOSTNAMELEN]
static struct sockaddr_in externip
 our external IP address/port for SIP sessions. externip.sin_addr is only set when we know we might be behind a NAT, and this is done using a variety of (mutually exclusive) ways from the config file:
static int externrefresh = 10
static struct _map_x_s faxecmodes []
static struct ast_haglobal_contact_ha = NULL
 Global list of addresses dynamic peers are not allowed to use.
static struct ast_jb_conf global_jbconf
static int hash_dialog_size = 563
static int hash_peer_size = 563
static int hash_user_size = 563
static struct _map_x_s insecurestr []
static struct sockaddr_in internip
 our (internal) default address/port to put in SIP/SDP messages internip is initialized picking a suitable address from one of the interfaces, and the same port number we bind to. It is used as the default address/port in SIP messages, and as the default address (but not port) in SDP messages.
static struct invstate2stringtable invitestate2string []
 Readable descriptions of device states.
static struct ast_halocaladdr
 List of local networks We store "localnet" addresses from the config file into an access list, marked as 'DENY', so the call to ast_apply_ha() will return AST_SENSE_DENY for 'local' addresses, and AST_SENSE_ALLOW for 'non local' (i.e. presumably public) addresses.
static char mandescr_show_peer []
static char mandescr_show_peers []
static char mandescr_show_registry []
 Manager Action SIPShowRegistry description.
static char mandescr_sipnotify []
static int max_expiry = DEFAULT_MAX_EXPIRY
static int min_expiry = DEFAULT_MIN_EXPIRY
static struct _map_x_s natmodes []
static const char notify_config [] = "sip_notify.conf"
static struct ast_confignotify_types = NULL
static int ourport_tcp
static int ourport_tls
ao2_containerpeers
 The peer list: Users, Peers and Friends.
ao2_containerpeers_by_ip
static struct _map_x_s referstatusstrings []
static struct ast_register_list regl
 The register list: Other SIP proxies we register with and place calls to.
static struct _map_x_s regstatestrings []
static struct ast_custom_function sip_header_function
static struct cfsip_methods sip_methods []
 The core structure to setup dialogs. We parse incoming messages by using structure and then route the messages according to the type.
static struct cfsip_options sip_options []
 List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly.
static struct ast_rtp_protocol sip_rtp
 Interface structure with callbacks used to connect to RTP module.
static struct ast_tcptls_session_args sip_tcp_desc
 The TCP server definition.
static struct ast_channel_tech sip_tech
 Definition of this channel for PBX channel registration.
static struct ast_channel_tech sip_tech_info
 This version of the sip channel tech has no send_digit_begin callback so that the core knows that the channel does not want DTMF BEGIN frames. The struct is initialized just before registering the channel driver, and is for use with channels using SIP INFO DTMF.
static struct ast_tls_config sip_tls_cfg
 Working TLS connection configuration.
static struct ast_tcptls_session_args sip_tls_desc
 The TCP/TLS server definition.
static struct ast_udptl_protocol sip_udptl
 Interface structure with callbacks used to connect to UDPTL module.
static struct ast_custom_function sipchaninfo_function
 Structure to declare a dialplan function: SIPCHANINFO.
static enum sip_debug_e sipdebug
static int sipdebug_text
 extra debugging for 'text' related events. At the moment this is set together with sip_debug_console.
ast_custom_function sippeer_function
 Structure to declare a dialplan function: SIPPEER.
static int sipsock = -1
 Main socket for SIP communication.
static struct _map_x_s stmodes []
 Report Peer status in character string.
static struct _map_x_s strefreshers []
static struct sockaddr_in stunaddr
static struct cfsubscription_types subscription_types []
 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 char * synopsis_dtmfmode = "Change the dtmfmode for a SIP call"
static char * synopsis_sipaddheader = "Add a SIP header to the outbound call"
static struct ao2_containerthreadt
 The table of TCP threads.
static struct ast_threadstorage ts_temp_pvt = { .once = PTHREAD_ONCE_INIT , .key_init = __init_ts_temp_pvt , .custom_init = temp_pvt_init , }


Detailed Description

Implementation of Session Initiation Protocol.

Author:
Mark Spencer <markster@digium.com>
See Also: Implementation of RFC 3261 - without S/MIME, and experimental TCP and TLS support Configuration file sip.conf

********** 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

VIA branch tag transaction checking

Transaction support

We need to test TCP sessions with SIP proxies and in regards to the SIP outbound specs.

Fix TCP/TLS handling in dialplan, SRV records, transfers and much more

Save TCP/TLS sessions in registry

Add TCP/TLS information to function SIPPEER and SIPCHANINFO

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".
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"

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

Outbound calls
Outbound calls are set up by the PBX through the sip_request_call() function. After that, they are activated by sip_call().
Hanging up
The PBX issues a hangup on both incoming and outgoing calls through the sip_hangup() function

Definition in file chan_sip.c.


Define Documentation

#define ALLOWED_METHODS   "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO"

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.

Definition at line 656 of file chan_sip.c.

Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), and transmit_reinvite_with_sdp().

#define append_history ( p,
event,
fmt,
args...   )     append_history_full(p, "%-15s " fmt, event, ## args)

Append to SIP dialog history.

Returns:
Always returns 0

Definition at line 2148 of file chan_sip.c.

Referenced by __sip_autodestruct(), __sip_reliable_xmit(), auto_congest(), build_reply_digest(), cb_extensionstate(), check_auth(), do_register_auth(), handle_invite_replaces(), handle_request_bye(), handle_request_do(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), handle_response_invite(), local_attended_transfer(), obproxy_get(), process_sdp(), retrans_pkt(), send_request(), send_response(), sip_cancel_destroy(), sip_fixup(), sip_hangup(), sip_new(), sip_park_thread(), sip_reregister(), sip_scheddestroy(), sip_set_rtp_peer(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_with_auth().

#define CALLERID_UNKNOWN   "Anonymous"

Definition at line 246 of file chan_sip.c.

Referenced by initreqprep().

#define CHECK_AUTH_BUF_INITLEN   256

Definition at line 11767 of file chan_sip.c.

Referenced by check_auth(), and transmit_fake_auth_response().

#define check_request_transport ( peer,
tmpl   ) 

generic function for determining if a correct transport is being used to contact a peer

this is done as a macro so that the "tmpl" var can be passed either a sip_request or a sip_peer

Definition at line 2055 of file chan_sip.c.

Referenced by create_addr_from_peer(), and register_verify().

#define DEC_CALL_LIMIT   0

Definition at line 857 of file chan_sip.c.

Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_hangup(), and update_call_counter().

#define DEC_CALL_RINGING   2

Definition at line 859 of file chan_sip.c.

Referenced by handle_response_invite(), and update_call_counter().

#define DEFAULT_ALLOW_EXT_DOM   TRUE

Allow external domains

Definition at line 704 of file chan_sip.c.

#define DEFAULT_ALLOWGUEST   TRUE

Definition at line 692 of file chan_sip.c.

#define DEFAULT_AUTOCREATEPEER   FALSE

Definition at line 708 of file chan_sip.c.

#define DEFAULT_CALLCOUNTER   FALSE

Definition at line 693 of file chan_sip.c.

#define DEFAULT_CALLERID   "asterisk"

Definition at line 690 of file chan_sip.c.

#define DEFAULT_COMPACTHEADERS   FALSE

Definition at line 695 of file chan_sip.c.

#define DEFAULT_CONTEXT   "default"

Definition at line 686 of file chan_sip.c.

#define DEFAULT_COS_AUDIO   5

Level 2 class of service for audio media

Definition at line 701 of file chan_sip.c.

#define DEFAULT_COS_SIP   4

Level 2 class of service for SIP signalling

Definition at line 700 of file chan_sip.c.

#define DEFAULT_COS_TEXT   5

Level 2 class of service for text media (T.140)

Definition at line 703 of file chan_sip.c.

#define DEFAULT_COS_VIDEO   6

Level 2 class of service for video media

Definition at line 702 of file chan_sip.c.

#define DEFAULT_DEFAULT_EXPIRY   120

Definition at line 223 of file chan_sip.c.

#define DEFAULT_EXPIRY   900

Expire slowly

Definition at line 240 of file chan_sip.c.

#define DEFAULT_FREQ_NOTOK   10 * 1000

Qualification: How often to check, if the host is down...

Definition at line 251 of file chan_sip.c.

#define DEFAULT_MAX_CALL_BITRATE   (384)

Max bitrate for video

Definition at line 712 of file chan_sip.c.

#define DEFAULT_MAX_EXPIRY   3600

Definition at line 225 of file chan_sip.c.

#define DEFAULT_MAX_FORWARDS   "70"

Definition at line 227 of file chan_sip.c.

Referenced by initreqprep(), reqprep(), and transmit_register().

#define DEFAULT_MAX_SE   1800

Session-Timer Default Session-Expires period (RFC 4028)

Definition at line 270 of file chan_sip.c.

#define DEFAULT_MAXMS   2000

Qualification: Must be faster than 2 seconds by default

Definition at line 249 of file chan_sip.c.

#define DEFAULT_MIN_EXPIRY   60

Definition at line 224 of file chan_sip.c.

#define DEFAULT_MIN_SE   90

Session-Timer Default Min-SE period (RFC 4028)

Definition at line 271 of file chan_sip.c.

#define DEFAULT_MOHINTERPRET   "default"

Definition at line 687 of file chan_sip.c.

#define DEFAULT_MOHSUGGEST   ""

Definition at line 688 of file chan_sip.c.

#define DEFAULT_NOTIFYMIME   "application/simple-message-summary"

Definition at line 691 of file chan_sip.c.

#define DEFAULT_NOTIFYRINGING   TRUE

Definition at line 706 of file chan_sip.c.

#define DEFAULT_PEDANTIC   FALSE

Definition at line 707 of file chan_sip.c.

#define DEFAULT_QUALIFY   FALSE

Definition at line 709 of file chan_sip.c.

#define DEFAULT_QUALIFYFREQ   60 * 1000

Qualification: How often to check for the host to be up

Definition at line 250 of file chan_sip.c.

#define DEFAULT_REALM   "asterisk"

Realm for HTTP digest authentication

Definition at line 705 of file chan_sip.c.

#define DEFAULT_REGEXTENONQUALIFY   FALSE

Definition at line 710 of file chan_sip.c.

#define DEFAULT_REGISTRATION_TIMEOUT   20

Definition at line 226 of file chan_sip.c.

#define DEFAULT_RETRANS   1000

How frequently to retransmit Default: 2 * 500 ms in RFC 3261

Definition at line 253 of file chan_sip.c.

#define DEFAULT_SDPOWNER   "root"

Default SDP username field in (o=) header unless re-defined in sip.conf

Definition at line 716 of file chan_sip.c.

#define DEFAULT_SDPSESSION   "Asterisk PBX"

Default SDP session name, (s=) header unless re-defined in sip.conf

Definition at line 715 of file chan_sip.c.

#define DEFAULT_SRVLOOKUP   TRUE

Recommended setting is ON

Definition at line 694 of file chan_sip.c.

#define DEFAULT_T1MIN   100

100 MS for minimal roundtrip time

Definition at line 711 of file chan_sip.c.

#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.

Definition at line 697 of file chan_sip.c.

#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.

Definition at line 696 of file chan_sip.c.

#define DEFAULT_TOS_TEXT   0

Text packets should be marked as XXXX XXXX, but the default is 0 to be compatible with previous versions.

Definition at line 699 of file chan_sip.c.

#define DEFAULT_TOS_VIDEO   0

Video packets should be marked as DSCP AF41, but the default is 0 to be compatible with previous versions.

Definition at line 698 of file chan_sip.c.

#define DEFAULT_TRANS_TIMEOUT   -1

Definition at line 259 of file chan_sip.c.

Referenced by __sip_autodestruct(), auto_congest(), cb_extensionstate(), check_auth(), check_pendings(), handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_response_invite(), handle_response_register(), receive_message(), sip_hangup(), sip_send_mwi_to_peer(), and transmit_fake_auth_response().

#define DEFAULT_USERAGENT   "Asterisk PBX"

Default Useragent: header unless re-defined in sip.conf

Definition at line 714 of file chan_sip.c.

#define DEFAULT_VMEXTEN   "asterisk"

Definition at line 689 of file chan_sip.c.

#define EXPIRY_GUARD_LIMIT   30

Below here, we use EXPIRY_GUARD_PCT instead of EXPIRY_GUARD_SECS

Definition at line 232 of file chan_sip.c.

Referenced by handle_response_register().

#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.

Definition at line 234 of file chan_sip.c.

Referenced by handle_response_register().

#define EXPIRY_GUARD_PCT   0.20

Percentage of expires timeout to use when below EXPIRY_GUARD_LIMIT

Definition at line 238 of file chan_sip.c.

Referenced by handle_response_register().

#define EXPIRY_GUARD_SECS   15

How long before expiry do we reregister

Definition at line 231 of file chan_sip.c.

Referenced by handle_response_register().

#define FALSE   0

Definition at line 203 of file chan_sip.c.

#define FINDALLDEVICES   (FINDUSERS | FINDPEERS)

Definition at line 215 of file chan_sip.c.

Referenced by check_peer_ok(), find_by_name(), sip_devicestate(), sip_peer_hold(), and update_call_counter().

#define FINDPEERS   (1 << 1)

Definition at line 214 of file chan_sip.c.

Referenced by _sip_qualify_peer(), _sip_show_peer(), check_peer_ok(), create_addr(), find_by_name(), function_sippeer(), register_verify(), sip_do_debug_peer(), sip_unregister(), st_get_mode(), st_get_refresher(), st_get_se(), and transmit_register().

#define FINDUSERS   (1 << 0)

Definition at line 213 of file chan_sip.c.

Referenced by check_peer_ok(), find_by_name(), and sip_show_user().

#define FORMAT   "%-15.15s %-15.15s %-15.15s %-15.15s %-3.3s %-3.3s %-15.15s %-10.10s\n"

Definition at line 15378 of file chan_sip.c.

#define FORMAT   "%-15.15s %-11.11s %-8.8s %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.6u %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.6u\n"

Definition at line 15378 of file chan_sip.c.

#define FORMAT   "%-30.30s %-6.6s %-12.12s %8d %-20.20s %-25.25s\n"

Definition at line 15378 of file chan_sip.c.

#define FORMAT   "%-40.40s %-20.20s %-16.16s\n"

Definition at line 15378 of file chan_sip.c.

#define FORMAT   "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %s\n"

Definition at line 15378 of file chan_sip.c.

#define FORMAT   "%-25.25s %-15.15s %-15.15s %-15.15s %-5.5s%-10.10s\n"

Definition at line 15378 of file chan_sip.c.

#define FORMAT   "%-30.30s %-6d %-9.9s %-6.6s\n"

Definition at line 15378 of file chan_sip.c.

#define FORMAT   "%-25.25s %-15.15s %-15.15s \n"

Definition at line 15378 of file chan_sip.c.

#define FORMAT2   "%-15.15s %-15.15s %-15.15s %-15.15s %-7.7s %-15.15s %-6.6s\n"

Definition at line 15377 of file chan_sip.c.

#define FORMAT2   "%-15.15s %-11.11s %-8.8s %-10.10s %-10.10s ( %%) %-6.6s %-10.10s %-10.10s ( %%) %-6.6s\n"

Definition at line 15377 of file chan_sip.c.

#define FORMAT2   "%-30.30s %-6.6s %-12.12s %8.8s %-20.20s %-25.25s\n"

Definition at line 15377 of file chan_sip.c.

#define FORMAT2   "%-25.25s %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %s\n"

Definition at line 15377 of file chan_sip.c.

#define FORMAT2   "%-30.30s %3.6s %9.9s %6.6s\n"

Definition at line 15377 of file chan_sip.c.

#define FORMAT2   "%-25.25s %-15.15s %-15.15s \n"

Definition at line 15377 of file chan_sip.c.

#define FORMAT3   "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6s\n"

Definition at line 15376 of file chan_sip.c.

Referenced by sip_show_channels().

#define FORMAT4   "%-15.15s %-15.15s %-15.15s %-15.15s %-13.13s %-15.15s %-10.10s %-6.6d\n"

Definition at line 15375 of file chan_sip.c.

Referenced by show_channels_cb().

#define FROMDOMAIN_INVALID   "anonymous.invalid"

Definition at line 247 of file chan_sip.c.

Referenced by initreqprep().

#define INC_CALL_LIMIT   1

Definition at line 858 of file chan_sip.c.

Referenced by handle_request_invite(), and update_call_counter().

#define INC_CALL_RINGING   3

Definition at line 860 of file chan_sip.c.

Referenced by sip_call(), and update_call_counter().

#define INITIAL_CSEQ   101

our initial sip sequence number

Definition at line 268 of file chan_sip.c.

Referenced by sip_alloc(), sip_register(), and transmit_response_using_temp().

#define IS_SIP_TECH (  )     ((t) == &sip_tech || (t) == &sip_tech_info)

Definition at line 2372 of file chan_sip.c.

Referenced by acf_channel_read(), func_header_read(), function_sipchaninfo_read(), handle_request_bye(), sip_dtmfmode(), and sip_hangup().

#define MAX_AUTHTRIES   3

Try authentication three times, then fail

Definition at line 261 of file chan_sip.c.

Referenced by handle_response(), handle_response_invite(), and handle_response_register().

#define MAX_HISTORY_ENTRIES   50

Max entires in the history list for a sip_pvt

Definition at line 1409 of file chan_sip.c.

Referenced by append_history_va().

#define MAX_RETRANS   6

Try only 6 times for retransmissions, a total of 7 transmissions

Definition at line 254 of file chan_sip.c.

#define NO_RTP   0

Definition at line 290 of file chan_sip.c.

#define NOT_SUPPORTED   0

Definition at line 574 of file chan_sip.c.

#define PROVIS_KEEPALIVE_TIMEOUT   60000

How long to wait before retransmitting a provisional response (rfc 3261 13.3.1.1)

Definition at line 260 of file chan_sip.c.

Referenced by send_provisional_keepalive_full(), and update_provisional_keepalive().

#define REQ_OFFSET_TO_STR ( req,
offset   )     ((req)->data->str + ((req)->offset))

Definition at line 923 of file chan_sip.c.

Referenced by __get_header(), _sip_tcp_helper_thread(), find_sdp(), get_body(), get_destination(), get_msg_text(), get_sdp_iterate(), get_sdp_line(), handle_incoming(), handle_request_do(), handle_request_invite(), reqprep(), and send_response().

#define RTP   1

Definition at line 289 of file chan_sip.c.

#define SDP_MAX_RTPMAP_CODECS   32

Maximum number of codecs allowed in received SDP

Definition at line 273 of file chan_sip.c.

Referenced by process_sdp_a_audio(), process_sdp_a_text(), and process_sdp_a_video().

#define SDP_SAMPLE_RATE (  )     8000

Note:
G.722 actually is supposed to specified as 8 kHz, even though it is really 16 kHz. Update this macro for other formats as they are added in the future.

Definition at line 9368 of file chan_sip.c.

Referenced by add_sdp().

#define SIP_CALL_LIMIT   (1 << 7)

D: Call limit enforced for this call

Definition at line 1006 of file chan_sip.c.

Referenced by check_peer_ok(), create_addr_from_peer(), and update_call_counter().

#define SIP_CAN_REINVITE   (1 << 20)

DP: allow peers to be reinvited to send media directly p2p

Definition at line 1034 of file chan_sip.c.

Referenced by _sip_show_peer(), handle_common_options(), sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), and sip_get_vrtp_peer().

#define SIP_CAN_REINVITE_NAT   (2 << 20)

DP: allow media reinvite when new peer is behind NAT

Definition at line 1035 of file chan_sip.c.

Referenced by handle_common_options(), sip_get_rtp_peer(), and sip_set_rtp_peer().

#define SIP_DEFER_BYE_ON_TRANSFER   (1 << 10)

D: Do not hangup at first ast_hangup

Definition at line 1009 of file chan_sip.c.

Referenced by handle_invite_replaces(), handle_request_refer(), local_attended_transfer(), sip_hangup(), and sip_set_rtp_peer().

#define SIP_DTMF   (7 << 15)

DP: DTMF Support: five settings, uses three bits

Definition at line 1017 of file chan_sip.c.

Referenced by _sip_show_peer(), check_peer_ok(), create_addr_from_peer(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), sip_dtmfmode(), sip_new(), sip_rtp_read(), sip_senddigit_begin(), sip_senddigit_end(), sip_show_channel(), sip_show_settings(), and transmit_info_with_digit().

#define SIP_DTMF_AUTO   (3 << 15)

DP: DTMF Support: AUTO switch between rfc2833 and in-band DTMF

Definition at line 1021 of file chan_sip.c.

Referenced by check_peer_ok(), create_addr_from_peer(), handle_common_options(), process_sdp(), sip_alloc(), and sip_new().

#define SIP_DTMF_INBAND   (1 << 15)

DP: DTMF Support: Inband audio, only for ULAW/ALAW - "inband"

Definition at line 1019 of file chan_sip.c.

Referenced by handle_common_options(), process_sdp(), sip_dtmfmode(), sip_new(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().

#define SIP_DTMF_INFO   (2 << 15)

DP: DTMF Support: SIP Info messages - "info"

Definition at line 1020 of file chan_sip.c.

Referenced by handle_common_options(), sip_dtmfmode(), sip_new(), and sip_senddigit_end().

#define SIP_DTMF_RFC2833   (0 << 15)

DP: DTMF Support: RTP DTMF - "rfc2833"

Definition at line 1018 of file chan_sip.c.

Referenced by check_peer_ok(), create_addr_from_peer(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), sip_dtmfmode(), sip_rtp_read(), sip_senddigit_begin(), and sip_senddigit_end().

#define SIP_DTMF_SHORTINFO   (4 << 15)

DP: DTMF Support: SIP Info messages - "info" - short variant

Definition at line 1022 of file chan_sip.c.

Referenced by handle_common_options(), sip_dtmfmode(), sip_new(), sip_senddigit_end(), and transmit_info_with_digit().

#define SIP_FLAGS_TO_COPY

Value:

Flags to copy from peer/user to dialog.

Definition at line 1054 of file chan_sip.c.

Referenced by check_peer_ok(), create_addr_from_peer(), set_peer_defaults(), sip_alloc(), and sip_poke_peer().

#define SIP_G726_NONSTANDARD   (1 << 31)

DP: Use non-standard packing for G726-32 data

Definition at line 1051 of file chan_sip.c.

Referenced by add_codec_to_sdp(), handle_common_options(), and process_sdp_a_audio().

#define SIP_GOTREFER   (1 << 6)

D: Got a refer?

Definition at line 1005 of file chan_sip.c.

Referenced by handle_request_refer(), local_attended_transfer(), sip_set_rtp_peer(), and sip_set_udptl_peer().

#define SIP_INC_COUNT   (1 << 8)

D: Did this dialog increment the counter of in-use calls?

Definition at line 1007 of file chan_sip.c.

Referenced by __sip_destroy(), handle_request_cancel(), sip_hangup(), and update_call_counter().

#define SIP_INC_RINGING   (1 << 9)

D: Did this connection increment the counter of in-use calls?

Definition at line 1008 of file chan_sip.c.

Referenced by update_call_counter().

#define SIP_INSECURE   (3 << 23)

DP: three settings, uses two bits

Definition at line 1039 of file chan_sip.c.

Referenced by _sip_show_peer(), and handle_common_options().

#define SIP_INSECURE_INVITE   (1 << 24)

DP: don't require authentication for incoming INVITEs

Definition at line 1042 of file chan_sip.c.

Referenced by check_peer_ok(), and set_insecure_flags().

#define SIP_INSECURE_NONE   (0 << 23)

DP: secure mode

Definition at line 1040 of file chan_sip.c.

#define SIP_INSECURE_PORT   (1 << 23)

DP: don't require matching port for incoming requests

Definition at line 1041 of file chan_sip.c.

Referenced by find_peer(), get_insecure_variable_from_config(), peer_ipcmp_cb(), and set_insecure_flags().

#define SIP_MAX_HEADERS   64

Max amount of SIP headers to read

Definition at line 263 of file chan_sip.c.

Referenced by add_header(), and parse_request().

#define SIP_MAX_LINES   256

Max amount of lines in SIP attachment (like SDP)

Definition at line 264 of file chan_sip.c.

Referenced by add_line(), and parse_request().

#define SIP_MAX_PACKET   4096

Also from RFC 3261 (2543), should sub headers tho

Definition at line 265 of file chan_sip.c.

#define SIP_MIN_PACKET   1024

Initialize size of memory to allocate for packets

Definition at line 266 of file chan_sip.c.

Referenced by _sip_tcp_helper_thread(), init_req(), init_resp(), and sipsock_read().

#define SIP_NAT   (3 << 18)

DP: four settings, uses two bits

Definition at line 1025 of file chan_sip.c.

Referenced by _sip_show_peer(), build_via(), copy_via_headers(), create_addr(), create_addr_from_peer(), handle_common_options(), process_sdp(), register_verify(), sip_alloc(), sip_nat_mode(), sip_real_dst(), sip_show_channel(), sip_show_settings(), sip_show_users(), and transmit_response_using_temp().

#define SIP_NAT_ALWAYS   (3 << 18)

DP: NAT Both ROUTE and RFC3581

Definition at line 1029 of file chan_sip.c.

Referenced by copy_via_headers(), and handle_common_options().

#define SIP_NAT_NEVER   (0 << 18)

DP: No nat support

Definition at line 1026 of file chan_sip.c.

Referenced by handle_common_options().

#define SIP_NAT_RFC3581   (1 << 18)

DP: NAT RFC3581

Definition at line 1027 of file chan_sip.c.

Referenced by build_via(), copy_via_headers(), and handle_common_options().

#define SIP_NAT_ROUTE   (2 << 18)

DP: NAT Only ROUTE

Definition at line 1028 of file chan_sip.c.

Referenced by _sip_show_peers(), build_peer(), check_peer_ok(), check_user_full(), create_addr(), create_addr_from_peer(), handle_common_options(), parse_register_contact(), send_request(), set_address_from_contact(), sip_alloc(), sip_nat_mode(), sip_real_dst(), and transmit_response_using_temp().

#define SIP_NEEDREINVITE   (1 << 4)

D: Do we need to send another reinvite?

Definition at line 1003 of file chan_sip.c.

Referenced by check_pendings(), interpret_t38_parameters(), sip_hangup(), sip_reinvite_retry(), sip_sendhtml(), sip_set_rtp_peer(), and sip_set_udptl_peer().

#define SIP_OPT_100REL   (1 << 1)

Definition at line 578 of file chan_sip.c.

#define SIP_OPT_EARLY_SESSION   (1 << 3)

Definition at line 580 of file chan_sip.c.

#define SIP_OPT_EVENTLIST   (1 << 11)

Definition at line 588 of file chan_sip.c.

#define SIP_OPT_FROMCHANGE   (1 << 17)

Definition at line 594 of file chan_sip.c.

#define SIP_OPT_GRUU   (1 << 12)

Definition at line 589 of file chan_sip.c.

#define SIP_OPT_HISTINFO   (1 << 15)

Definition at line 592 of file chan_sip.c.

#define SIP_OPT_JOIN   (1 << 4)

Definition at line 581 of file chan_sip.c.

#define SIP_OPT_NOREFERSUB   (1 << 14)

Definition at line 591 of file chan_sip.c.

#define SIP_OPT_PATH   (1 << 5)

Definition at line 582 of file chan_sip.c.

#define SIP_OPT_PRECONDITION   (1 << 7)

Definition at line 584 of file chan_sip.c.

#define SIP_OPT_PREF   (1 << 6)

Definition at line 583 of file chan_sip.c.

#define SIP_OPT_PRIVACY   (1 << 8)

Definition at line 585 of file chan_sip.c.

#define SIP_OPT_RECLISTINV   (1 << 18)

Definition at line 595 of file chan_sip.c.

#define SIP_OPT_RECLISTSUB   (1 << 19)

Definition at line 596 of file chan_sip.c.

#define SIP_OPT_REPLACES   (1 << 0)

Definition at line 577 of file chan_sip.c.

Referenced by handle_request_invite().

#define SIP_OPT_RESPRIORITY   (1 << 16)

Definition at line 593 of file chan_sip.c.

#define SIP_OPT_SDP_ANAT   (1 << 9)

Definition at line 586 of file chan_sip.c.

#define SIP_OPT_SEC_AGREE   (1 << 10)

Definition at line 587 of file chan_sip.c.

#define SIP_OPT_TARGET_DIALOG   (1 << 13)

Definition at line 590 of file chan_sip.c.

#define SIP_OPT_TIMER   (1 << 2)

Definition at line 579 of file chan_sip.c.

Referenced by handle_request_invite().

#define SIP_OPT_UNKNOWN   (1 << 20)

Definition at line 597 of file chan_sip.c.

Referenced by parse_sip_options().

#define SIP_OUTGOING   (1 << 0)

D: Direction of the last transaction in this dialog

Definition at line 1000 of file chan_sip.c.

Referenced by handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), manager_sipnotify(), reqprep(), respprep(), sip_call(), sip_cli_notify(), sip_hangup(), sip_indicate(), sip_poke_peer(), sip_send_mwi_to_peer(), sip_show_channel(), sip_write(), transmit_refer(), transmit_register(), transmit_reinvite_with_sdp(), and transmit_response_with_sdp().

#define SIP_PAGE2_ALLOWOVERLAP   (1 << 17)

DP: Allow overlap dialing ?

Definition at line 1074 of file chan_sip.c.

Referenced by _sip_show_peer(), get_destination(), handle_common_options(), handle_request_invite(), and sip_show_settings().

#define SIP_PAGE2_ALLOWSUBSCRIBE   (1 << 16)

GP: Allow subscriptions from this peer?

Definition at line 1073 of file chan_sip.c.

Referenced by _sip_show_peer(), build_peer(), handle_common_options(), handle_request_subscribe(), and sip_show_settings().

#define SIP_PAGE2_BUGGY_MWI   (1 << 26)

DP: Buggy CISCO MWI fix

Definition at line 1089 of file chan_sip.c.

Referenced by handle_common_options(), and transmit_notify_with_mwi().

#define SIP_PAGE2_CALL_ONHOLD   (3 << 23)

D: Call hold states:

Definition at line 1083 of file chan_sip.c.

Referenced by __sip_destroy(), add_sdp(), check_rtp_timeout(), handle_request_cancel(), process_sdp(), show_channels_cb(), sip_hangup(), and update_call_counter().

#define SIP_PAGE2_CALL_ONHOLD_ACTIVE   (1 << 23)

D: Active hold

Definition at line 1084 of file chan_sip.c.

Referenced by process_sdp().

#define SIP_PAGE2_CALL_ONHOLD_INACTIVE   (3 << 23)

D: Inactive hold

Definition at line 1086 of file chan_sip.c.

Referenced by add_sdp(), and process_sdp().

#define SIP_PAGE2_CALL_ONHOLD_ONEDIR   (2 << 23)

D: One directional hold

Definition at line 1085 of file chan_sip.c.

Referenced by add_sdp(), and process_sdp().

#define SIP_PAGE2_DIALOG_ESTABLISHED   (1 << 27)

29: Has a dialog been established?

Definition at line 1090 of file chan_sip.c.

Referenced by find_call_cb(), handle_request_bye(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), and sip_answer().

#define SIP_PAGE2_FAX_DETECT   (1 << 28)

DP: Fax Detection support

Definition at line 1091 of file chan_sip.c.

Referenced by handle_common_options(), sip_new(), sip_read(), and sip_rtp_read().

#define SIP_PAGE2_FLAGS_TO_COPY

Value:

Definition at line 1096 of file chan_sip.c.

Referenced by check_peer_ok(), create_addr_from_peer(), set_peer_defaults(), sip_alloc(), and sip_poke_peer().

#define SIP_PAGE2_HAVEPEERCONTEXT   (1 << 3)

Definition at line 1066 of file chan_sip.c.

Referenced by build_peer(), and get_destination().

#define SIP_PAGE2_IGNORESDPVERSION   (1 << 19)

GDP: Ignore the SDP session version number we receive and treat all sessions as new

Definition at line 1076 of file chan_sip.c.

Referenced by _sip_show_peer(), handle_common_options(), process_sdp_o(), sip_show_settings(), and sip_show_user().

#define SIP_PAGE2_REGISTERTRYING   (1 << 29)

DP: Send 100 Trying on REGISTER attempts

Definition at line 1092 of file chan_sip.c.

Referenced by _sip_show_peer(), build_peer(), and register_verify().

#define SIP_PAGE2_RFC2833_COMPENSATE   (1 << 25)

DP: Compensate for buggy RFC2833 implementations

Definition at line 1088 of file chan_sip.c.

Referenced by create_addr_from_peer(), handle_common_options(), handle_request_invite(), process_sdp(), sip_alloc(), and sip_show_settings().

#define SIP_PAGE2_RPORT_PRESENT   (1 << 10)

Was rport received in the Via header?

Definition at line 1070 of file chan_sip.c.

Referenced by check_user_full(), and check_via().

#define SIP_PAGE2_RTAUTOCLEAR   (1 << 2)

GP: Should we clean memory from peers after expiry?

Definition at line 1065 of file chan_sip.c.

Referenced by expire_register().

#define SIP_PAGE2_RTCACHEFRIENDS   (1 << 0)

GP: Should we keep RT objects in memory for extended time?

Definition at line 1064 of file chan_sip.c.

Referenced by build_peer(), parse_register_contact(), reload_config(), sip_prune_realtime(), sip_show_settings(), and update_peer().

#define SIP_PAGE2_STATECHANGEQUEUE   (1 << 9)

D: Unsent state pending change exists

Definition at line 1068 of file chan_sip.c.

Referenced by cb_extensionstate(), handle_response(), and handle_response_notify().

#define SIP_PAGE2_SUBSCRIBEMWIONLY   (1 << 18)

GP: Only issue MWI notification if subscribed to

Definition at line 1075 of file chan_sip.c.

Referenced by build_peer(), handle_request_subscribe(), register_verify(), and sip_send_mwi_to_peer().

#define SIP_PAGE2_T38SUPPORT   (3 << 20)

GDP: T.38 Fax Support

Definition at line 1078 of file chan_sip.c.

Referenced by _sip_show_peer(), check_peer_ok(), create_addr_from_peer(), handle_request_invite(), handle_t38_options(), interpret_t38_parameters(), set_t38_capabilities(), sip_alloc(), sip_queryoption(), and sip_show_settings().

#define SIP_PAGE2_T38SUPPORT_UDPTL   (1 << 20)

GDP: T.38 Fax Support (no error correction)

Definition at line 1079 of file chan_sip.c.

Referenced by handle_t38_options(), and set_t38_capabilities().

#define SIP_PAGE2_T38SUPPORT_UDPTL_FEC   (2 << 20)

GDP: T.38 Fax Support (FEC error correction)

Definition at line 1080 of file chan_sip.c.

Referenced by handle_t38_options(), and set_t38_capabilities().

#define SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY   (3 << 20)

GDP: T.38 Fax Support (redundancy error correction)

Definition at line 1081 of file chan_sip.c.

Referenced by handle_t38_options(), and set_t38_capabilities().

#define SIP_PAGE2_TEXTSUPPORT   (1 << 15)

GDP: Global text enable

Definition at line 1072 of file chan_sip.c.

Referenced by _sip_show_peer(), _sip_show_peers(), check_peer_ok(), create_addr_from_peer(), handle_common_options(), sip_alloc(), and sip_show_settings().

#define SIP_PAGE2_UDPTL_DESTINATION   (1 << 30)

DP: Use source IP of RTP as destination if NAT is enabled

Definition at line 1093 of file chan_sip.c.

Referenced by handle_t38_options(), and process_sdp().

#define SIP_PAGE2_VIDEOSUPPORT   (1 << 14)

DP: Video supported if offered?

Definition at line 1071 of file chan_sip.c.

Referenced by _sip_show_peer(), _sip_show_peers(), check_peer_ok(), create_addr_from_peer(), handle_common_options(), sip_alloc(), sip_new(), and sip_show_settings().

#define SIP_PAGE2_VIDEOSUPPORT_ALWAYS   (1 << 31)

DP: Always set up video, even if endpoints don't support it

Definition at line 1094 of file chan_sip.c.

Referenced by check_peer_ok(), create_addr_from_peer(), and handle_common_options().

#define SIP_PENDINGBYE   (1 << 5)

D: Need to send bye after we ack?

Definition at line 1004 of file chan_sip.c.

Referenced by check_pendings(), handle_response_invite(), interpret_t38_parameters(), register_verify(), sip_hangup(), sip_sendhtml(), sip_set_rtp_peer(), and sip_set_udptl_peer().

#define SIP_PROG_INBAND   (3 << 25)

DP: three settings, uses two bits

Definition at line 1045 of file chan_sip.c.

Referenced by handle_common_options(), sip_indicate(), and sip_show_settings().

#define SIP_PROG_INBAND_NEVER   (0 << 25)

Definition at line 1046 of file chan_sip.c.

Referenced by sip_indicate(), and sip_show_settings().

#define SIP_PROG_INBAND_NO   (1 << 25)

Definition at line 1047 of file chan_sip.c.

Referenced by handle_common_options(), and sip_show_settings().

#define SIP_PROG_INBAND_YES   (2 << 25)

Definition at line 1048 of file chan_sip.c.

Referenced by handle_common_options(), and sip_indicate().

#define SIP_PROGRESS_SENT   (1 << 3)

D: Have sent 183 message progress

Definition at line 1002 of file chan_sip.c.

Referenced by sip_indicate(), and sip_write().

#define SIP_PROMISCREDIR   (1 << 11)

DP: Promiscuous redirection

Definition at line 1011 of file chan_sip.c.

Referenced by _sip_show_peer(), handle_common_options(), parse_moved_contact(), sip_show_channel(), and sip_show_settings().

#define sip_pvt_lock (  )     ao2_lock(x)

Definition at line 1421 of file chan_sip.c.

Referenced by __sip_ack(), auto_congest(), cb_extensionstate(), check_rtp_timeout(), complete_sipch(), find_call(), get_sip_pvt_byid_locked(), handle_invite_replaces(), handle_request_bye(), handle_request_invite(), handle_request_subscribe(), proc_session_timer(), retrans_pkt(), scheduler_process_request_queue(), sip_answer(), sip_dtmfmode(), sip_fixup(), sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), sip_hangup(), sip_indicate(), sip_new(), sip_park(), sip_queryoption(), sip_read(), sip_reg_timeout(), sip_reinvite_retry(), sip_request_call(), sip_senddigit_begin(), sip_senddigit_end(), sip_set_rtp_peer(), sip_set_udptl_peer(), sip_show_channel(), sip_show_history(), sip_transfer(), sip_write(), and update_call_counter().

#define sip_pvt_trylock (  )     ao2_trylock(x)

Definition at line 1422 of file chan_sip.c.

Referenced by dialog_needdestroy(), find_call(), and sip_hangup().

#define sip_pvt_unlock (  )     ao2_unlock(x)

Definition at line 1423 of file chan_sip.c.

Referenced by __sip_ack(), auto_congest(), cb_extensionstate(), check_rtp_timeout(), complete_sipch(), dialog_needdestroy(), get_sip_pvt_byid_locked(), handle_invite_replaces(), handle_request_bye(), handle_request_do(), handle_request_invite(), handle_request_subscribe(), local_attended_transfer(), proc_session_timer(), retrans_pkt(), scheduler_process_request_queue(), sip_answer(), sip_dtmfmode(), sip_fixup(), sip_get_rtp_peer(), sip_get_trtp_peer(), sip_get_udptl_peer(), sip_get_vrtp_peer(), sip_hangup(), sip_indicate(), sip_new(), sip_park(), sip_queryoption(), sip_read(), sip_reg_timeout(), sip_reinvite_retry(), sip_request_call(), sip_senddigit_begin(), sip_senddigit_end(), sip_set_rtp_peer(), sip_set_udptl_peer(), sip_show_channel(), sip_show_history(), sip_transfer(), sip_write(), and update_call_counter().

#define SIP_REINVITE   (7 << 20)

DP: four settings, uses three bits

Definition at line 1032 of file chan_sip.c.

Referenced by handle_common_options().

#define SIP_REINVITE_NONE   (0 << 20)

DP: no reinvite allowed

Definition at line 1033 of file chan_sip.c.

#define SIP_REINVITE_UPDATE   (4 << 20)

DP: use UPDATE (RFC3311) when reinviting this peer

Definition at line 1036 of file chan_sip.c.

Referenced by handle_common_options(), and transmit_reinvite_with_sdp().

#define SIP_RESERVED   ";/?:@&=+$,# "

Definition at line 219 of file chan_sip.c.

#define SIP_RINGING   (1 << 2)

D: Have sent 180 ringing

Definition at line 1001 of file chan_sip.c.

Referenced by sip_indicate().

#define SIP_SENDRPID   (1 << 29)

DP: Remote Party-ID Support

Definition at line 1050 of file chan_sip.c.

Referenced by _sip_show_peer(), handle_common_options(), and initreqprep().

#define SIP_TIMER_T1   500

Definition at line 255 of file chan_sip.c.

#define SIP_TRANS_TIMEOUT   64 * SIP_TIMER_T1

SIP request timeout (rfc 3261) 64*T1

Todo:
Use known T1 for timeout (peerpoke)

Definition at line 256 of file chan_sip.c.

Referenced by manager_sipnotify(), sip_cli_notify(), and sip_sipredirect().

#define SIP_TRUSTRPID   (1 << 12)

DP: Trust RPID headers?

Definition at line 1012 of file chan_sip.c.

Referenced by _sip_show_peer(), handle_common_options(), and replace_cid().

#define SIP_USECLIENTCODE   (1 << 14)

DP: Trust X-ClientCode info message

Definition at line 1014 of file chan_sip.c.

Referenced by handle_common_options(), handle_request_info(), and sip_show_settings().

#define SIP_USEREQPHONE   (1 << 13)

DP: Add user=phone to numeric URI. Default off

Definition at line 1013 of file chan_sip.c.

Referenced by _sip_show_peer(), build_peer(), initreqprep(), and sip_show_settings().

#define SIPBUFSIZE   512

Definition at line 210 of file chan_sip.c.

Referenced by add_route(), add_sdp(), extract_uri(), handle_request_refer(), initreqprep(), parse_moved_contact(), parse_ok_contact(), parse_register_contact(), process_sdp(), respprep(), show_channels_cb(), sip_call(), sip_new(), sip_show_channel(), sip_show_settings(), transmit_invite(), and transmit_notify_with_sipfrag().

#define STANDARD_SIP_PORT   5060

Standard SIP unsecure port for UDP and TCP from RFC 3261. DO NOT CHANGE THIS.

Definition at line 666 of file chan_sip.c.

Referenced by __set_address_from_contact(), build_peer(), check_via(), create_addr(), manager_show_registry(), parse_register_contact(), proxy_allocate(), reload_config(), set_destination(), set_peer_defaults(), sip_parse_host(), sip_show_registry(), sip_standard_port(), and transmit_register().

#define STANDARD_TLS_PORT   5061

Standard SIP TLS port for sips: from RFC 3261. DO NOT CHANGE THIS.

Definition at line 668 of file chan_sip.c.

Referenced by __set_address_from_contact(), build_peer(), create_addr(), parse_register_contact(), reload_config(), sip_parse_host(), and sip_standard_port().

#define SUPPORTED   1

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

Definition at line 573 of file chan_sip.c.

#define SUPPORTED_EXTENSIONS   "replaces, timer"

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.

Definition at line 663 of file chan_sip.c.

Referenced by respprep(), transmit_invite(), transmit_notify_with_sipfrag(), transmit_refer(), and transmit_reinvite_with_sdp().

#define TRUE   1

Definition at line 207 of file chan_sip.c.

#define UNLINK ( element,
head,
prev   ) 

some list management macros.

Definition at line 1888 of file chan_sip.c.

Referenced by __sip_ack(), handle_request_cancel(), and retrans_pkt().

#define XMIT_ERROR   -2

Definition at line 217 of file chan_sip.c.

Referenced by __sip_reliable_xmit(), __sip_xmit(), handle_response_invite(), retrans_pkt(), sip_call(), sip_poke_peer(), and sip_tcptls_write().


Enumeration Type Documentation

enum can_create_dialog

States whether a SIP message can create a dialog in Asterisk.

Enumerator:
CAN_NOT_CREATE_DIALOG 
CAN_CREATE_DIALOG 
CAN_CREATE_DIALOG_UNSUPPORTED_METHOD 

Definition at line 496 of file chan_sip.c.

enum check_auth_result

Authentication result from check_auth* functions.

Enumerator:
AUTH_DONT_KNOW  no result, need to check further
AUTH_SUCCESSFUL 
AUTH_CHALLENGE_SENT 
AUTH_SECRET_FAILED 
AUTH_USERNAME_MISMATCH 
AUTH_NOT_FOUND  returned by register_verify
AUTH_FAKE_AUTH 
AUTH_UNKNOWN_DOMAIN 
AUTH_PEER_NOT_DYNAMIC 
AUTH_ACL_FAILED 
AUTH_BAD_TRANSPORT 

Definition at line 397 of file chan_sip.c.

00397                        {
00398    AUTH_DONT_KNOW = -100,  /*!< no result, need to check further */
00399       /* XXX maybe this is the same as AUTH_NOT_FOUND */
00400 
00401    AUTH_SUCCESSFUL = 0,
00402    AUTH_CHALLENGE_SENT = 1,
00403    AUTH_SECRET_FAILED = -1,
00404    AUTH_USERNAME_MISMATCH = -2,
00405    AUTH_NOT_FOUND = -3, /*!< returned by register_verify */
00406    AUTH_FAKE_AUTH = -4,
00407    AUTH_UNKNOWN_DOMAIN = -5,
00408    AUTH_PEER_NOT_DYNAMIC = -6,
00409    AUTH_ACL_FAILED = -7,
00410    AUTH_BAD_TRANSPORT = -8,
00411 };

enum domain_mode

Modes for SIP domain handling in the PBX.

Enumerator:
SIP_DOMAIN_AUTO  This domain is auto-configured
SIP_DOMAIN_CONFIG  This domain is from configuration

Definition at line 954 of file chan_sip.c.

00954                  {
00955    SIP_DOMAIN_AUTO,     /*!< This domain is auto-configured */
00956    SIP_DOMAIN_CONFIG,      /*!< This domain is from configuration */
00957 };

enum invitestates

States for the INVITE transaction, not the dialog.

Note:
this is for the INVITE that sets up the dialog
Enumerator:
INV_NONE  No state at all, maybe not an INVITE dialog
INV_CALLING  Invite sent, no answer
INV_PROCEEDING  We got/sent 1xx message
INV_EARLY_MEDIA  We got 18x message with to-tag back
INV_COMPLETED  Got final response with error. Wait for ACK, then CONFIRMED
INV_CONFIRMED  Confirmed response - we've got an ack (Incoming calls only)
INV_TERMINATED  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  Transaction cancelled by client or server in non-terminated state

Definition at line 310 of file chan_sip.c.

00310                   {
00311    INV_NONE = 0,          /*!< No state at all, maybe not an INVITE dialog */
00312    INV_CALLING = 1,  /*!< Invite sent, no answer */
00313    INV_PROCEEDING = 2,  /*!< We got/sent 1xx message */
00314    INV_EARLY_MEDIA = 3,    /*!< We got 18x message with to-tag back */
00315    INV_COMPLETED = 4,   /*!< Got final response with error. Wait for ACK, then CONFIRMED */
00316    INV_CONFIRMED = 5,   /*!< Confirmed response - we've got an ack (Incoming calls only) */
00317    INV_TERMINATED = 6,  /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done 
00318                  The only way out of this is a BYE from one side */
00319    INV_CANCELLED = 7,   /*!< Transaction cancelled by client or server in non-terminated state */
00320 };

enum media_type

Enumerator:
SDP_AUDIO 
SDP_VIDEO 
SDP_IMAGE 
SDP_TEXT 

Definition at line 7390 of file chan_sip.c.

07390                 {
07391    SDP_AUDIO,
07392    SDP_VIDEO,
07393    SDP_IMAGE,
07394    SDP_TEXT,
07395 };

enum parse_register_result

Enumerator:
PARSE_REGISTER_DENIED 
PARSE_REGISTER_FAILED 
PARSE_REGISTER_UPDATE 
PARSE_REGISTER_QUERY 

Definition at line 348 of file chan_sip.c.

enum referstatus

Parameters to know status of transfer.

Enumerator:
REFER_IDLE  No REFER is in progress
REFER_SENT  Sent REFER to transferee
REFER_RECEIVED  Received REFER from transferrer
REFER_CONFIRMED  Refer confirmed with a 100 TRYING (unused)
REFER_ACCEPTED  Accepted by transferee
REFER_RINGING  Target Ringing
REFER_200OK  Answered by transfer target
REFER_FAILED  REFER declined - go on
REFER_NOAUTH  We had no auth for REFER

Definition at line 1141 of file chan_sip.c.

01141                  {
01142    REFER_IDLE,                    /*!< No REFER is in progress */
01143    REFER_SENT,                    /*!< Sent REFER to transferee */
01144    REFER_RECEIVED,                /*!< Received REFER from transferrer */
01145    REFER_CONFIRMED,               /*!< Refer confirmed with a 100 TRYING (unused) */
01146    REFER_ACCEPTED,                /*!< Accepted by transferee */
01147    REFER_RINGING,                 /*!< Target Ringing */
01148    REFER_200OK,                   /*!< Answered by transfer target */
01149    REFER_FAILED,                  /*!< REFER declined - go on */
01150    REFER_NOAUTH                   /*!< We had no auth for REFER */
01151 };

enum sip_auth_type

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.
Enumerator:
PROXY_AUTH 
WWW_AUTH 

Definition at line 391 of file chan_sip.c.

00391                    {
00392    PROXY_AUTH = 407,
00393    WWW_AUTH = 401,
00394 };

enum sip_debug_e

debugging state We store separately the debugging requests from the config file and requests from the CLI. Debugging is enabled if either is set (which means that if sipdebug is set in the config file, we can only turn it off by reloading the config).

Enumerator:
sip_debug_none 
sip_debug_config 
sip_debug_console 

Definition at line 1111 of file chan_sip.c.

01111                  {
01112    sip_debug_none = 0,
01113    sip_debug_config = 1,
01114    sip_debug_console = 2,
01115 };

enum sip_peer_type

Enumerator:
SIP_TYPE_PEER 
SIP_TYPE_USER 

Definition at line 1503 of file chan_sip.c.

01503                    {
01504    SIP_TYPE_PEER = (1 << 0),
01505    SIP_TYPE_USER = (1 << 1),
01506 };

enum sip_result

The result of a lot of functions.

Enumerator:
AST_SUCCESS 
AST_FAILURE  FALSE means success, funny enough

Definition at line 302 of file chan_sip.c.

00302                 {
00303    AST_SUCCESS = 0,     /*! FALSE means success, funny enough */
00304    AST_FAILURE = -1,    
00305 };

enum sip_tcptls_alert

Enumerator:
TCPTLS_ALERT_DATA  There is new data to be sent out.
TCPTLS_ALERT_STOP  A request to stop the tcp_handler thread.

Definition at line 1643 of file chan_sip.c.

01643                       {
01644    /*! \brief There is new data to be sent out */
01645    TCPTLS_ALERT_DATA,
01646    /*! \brief A request to stop the tcp_handler thread */
01647    TCPTLS_ALERT_STOP,
01648 };

enum sip_transport

Define some implemented SIP transports.

Note:
Asterisk does not support SCTP or UDP/DTLS
Enumerator:
SIP_TRANSPORT_UDP  Unreliable transport for SIP, needs retransmissions
SIP_TRANSPORT_TCP  Reliable, but unsecure
SIP_TRANSPORT_TLS  TCP/TLS - reliable and secure transport for signalling

Definition at line 466 of file chan_sip.c.

00466                    {
00467    SIP_TRANSPORT_UDP = 1,     /*!< Unreliable transport for SIP, needs retransmissions */
00468    SIP_TRANSPORT_TCP = 1 << 1,   /*!< Reliable, but unsecure */
00469    SIP_TRANSPORT_TLS = 1 << 2,   /*!< TCP/TLS - reliable and secure transport for signalling */
00470 };

enum sipmethod

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.
Enumerator:
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

Definition at line 512 of file chan_sip.c.

00512                {
00513    SIP_UNKNOWN,      /*!< Unknown response */
00514    SIP_RESPONSE,     /*!< Not request, response to outbound request */
00515    SIP_REGISTER,     /*!< Registration to the mothership, tell us where you are located */
00516    SIP_OPTIONS,      /*!< Check capabilities of a device, used for "ping" too */
00517    SIP_NOTIFY,    /*!< Status update, Part of the event package standard, result of a SUBSCRIBE or a REFER */
00518    SIP_INVITE,    /*!< Set up a session */
00519    SIP_ACK,    /*!< End of a three-way handshake started with INVITE. */
00520    SIP_PRACK,     /*!< Reliable pre-call signalling. Not supported in Asterisk. */
00521    SIP_BYE,    /*!< End of a session */
00522    SIP_REFER,     /*!< Refer to another URI (transfer) */
00523    SIP_SUBSCRIBE,    /*!< Subscribe for updates (voicemail, session status, device status, presence) */
00524    SIP_MESSAGE,      /*!< Text messaging */
00525    SIP_UPDATE,    /*!< Update a dialog. We can send UPDATE; but not accept it */
00526    SIP_INFO,      /*!< Information updates during a session */
00527    SIP_CANCEL,    /*!< Cancel an INVITE */
00528    SIP_PUBLISH,      /*!< Not supported in Asterisk */
00529    SIP_PING,      /*!< Not supported at all, no standard but still implemented out there */
00530 };

enum sipregistrystate

States for outbound registrations (with register= lines in sip.conf.

Enumerator:
REG_STATE_UNREGISTERED  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

Definition at line 414 of file chan_sip.c.

00414                       {
00415    REG_STATE_UNREGISTERED = 0,   /*!< We are not registered 
00416        *  \note Initial state. We should have a timeout scheduled for the initial
00417        * (or next) registration transmission, calling sip_reregister
00418        */
00419 
00420    REG_STATE_REGSENT,   /*!< Registration request sent 
00421        * \note sent initial request, waiting for an ack or a timeout to
00422        * retransmit the initial request.
00423       */
00424 
00425    REG_STATE_AUTHSENT,  /*!< We have tried to authenticate 
00426        * \note entered after transmit_register with auth info,
00427        * waiting for an ack.
00428        */
00429 
00430    REG_STATE_REGISTERED,   /*!< Registered and done */
00431 
00432    REG_STATE_REJECTED,  /*!< Registration rejected *
00433        * \note only used when the remote party has an expire larger than
00434        * our max-expire. This is a final state from which we do not
00435        * recover (not sure how correctly).
00436        */
00437 
00438    REG_STATE_TIMEOUT,   /*!< Registration timed out *
00439       * \note XXX unused */
00440 
00441    REG_STATE_NOAUTH, /*!< We have no accepted credentials
00442        * \note fatal - no chance to proceed */
00443 
00444    REG_STATE_FAILED, /*!< Registration failed after several tries
00445        * \note fatal - no chance to proceed */
00446 };

enum st_mode

Modes in which Asterisk can be configured to run SIP Session-Timers.

Enumerator:
SESSION_TIMER_MODE_INVALID  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

Definition at line 449 of file chan_sip.c.

00449              {
00450         SESSION_TIMER_MODE_INVALID = 0, /*!< Invalid value */ 
00451         SESSION_TIMER_MODE_ACCEPT,      /*!< Honor inbound Session-Timer requests */
00452         SESSION_TIMER_MODE_ORIGINATE,   /*!< Originate outbound and honor inbound requests */
00453         SESSION_TIMER_MODE_REFUSE       /*!< Ignore inbound Session-Timers requests */
00454 };

enum st_refresher

The entity playing the refresher role for Session-Timers.

Enumerator:
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

Definition at line 457 of file chan_sip.c.

00457                   {
00458         SESSION_TIMER_REFRESHER_AUTO,    /*!< Negotiated                      */
00459         SESSION_TIMER_REFRESHER_UAC,     /*!< Session is refreshed by the UAC */
00460         SESSION_TIMER_REFRESHER_UAS      /*!< Session is refreshed by the UAS */
00461 };

enum subscriptiontype

Type of subscription, based on the packages we do support.

Enumerator:
NONE 
XPIDF_XML 
DIALOG_INFO_XML 
CPIM_PIDF_XML 
PIDF_XML 
MWI_NOTIFICATION 

Definition at line 356 of file chan_sip.c.

00356                       { 
00357    NONE = 0,
00358    XPIDF_XML,
00359    DIALOG_INFO_XML,
00360    CPIM_PIDF_XML,
00361    PIDF_XML,
00362    MWI_NOTIFICATION
00363 };

enum t38_action_flag

Enumerator:
SDP_T38_NONE  Do not modify T38 information at all
SDP_T38_INITIATE  Remote side has requested T38 with us
SDP_T38_ACCEPT  Remote side accepted our T38 request

Definition at line 1895 of file chan_sip.c.

01895                      {
01896    SDP_T38_NONE = 0, /*!< Do not modify T38 information at all */
01897    SDP_T38_INITIATE, /*!< Remote side has requested T38 with us */
01898    SDP_T38_ACCEPT,   /*!< Remote side accepted our T38 request */
01899 };

enum t38state

T38 States for a call.

Enumerator:
T38_DISABLED  Not enabled
T38_LOCAL_REINVITE  Offered from local - REINVITE
T38_PEER_REINVITE  Offered from peer - REINVITE
T38_ENABLED  Negotiated (enabled)

Definition at line 1126 of file chan_sip.c.

01126               {
01127    T38_DISABLED = 0,                /*!< Not enabled */
01128    T38_LOCAL_REINVITE,              /*!< Offered from local - REINVITE */
01129    T38_PEER_REINVITE,               /*!< Offered from peer - REINVITE */
01130    T38_ENABLED                      /*!< Negotiated (enabled) */
01131 };

enum transfermodes

Authorization scheme for call transfers.

Note:
Not a bitfield flag, since there are plans for other modes, like "only allow transfers for authenticated devices"
Enumerator:
TRANSFER_OPENFORALL  Allow all SIP transfers
TRANSFER_CLOSED  Allow no SIP transfers

Definition at line 295 of file chan_sip.c.

00295                    {
00296    TRANSFER_OPENFORALL,            /*!< Allow all SIP transfers */
00297    TRANSFER_CLOSED,                /*!< Allow no SIP transfers */
00298 };

enum xmittype

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.

Enumerator:
XMIT_CRITICAL  Transmit critical SIP message reliably, with re-transmits. If it fails, it's critical and will cause a teardown of the session
XMIT_RELIABLE  Transmit SIP message reliably, with re-transmits
XMIT_UNRELIABLE  Transmit SIP message without bothering with re-transmits

Definition at line 341 of file chan_sip.c.

00341               {
00342    XMIT_CRITICAL = 2,              /*!< Transmit critical SIP message reliably, with re-transmits.
00343                                               If it fails, it's critical and will cause a teardown of the session */
00344    XMIT_RELIABLE = 1,              /*!< Transmit SIP message reliably, with re-transmits */
00345    XMIT_UNRELIABLE = 0,            /*!< Transmit SIP message without bothering with re-transmits */
00346 };


Function Documentation

static const char * __get_header ( const struct sip_request req,
const char *  name,
int *  start 
) [static]

Definition at line 6495 of file chan_sip.c.

References ast_skip_blanks(), find_alias(), sip_request::header, sip_request::headers, pass, and REQ_OFFSET_TO_STR.

06496 {
06497    int pass;
06498 
06499    /*
06500     * Technically you can place arbitrary whitespace both before and after the ':' in
06501     * a header, although RFC3261 clearly says you shouldn't before, and place just
06502     * one afterwards.  If you shouldn't do it, what absolute idiot decided it was 
06503     * a good idea to say you can do it, and if you can do it, why in the hell would.
06504     * you say you shouldn't.
06505     * Anyways, pedanticsipchecking controls whether we allow spaces before ':',
06506     * and we always allow spaces after that for compatibility.
06507     */
06508    for (pass = 0; name && pass < 2;pass++) {
06509       int x, len = strlen(name);
06510       for (x = *start; x < req->headers; x++) {
06511          char *header = REQ_OFFSET_TO_STR(req, header[x]);
06512          if (!strncasecmp(header, name, len)) {
06513             char *r = header + len; /* skip name */
06514             if (pedanticsipchecking)
06515                r = ast_skip_blanks(r);
06516 
06517             if (*r == ':') {
06518                *start = x+1;
06519                return ast_skip_blanks(r+1);
06520             }
06521          }
06522       }
06523       if (pass == 0) /* Try aliases */
06524          name = find_alias(name, NULL);
06525    }
06526 
06527    /* Don't return NULL, so get_header is always a valid pointer */
06528    return "";
06529 }

static void __init_check_auth_buf ( void   )  [static]

Definition at line 11766 of file chan_sip.c.

11777 {

static void __init_ts_temp_pvt ( void   )  [static]

A per-thread temporary pvt structure.

Definition at line 1804 of file chan_sip.c.

01837 : The address we bind to */

static void __reg_module ( void   )  [static]

Definition at line 24898 of file chan_sip.c.

static int __set_address_from_contact ( const char *  fullcontact,
struct sockaddr_in *  sin,
int  tcp 
) [static]

Definition at line 11367 of file chan_sip.c.

References ahp, ast_copy_string(), ast_gethostbyname(), ast_log(), get_transport_str2enum(), hp, LOG_WARNING, parse_uri(), port_str2int(), SIP_TRANSPORT_TLS, STANDARD_SIP_PORT, and STANDARD_TLS_PORT.

Referenced by build_peer(), and set_address_from_contact().

11368 {
11369    struct hostent *hp;
11370    struct ast_hostent ahp;
11371    int port = STANDARD_SIP_PORT;
11372    char *host, *pt, *transport;
11373    char contact_buf[256];
11374    char *contact;
11375 
11376    /* Work on a copy */
11377    ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf));
11378    contact = contact_buf;
11379 
11380    /* 
11381     * We have only the part in <brackets> here so we just need to parse a SIP URI.
11382     *
11383     * Note: The outbound proxy could be using UDP between the proxy and Asterisk.
11384     * We still need to be able to send to the remote agent through the proxy.
11385    */
11386 
11387    if (parse_uri(contact, "sip:,sips:", &contact, NULL, &host, &pt, NULL, &transport)) {
11388       ast_log(LOG_WARNING, "Invalid contact uri %s (missing sip: or sips:), attempting to use anyway\n", fullcontact);
11389    }
11390 
11391    /* set port */
11392    if (((get_transport_str2enum(transport) == SIP_TRANSPORT_TLS)) || !(strncasecmp(fullcontact, "sips", 4))) {
11393       port = port_str2int(pt, STANDARD_TLS_PORT);
11394    } else {
11395       port = port_str2int(pt, STANDARD_SIP_PORT);
11396    }
11397 
11398    /* XXX This could block for a long time XXX */
11399    /* We should only do this if it's a name, not an IP */
11400    hp = ast_gethostbyname(host, &ahp);
11401    if (!hp)  {
11402       ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host);
11403       return -1;
11404    }
11405    sin->sin_family = AF_INET;
11406    memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
11407    sin->sin_port = htons(port);
11408 
11409    return 0;
11410 }

static int __sip_ack ( struct sip_pvt p,
int  seqno,
int  resp,
int  sipmethod 
) [static]

Acknowledges receipt of a packet and stops retransmission called with p locked.

Definition at line 3650 of file chan_sip.c.

References ast_debug, ast_free, ast_sched_del(), sip_pvt::callid, sip_pkt::data, dialog_unref(), FALSE, sip_proxy::force, sip_pkt::is_resp, sip_pkt::method, msg, sip_pkt::next, sip_pvt::outboundproxy, sip_pkt::owner, sip_pvt::packets, sip_pvt::pendinginvite, ref_proxy(), sip_pkt::retransid, sched, sip_pkt::seqno, sip_pvt_lock, sip_pvt_unlock, TRUE, and UNLINK.

Referenced by __sip_pretend_ack(), handle_incoming(), handle_request_invite(), and handle_response().

03651 {
03652    struct sip_pkt *cur, *prev = NULL;
03653    const char *msg = "Not Found";   /* used only for debugging */
03654    int res = FALSE;
03655 
03656    /* If we have an outbound proxy for this dialog, then delete it now since
03657      the rest of the requests in this dialog needs to follow the routing.
03658      If obforcing is set, we will keep the outbound proxy during the whole
03659      dialog, regardless of what the SIP rfc says
03660    */
03661    if (p->outboundproxy && !p->outboundproxy->force){
03662       ref_proxy(p, NULL);
03663    }
03664 
03665    for (cur = p->packets; cur; prev = cur, cur = cur->next) {
03666       if (cur->seqno != seqno || cur->is_resp != resp)
03667          continue;
03668       if (cur->is_resp || cur->method == sipmethod) {
03669          res = TRUE;
03670          msg = "Found";
03671          if (!resp && (seqno == p->pendinginvite)) {
03672             ast_debug(1, "Acked pending invite %d\n", p->pendinginvite);
03673             p->pendinginvite = 0;
03674          }
03675          if (cur->retransid > -1) {
03676             if (sipdebug)
03677                ast_debug(4, "** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #%d\n", cur->retransid);
03678          }
03679          /* This odd section is designed to thwart a 
03680           * race condition in the packet scheduler. There are
03681           * two conditions under which deleting the packet from the
03682           * scheduler can fail.
03683           *
03684           * 1. The packet has been removed from the scheduler because retransmission
03685           * is being attempted. The problem is that if the packet is currently attempting
03686           * retransmission and we are at this point in the code, then that MUST mean
03687           * that retrans_pkt is waiting on p's lock. Therefore we will relinquish the
03688           * lock temporarily to allow retransmission.
03689           *
03690           * 2. The packet has reached its maximum number of retransmissions and has
03691           * been permanently removed from the packet scheduler. If this is the case, then
03692           * the packet's retransid will be set to -1. The atomicity of the setting and checking
03693           * of the retransid to -1 is ensured since in both cases p's lock is held.
03694           */
03695          while (cur->retransid > -1 && ast_sched_del(sched, cur->retransid)) {
03696             sip_pvt_unlock(p);
03697             usleep(1);
03698             sip_pvt_lock(p);
03699          }
03700          UNLINK(cur, p->packets, prev);
03701          dialog_unref(cur->owner, "unref pkt cur->owner dialog from sip ack before freeing pkt");
03702          if (cur->data)
03703             ast_free(cur->data);
03704          ast_free(cur);
03705          break;
03706       }
03707    }
03708    ast_debug(1, "Stopping retransmission on '%s' of %s %d: Match %s\n",
03709       p->callid, resp ? "Response" : "Request", seqno, msg);
03710    return res;
03711 }

static int __sip_autodestruct ( const void *  data  )  [static]

Kill a SIP dialog (called only by the scheduler) The scheduler has a reference to this dialog when p->autokillid != -1, and we are called using that reference. So if the event is not rescheduled, we need to call dialog_unref().

Definition at line 3548 of file chan_sip.c.

References __sip_pretend_ack(), sip_pvt::alreadygone, append_history, AST_CAUSE_PROTOCOL_ERROR, ast_debug, AST_EXTENSION_DEACTIVATED, ast_log(), ast_queue_hangup_with_cause(), sip_pvt::autokillid, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, dialog_unlink_all(), dialog_unref(), sip_pvt::lastmsg, LOG_WARNING, sip_pvt::method, method_match(), sip_pvt::needdestroy, NONE, sip_pvt::owner, sip_pvt::packets, sip_pvt::refer, sip_pvt::relatedpeer, SIP_BYE, SIP_CANCEL, sip_methods, sip_scheddestroy(), sip_pvt::subscribed, transmit_request_with_auth(), transmit_state_notify(), TRUE, unref_peer(), and XMIT_RELIABLE.

Referenced by sip_scheddestroy(), and sip_show_sched().

03549 {
03550    struct sip_pvt *p = (struct sip_pvt *)data;
03551 
03552    /* If this is a subscription, tell the phone that we got a timeout */
03553    if (p->subscribed) {
03554       transmit_state_notify(p, AST_EXTENSION_DEACTIVATED, 1, TRUE);  /* Send last notification */
03555       p->subscribed = NONE;
03556       append_history(p, "Subscribestatus", "timeout");
03557       ast_debug(3, "Re-scheduled destruction of SIP subscription %s\n", p->callid ? p->callid : "<unknown>");
03558       return 10000;  /* Reschedule this destruction so that we know that it's gone */
03559    }
03560 
03561    /* If there are packets still waiting for delivery, delay the destruction */
03562    if (p->packets) {
03563       if (!p->needdestroy) {
03564          char method_str[31];
03565          ast_debug(3, "Re-scheduled destruction of SIP call %s\n", p->callid ? p->callid : "<unknown>");
03566          append_history(p, "ReliableXmit", "timeout");
03567          if (sscanf(p->lastmsg, "Tx: %30s", method_str) == 1 || sscanf(p->lastmsg, "Rx: %30s", method_str) == 1) {
03568             if (method_match(SIP_CANCEL, method_str) || method_match(SIP_BYE, method_str)) {
03569                p->needdestroy = 1;
03570             }
03571          }
03572          return 10000;
03573       } else {
03574          /* They've had their chance to respond. Time to bail */
03575          __sip_pretend_ack(p);
03576       }
03577    }
03578 
03579    if (p->subscribed == MWI_NOTIFICATION)
03580       if (p->relatedpeer)
03581          p->relatedpeer = unref_peer(p->relatedpeer, "__sip_autodestruct: unref peer p->relatedpeer");   /* Remove link to peer. If it's realtime, make sure it's gone from memory) */
03582 
03583    /* Reset schedule ID */
03584    p->autokillid = -1;
03585 
03586    if (p->owner) {
03587       ast_log(LOG_WARNING, "Autodestruct on dialog '%s' with owner in place (Method: %s)\n", p->callid, sip_methods[p->method].text);
03588       ast_queue_hangup_with_cause(p->owner, AST_CAUSE_PROTOCOL_ERROR);
03589    } else if (p->refer && !p->alreadygone) {
03590       ast_debug(3, "Finally hanging up channel after transfer: %s\n", p->callid);
03591       transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
03592       append_history(p, "ReferBYE", "Sending BYE on transferer call leg %s", p->callid);
03593       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
03594    } else {
03595       append_history(p, "AutoDestroy", "%s", p->callid);
03596       ast_debug(3, "Auto destroying SIP dialog '%s'\n", p->callid);
03597       dialog_unlink_all(p, TRUE, TRUE); /* once it's unlinked and unrefd everywhere, it'll be freed automagically */
03598       /* dialog_unref(p, "unref dialog-- no other matching conditions"); -- unlink all now should finish off the dialog's references and free it. */
03599       /* sip_destroy(p); */      /* Go ahead and destroy dialog. All attempts to recover is done */
03600       /* sip_destroy also absorbs the reference */
03601    }
03602    dialog_unref(p, "The ref to a dialog passed to this sched callback is going out of scope; unref it.");
03603    return 0;
03604 }

static void __sip_destroy ( struct sip_pvt p,
int  lockowner,
int  lockdialoglist 
) [static]

Execute destruction of SIP dialog structure, release memory.

Definition at line 5098 of file chan_sip.c.

References ast_channel::_softhangup, ao2_ref, ast_channel_lock, ast_channel_unlock, ast_debug, ast_free, AST_LIST_REMOVE_HEAD, ast_log(), ast_rtp_destroy(), ast_rtp_get_bridged(), AST_SCHED_DEL_UNREF, AST_SOFTHANGUP_DEV, ast_string_field_free_memory, ast_test_flag, ast_udptl_destroy(), ast_variables_destroy(), ast_verbose, sip_registry::call, sip_peer::call, sip_pvt::callid, DEC_CALL_LIMIT, dialog_unref(), sip_pvt::flags, free_old_route(), sip_history::list, LOG_DEBUG, sip_pvt::method, sip_peer::mwipvt, ast_channel::name, sip_request::next, option_debug, sip_pvt::owner, sip_pvt::registry, registry_unref(), sip_pvt::relatedpeer, sched, sip_debug_test_pvt(), sip_dump_history(), SIP_INC_COUNT, sip_methods, SIP_PAGE2_CALL_ONHOLD, sip_pvt::stimer, ast_channel::tech_pvt, TRUE, unref_peer(), and update_call_counter().

Referenced by sip_destroy().

05099 {
05100    struct sip_request *req;
05101 
05102    if (p->stimer) {
05103       ast_free(p->stimer);
05104       p->stimer = NULL;
05105    }
05106 
05107    if (sip_debug_test_pvt(p))
05108       ast_verbose("Really destroying SIP dialog '%s' Method: %s\n", p->callid, sip_methods[p->method].text);
05109 
05110    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
05111       update_call_counter(p, DEC_CALL_LIMIT);
05112       ast_debug(2, "This call did not properly clean up call limits. Call ID %s\n", p->callid);
05113    }
05114 
05115    /* Unlink us from the owner if we have one */
05116    if (p->owner) {
05117       if (lockowner)
05118          ast_channel_lock(p->owner);
05119       if (option_debug)
05120          ast_log(LOG_DEBUG, "Detaching from %s\n", p->owner->name);
05121       p->owner->tech_pvt = NULL;
05122       /* Make sure that the channel knows its backend is going away */
05123       p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
05124       if (lockowner)
05125          ast_channel_unlock(p->owner);
05126       /* Give the channel a chance to react before deallocation */
05127       usleep(1);
05128    }
05129 
05130    /* Remove link from peer to subscription of MWI */
05131    if (p->relatedpeer && p->relatedpeer->mwipvt)
05132       p->relatedpeer->mwipvt = dialog_unref(p->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt");
05133    if (p->relatedpeer && p->relatedpeer->call == p)
05134       p->relatedpeer->call = dialog_unref(p->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself");
05135    
05136    if (p->relatedpeer)
05137       p->relatedpeer = unref_peer(p->relatedpeer,"unsetting a dialog relatedpeer field in sip_destroy");
05138    
05139    if (p->registry) {
05140       if (p->registry->call == p)
05141          p->registry->call = dialog_unref(p->registry->call, "nulling out the registry's call dialog field in unlink_all");
05142       p->registry = registry_unref(p->registry, "delete p->registry");
05143    }
05144    
05145    if (dumphistory)
05146       sip_dump_history(p);
05147 
05148    if (p->options)
05149       ast_free(p->options);
05150 
05151    if (p->notify_headers) {
05152       ast_variables_destroy(p->notify_headers);
05153       p->notify_headers = NULL;
05154    }
05155    if (p->rtp) {
05156       ast_rtp_destroy(p->rtp);
05157    }
05158    if (p->vrtp) {
05159       ast_rtp_destroy(p->vrtp);
05160    }
05161    if (p->trtp) {
05162       while (ast_rtp_get_bridged(p->trtp))
05163          usleep(1);
05164       ast_rtp_destroy(p->trtp);
05165    }
05166    if (p->udptl)
05167       ast_udptl_destroy(p->udptl);
05168    if (p->refer)
05169       ast_free(p->refer);
05170    if (p->route) {
05171       free_old_route(p->route);
05172       p->route = NULL;
05173    }
05174    if (p->initreq.data)
05175       ast_free(p->initreq.data);
05176 
05177    /* Destroy Session-Timers if allocated */
05178    if (p->stimer) {
05179       p->stimer->quit_flag = 1;
05180       if (p->stimer->st_active == TRUE && p->stimer->st_schedid > -1) {
05181          AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid,
05182                dialog_unref(p, "removing session timer ref"));
05183       }
05184       ast_free(p->stimer);
05185       p->stimer = NULL;
05186    }
05187 
05188    /* Clear history */
05189    if (p->history) {
05190       struct sip_history *hist;
05191       while ( (hist = AST_LIST_REMOVE_HEAD(p->history, list)) ) {
05192          ast_free(hist);
05193          p->history_entries--;
05194       }
05195       ast_free(p->history);
05196       p->history = NULL;
05197    }
05198 
05199    while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) {
05200       ast_free(req);
05201    }
05202 
05203    if (p->chanvars) {
05204       ast_variables_destroy(p->chanvars);
05205       p->chanvars = NULL;
05206    }
05207 
05208    ast_string_field_free_memory(p);
05209 
05210    if (p->socket.tcptls_session) {
05211       ao2_ref(p->socket.tcptls_session, -1);
05212       p->socket.tcptls_session = NULL;
05213    }
05214 }

static int __sip_do_register ( struct sip_registry r  )  [static]

Register with SIP proxy.

Definition at line 10701 of file chan_sip.c.

References SIP_REGISTER, and transmit_register().

Referenced by sip_reregister().

10702 {
10703    int res;
10704 
10705    res = transmit_register(r, SIP_REGISTER, NULL, NULL);
10706    return res;
10707 }

static void __sip_pretend_ack ( struct sip_pvt p  )  [static]

Pretend to ack all packets called with p locked.

Definition at line 3715 of file chan_sip.c.

References __sip_ack(), ast_log(), sip_pkt::data, find_sip_method(), sip_pkt::is_resp, LOG_WARNING, sip_pkt::method, sip_request::method, sip_pvt::packets, sip_pkt::seqno, sip_methods, and ast_str::str.

Referenced by __sip_autodestruct(), handle_request_bye(), handle_request_cancel(), sip_hangup(), and sip_reg_timeout().

03716 {
03717    struct sip_pkt *cur = NULL;
03718 
03719    while (p->packets) {
03720       int method;
03721       if (cur == p->packets) {
03722          ast_log(LOG_WARNING, "Have a packet that doesn't want to give up! %s\n", sip_methods[cur->method].text);
03723          return;
03724       }
03725       cur = p->packets;
03726       method = (cur->method) ? cur->method : find_sip_method(cur->data->str);
03727       __sip_ack(p, cur->seqno, cur->is_resp, method);
03728    }
03729 }

static enum sip_result __sip_reliable_xmit ( struct sip_pvt p,
int  seqno,
int  resp,
struct ast_str data,
int  len,
int  fatal,
int  sipmethod 
) [static]

Transmit packet with retransmits.

Returns:
0 on success, -1 on failure to allocate packet

Definition at line 3470 of file chan_sip.c.

References __sip_xmit(), append_history, ast_calloc, ast_debug, AST_FAILURE, ast_free, ast_log(), AST_SCHED_DEL, AST_SCHED_REPLACE_VARIABLE, ast_str_buffer, ast_str_create(), ast_str_set(), AST_SUCCESS, sip_request::data, DEFAULT_RETRANS, dialog_ref(), dialog_unref(), LOG_ERROR, sip_pkt::next, sip_pkt::owner, sip_pvt::packets, sip_pvt::pendinginvite, sip_pkt::response_code, retrans_pkt(), sched, SIP_INVITE, SIP_TRANSPORT_UDP, sip_pvt::socket, ast_str::str, sip_pvt::timer_t1, sip_socket::type, and XMIT_ERROR.

Referenced by send_request(), and send_response().

03471 {
03472    struct sip_pkt *pkt = NULL;
03473    int siptimer_a = DEFAULT_RETRANS;
03474    int xmitres = 0;
03475    int respid;
03476 
03477    if (sipmethod == SIP_INVITE) {
03478       /* Note this is a pending invite */
03479       p->pendinginvite = seqno;
03480    }
03481 
03482    /* If the transport is something reliable (TCP or TLS) then don't really send this reliably */
03483    /* I removed the code from retrans_pkt that does the same thing so it doesn't get loaded into the scheduler */
03484    /* According to the RFC some packets need to be retransmitted even if its TCP, so this needs to get revisited */
03485    if (!(p->socket.type & SIP_TRANSPORT_UDP)) {
03486       xmitres = __sip_xmit(p, data, len); /* Send packet */
03487       if (xmitres == XMIT_ERROR) {  /* Serious network trouble, no need to try again */
03488          append_history(p, "XmitErr", "%s", fatal ? "(Critical)" : "(Non-critical)");
03489          return AST_FAILURE;
03490       } else
03491          return AST_SUCCESS;
03492    }
03493 
03494    if (!(pkt = ast_calloc(1, sizeof(*pkt) + len + 1)))
03495       return AST_FAILURE;
03496    /* copy data, add a terminator and save length */
03497    if (!(pkt->data = ast_str_create(len))) {
03498       ast_free(pkt);
03499       return AST_FAILURE;
03500    }
03501    ast_str_set(&pkt->data, 0, "%s%s", data->str, "\0");
03502    pkt->packetlen = len;
03503    /* copy other parameters from the caller */
03504    pkt->method = sipmethod;
03505    pkt->seqno = seqno;
03506    pkt->is_resp = resp;
03507    pkt->is_fatal = fatal;
03508    pkt->owner = dialog_ref(p, "__sip_reliable_xmit: setting pkt->owner");
03509    pkt->next = p->packets;
03510    p->packets = pkt; /* Add it to the queue */
03511    if (resp) {
03512       /* Parse out the response code */
03513       if (sscanf(ast_str_buffer(pkt->data), "SIP/2.0 %30u", &respid) == 1) {
03514          pkt->response_code = respid;
03515       }
03516    }
03517    pkt->timer_t1 = p->timer_t1;  /* Set SIP timer T1 */
03518    pkt->retransid = -1;
03519    if (pkt->timer_t1)
03520       siptimer_a = pkt->timer_t1 * 2;
03521 
03522    /* Schedule retransmission */
03523    AST_SCHED_REPLACE_VARIABLE(pkt->retransid, sched, siptimer_a, retrans_pkt, pkt, 1);
03524    if (sipdebug)
03525       ast_debug(4, "*** SIP TIMER: Initializing retransmit timer on packet: Id  #%d\n", pkt->retransid);
03526 
03527    xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen);   /* Send packet */
03528 
03529    if (xmitres == XMIT_ERROR) {  /* Serious network trouble, no need to try again */
03530       append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
03531       ast_log(LOG_ERROR, "Serious Network Trouble; __sip_xmit returns error for pkt data\n");
03532       AST_SCHED_DEL(sched, pkt->retransid);
03533       p->packets = pkt->next;
03534       pkt->owner = dialog_unref(pkt->owner,"pkt is being freed, its dialog ref is dead now");
03535       ast_free(pkt->data);
03536       ast_free(pkt);
03537       return AST_FAILURE;
03538    } else {
03539       return AST_SUCCESS;
03540    }
03541 }

static int __sip_semi_ack ( struct sip_pvt p,
int  seqno,
int  resp,
int  sipmethod 
) [static]

Acks receipt of packet, keep it around (used for provisional responses).

Definition at line 3732 of file chan_sip.c.

References ast_debug, AST_SCHED_DEL, sip_pvt::callid, sip_pkt::data, FALSE, sip_pkt::is_resp, method_match(), sip_pkt::next, sip_pvt::packets, sip_pkt::retransid, sched, sip_pkt::seqno, sip_methods, ast_str::str, cfsip_methods::text, and TRUE.

Referenced by handle_response(), and sip_hangup().

03733 {
03734    struct sip_pkt *cur;
03735    int res = FALSE;
03736 
03737    for (cur = p->packets; cur; cur = cur->next) {
03738       if (cur->seqno == seqno && cur->is_resp == resp &&
03739          (cur->is_resp || method_match(sipmethod, cur->data->str))) {
03740          /* this is our baby */
03741          if (cur->retransid > -1) {
03742             if (sipdebug)
03743                ast_debug(4, "*** SIP TIMER: Cancelling retransmission #%d - %s (got response)\n", cur->retransid, sip_methods[sipmethod].text);
03744          }
03745          AST_SCHED_DEL(sched, cur->retransid);
03746          res = TRUE;
03747          break;
03748       }
03749    }
03750    ast_debug(1, "(Provisional) Stopping retransmission (but retaining packet) on '%s' %s %d: %s\n", p->callid, resp ? "Response" : "Request", seqno, res == -1 ? "Not Found" : "Found");
03751    return res;
03752 }

static int __sip_xmit ( struct sip_pvt p,
struct ast_str data,
int  len 
) [static]

Transmit SIP message Sends a SIP request or response on a given socket (in the pvt) Called by retrans_pkt, send_request, send_response and __sip_reliable_xmit.

Definition at line 3169 of file chan_sip.c.

References ast_debug, ast_inet_ntoa(), ast_log(), sip_request::data, errno, sip_socket::fd, get_transport_pvt(), LOG_WARNING, sip_prepare_socket(), sip_real_dst(), sip_tcptls_write(), SIP_TRANSPORT_UDP, sip_pvt::socket, ast_str::str, sip_socket::tcptls_session, sip_socket::type, and XMIT_ERROR.

Referenced by __sip_reliable_xmit(), retrans_pkt(), send_request(), and send_response().

03170 {
03171    int res = 0;
03172    const struct sockaddr_in *dst = sip_real_dst(p);
03173 
03174    ast_debug(1, "Trying to put '%.11s' onto %s socket destined for %s:%d\n", data->str, get_transport_pvt(p), ast_inet_ntoa(dst->sin_addr), htons(dst->sin_port));
03175 
03176    if (sip_prepare_socket(p) < 0)
03177       return XMIT_ERROR;
03178 
03179    if (p->socket.type == SIP_TRANSPORT_UDP) {
03180       res = sendto(p->socket.fd, data->str, len, 0, (const struct sockaddr *)dst, sizeof(struct sockaddr_in));
03181    } else if (p->socket.tcptls_session) {
03182       res = sip_tcptls_write(p->socket.tcptls_session, data->str, len);
03183    } else {
03184       ast_debug(2, "Socket type is TCP but no tcptls_session is present to write to\n");
03185       return XMIT_ERROR;
03186    }
03187 
03188    if (res == -1) {
03189       switch (errno) {
03190       case EBADF:       /* Bad file descriptor - seems like this is generated when the host exist, but doesn't accept the UDP packet */
03191       case EHOSTUNREACH:   /* Host can't be reached */
03192       case ENETDOWN:       /* Inteface down */
03193       case ENETUNREACH: /* Network failure */
03194       case ECONNREFUSED:      /* ICMP port unreachable */ 
03195          res = XMIT_ERROR; /* Don't bother with trying to transmit again */
03196       }
03197    }
03198    if (res != len)
03199       ast_log(LOG_WARNING, "sip_xmit of %p (len %d) to %s:%d returned %d: %s\n", data, len, ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), res, strerror(errno));
03200 
03201    return res;
03202 }

static int __transmit_response ( struct sip_pvt p,
const char *  msg,
const struct sip_request req,
enum xmittype  reliable 
) [static]

Base transmit response function.

Definition at line 8927 of file chan_sip.c.

References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), buf, get_header(), ast_channel::hangupcause, LOG_WARNING, sip_pvt::method, sip_pvt::owner, respprep(), send_response(), and SIP_INVITE.

Referenced by transmit_response(), transmit_response_reliable(), and transmit_response_using_temp().

08928 {
08929    struct sip_request resp;
08930    int seqno = 0;
08931 
08932    if (reliable && (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1)) {
08933       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
08934       return -1;
08935    }
08936    respprep(&resp, p, msg, req);
08937    add_header_contentLength(&resp, 0);
08938    /* If we are cancelling an incoming invite for some reason, add information
08939       about the reason why we are doing this in clear text */
08940    if (p->method == SIP_INVITE && msg[0] != '1' && p->owner && p->owner->hangupcause) {
08941       char buf[10];
08942 
08943       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->owner->hangupcause));
08944       snprintf(buf, sizeof(buf), "%d", p->owner->hangupcause);
08945       add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
08946    }
08947    return send_response(p, &resp, reliable, seqno);
08948 }

static void __unreg_module ( void   )  [static]

Definition at line 24898 of file chan_sip.c.

static char * _sip_qualify_peer ( int  type,
int  fd,
struct mansession s,
const struct message m,
int  argc,
const char *  argv[] 
) [static]

Send qualify message to peer from cli or manager. Mostly for debugging.

Definition at line 14496 of file chan_sip.c.

References ast_cli(), astman_send_error(), CLI_SHOWUSAGE, CLI_SUCCESS, FALSE, find_peer(), FINDPEERS, s, sip_poke_peer(), TRUE, and unref_peer().

Referenced by manager_sip_qualify_peer(), and sip_qualify_peer().

14497 {
14498    struct sip_peer *peer;
14499    int load_realtime;
14500 
14501    if (argc < 4)
14502       return CLI_SHOWUSAGE;
14503 
14504    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
14505    if ((peer = find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE, 0))) {
14506       sip_poke_peer(peer, 1);
14507       unref_peer(peer, "qualify: done with peer");
14508    } else if (type == 0) {
14509       ast_cli(fd, "Peer '%s' not found\n", argv[3]);
14510    } else {
14511       astman_send_error(s, m, "Peer not found");
14512    }
14513    return CLI_SUCCESS;
14514 }

static char * _sip_show_peer ( int  type,
int  fd,
struct mansession s,
const struct message m,
int  argc,
const char *  argv[] 
) [static]

Show one peer in detail (main function).

Definition at line 14581 of file chan_sip.c.

References sip_peer::accountcode, sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ARRAY_LEN, ast_callerid_merge(), ast_cdr_flags2str(), ast_check_realtime(), ast_cli(), ast_codec_pref_index(), ast_describe_caller_presentation(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_print_group(), ast_sched_when(), ast_str_alloca, ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), astman_send_error(), sip_peer::auth, sip_peer::autoframing, sip_peer::busy_level, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, CLI_SHOWUSAGE, CLI_SUCCESS, cli_yesno(), sip_peer::context, sip_peer::defaddr, dtmfmode2str(), sip_peer::expire, FALSE, faxec2str(), find_peer(), FINDPEERS, sip_peer::flags, sip_proxy::force, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, get_transport(), sip_peer::ha, sip_peer::host_dynamic, cfsip_options::id, insecure2str(), sip_peer::is_realtime, sip_peer::language, sip_peer::lastmsgssent, sip_peer::maxcallbitrate, sip_auth::md5secret, sip_peer::md5secret, ast_variable::name, sip_proxy::name, sip_peer::name, nat2str(), ast_variable::next, sip_auth::next, sip_peer::outboundproxy, sip_peer::parkinglot, peer_mailboxes_to_str(), peer_status(), sip_peer::pickupgroup, sip_peer::prefs, print_codec_to_cli(), print_group(), sip_peer::qualifyfreq, sip_auth::realm, sip_peer::regexten, s, S_OR, sched, sip_auth::secret, sip_peer::secret, SIP_CAN_REINVITE, SIP_DTMF, SIP_INSECURE, SIP_NAT, sip_options, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_IGNORESDPVERSION, SIP_PAGE2_REGISTERTRYING, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_TEXTSUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_PROMISCREDIR, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USEREQPHONE, sip_peer::sipoptions, sip_peer::socket, sip_st_cfg::st_max_se, sip_st_cfg::st_min_se, sip_st_cfg::st_mode_oper, sip_st_cfg::st_ref, status, sip_peer::stimer, stmode2str(), ast_str::str, strefresher2str(), sip_peer::subscribecontext, sip_peer::t38_maxdatagram, text, sip_peer::timer_b, sip_peer::timer_t1, sip_peer::tohost, transfermode2str(), TRUE, sip_socket::type, unref_peer(), sip_peer::useragent, sip_peer::username, sip_auth::username, ast_variable::value, and sip_peer::vmexten.

Referenced by manager_sip_show_peer(), and sip_show_peer().

14582 {
14583    char status[30] = "";
14584    char cbuf[256];
14585    struct sip_peer *peer;
14586    char codec_buf[512];
14587    struct ast_codec_pref *pref;
14588    struct ast_variable *v;
14589    struct sip_auth *auth;
14590    int x = 0, codec = 0, load_realtime;
14591    int realtimepeers;
14592 
14593    realtimepeers = ast_check_realtime("sippeers");
14594 
14595    if (argc < 4)
14596       return CLI_SHOWUSAGE;
14597 
14598    load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
14599    peer = find_peer(argv[3], NULL, load_realtime, FINDPEERS, FALSE, 0);
14600 
14601    if (s) {    /* Manager */
14602       if (peer) {
14603          const char *id = astman_get_header(m, "ActionID");
14604 
14605          astman_append(s, "Response: Success\r\n");
14606          if (!ast_strlen_zero(id))
14607             astman_append(s, "ActionID: %s\r\n", id);
14608       } else {
14609          snprintf (cbuf, sizeof(cbuf), "Peer %s not found.", argv[3]);
14610          astman_send_error(s, m, cbuf);
14611          return CLI_SUCCESS;
14612       }
14613    }
14614    if (peer && type==0 ) { /* Normal listing */
14615       struct ast_str *mailbox_str = ast_str_alloca(512);
14616       ast_cli(fd, "\n\n");
14617       ast_cli(fd, "  * Name       : %s\n", peer->name);
14618       if (realtimepeers) { /* Realtime is enabled */
14619          ast_cli(fd, "  Realtime peer: %s\n", peer->is_realtime ? "Yes, cached" : "No");
14620       }
14621       ast_cli(fd, "  Secret       : %s\n", ast_strlen_zero(peer->secret)?"<Not set>":"<Set>");
14622       ast_cli(fd, "  MD5Secret    : %s\n", ast_strlen_zero(peer->md5secret)?"<Not set>":"<Set>");
14623       for (auth = peer->auth; auth; auth = auth->next) {
14624          ast_cli(fd, "  Realm-auth   : Realm %-15.15s User %-10.20s ", auth->realm, auth->username);
14625          ast_cli(fd, "%s\n", !ast_strlen_zero(auth->secret)?"<Secret set>":(!ast_strlen_zero(auth->md5secret)?"<MD5secret set>" : "<Not set>"));
14626       }
14627       ast_cli(fd, "  Context      : %s\n", peer->context);
14628       ast_cli(fd, "  Subscr.Cont. : %s\n", S_OR(peer->subscribecontext, "<Not set>") );
14629       ast_cli(fd, "  Language     : %s\n", peer->language);
14630       if (!ast_strlen_zero(peer->accountcode))
14631          ast_cli(fd, "  Accountcode  : %s\n", peer->accountcode);
14632       ast_cli(fd, "  AMA flags    : %s\n", ast_cdr_flags2str(peer->amaflags));
14633       ast_cli(fd, "  Transfer mode: %s\n", transfermode2str(peer->allowtransfer));
14634       ast_cli(fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(peer->callingpres));
14635       if (!ast_strlen_zero(peer->fromuser))
14636          ast_cli(fd, "  FromUser     : %s\n", peer->fromuser);
14637       if (!ast_strlen_zero(peer->fromdomain))
14638          ast_cli(fd, "  FromDomain   : %s\n", peer->fromdomain);
14639       ast_cli(fd, "  Callgroup    : ");
14640       print_group(fd, peer->callgroup, 0);
14641       ast_cli(fd, "  Pickupgroup  : ");
14642       print_group(fd, peer->pickupgroup, 0);
14643       peer_mailboxes_to_str(&mailbox_str, peer);
14644       ast_cli(fd, "  Mailbox      : %s\n", mailbox_str->str);
14645       ast_cli(fd, "  VM Extension : %s\n", peer->vmexten);
14646       ast_cli(fd, "  LastMsgsSent : %d/%d\n", (peer->lastmsgssent & 0x7fff0000) >> 16, peer->lastmsgssent & 0xffff);
14647       ast_cli(fd, "  Call limit   : %d\n", peer->call_limit);
14648       if (peer->busy_level)
14649          ast_cli(fd, "  Busy level   : %d\n", peer->busy_level);
14650       ast_cli(fd, "  Dynamic      : %s\n", cli_yesno(peer->host_dynamic));
14651       ast_cli(fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, "<unspecified>"));
14652       ast_cli(fd, "  MaxCallBR    : %d kbps\n", peer->maxcallbitrate);
14653       ast_cli(fd, "  Expire       : %ld\n", ast_sched_when(sched, peer->expire));
14654       ast_cli(fd, "  Insecure     : %s\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE)));
14655       ast_cli(fd, "  Nat          : %s\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT)));
14656       ast_cli(fd, "  ACL          : %s\n", cli_yesno(peer->ha != NULL));
14657       ast_cli(fd, "  T.38 support : %s\n", cli_yesno(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)));
14658       ast_cli(fd, "  T.38 EC mode : %s\n", faxec2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)));
14659       ast_cli(fd, "  T.38 MaxDtgrm: %d\n", peer->t38_maxdatagram);
14660       ast_cli(fd, "  CanReinvite  : %s\n", cli_yesno(ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)));
14661       ast_cli(fd, "  PromiscRedir : %s\n", cli_yesno(ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)));
14662       ast_cli(fd, "  User=Phone   : %s\n", cli_yesno(ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)));
14663       ast_cli(fd, "  Video Support: %s\n", cli_yesno(ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)));
14664       ast_cli(fd, "  Text Support : %s\n", cli_yesno(ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT)));
14665       ast_cli(fd, "  Ign SDP ver  : %s\n", cli_yesno(ast_test_flag(&peer->flags[1], SIP_PAGE2_IGNORESDPVERSION)));
14666       ast_cli(fd, "  Trust RPID   : %s\n", cli_yesno(ast_test_flag(&peer->flags[0], SIP_TRUSTRPID)));
14667       ast_cli(fd, "  Send RPID    : %s\n", cli_yesno(ast_test_flag(&peer->flags[0], SIP_SENDRPID)));
14668       ast_cli(fd, "  Subscriptions: %s\n", cli_yesno(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)));
14669       ast_cli(fd, "  Overlap dial : %s\n", cli_yesno(ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWOVERLAP)));
14670       if (peer->outboundproxy)
14671          ast_cli(fd, "  Outb. proxy  : %s %s\n", ast_strlen_zero(peer->outboundproxy->name) ? "<not set>" : peer->outboundproxy->name,
14672                      peer->outboundproxy->force ? "(forced)" : "");
14673 
14674       /* - is enumerated */
14675       ast_cli(fd, "  DTMFmode     : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
14676       ast_cli(fd, "  Timer T1     : %d\n", peer->timer_t1);
14677       ast_cli(fd, "  Timer B      : %d\n", peer->timer_b);
14678       ast_cli(fd, "  ToHost       : %s\n", peer->tohost);
14679       ast_cli(fd, "  Addr->IP     : %s Port %d\n",  peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)", ntohs(peer->addr.sin_port));
14680       ast_cli(fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
14681       ast_cli(fd, "  Transport    : %s\n", get_transport(peer->socket.type));
14682       if (!ast_strlen_zero(global_regcontext))
14683          ast_cli(fd, "  Reg. exten   : %s\n", peer->regexten);
14684       ast_cli(fd, "  Def. Username: %s\n", peer->username);
14685       ast_cli(fd, "  SIP Options  : ");
14686       if (peer->sipoptions) {
14687          int lastoption = -1;
14688          for (x = 0 ; x < ARRAY_LEN(sip_options); x++) {
14689             if (sip_options[x].id != lastoption) {
14690                if (peer->sipoptions & sip_options[x].id)
14691                   ast_cli(fd, "%s ", sip_options[x].text);
14692                lastoption = x;
14693             }
14694          }
14695       } else
14696          ast_cli(fd, "(none)");
14697 
14698       ast_cli(fd, "\n");
14699       ast_cli(fd, "  Codecs       : ");
14700       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
14701       ast_cli(fd, "%s\n", codec_buf);
14702       ast_cli(fd, "  Codec Order  : (");
14703       print_codec_to_cli(fd, &peer->prefs);
14704       ast_cli(fd, ")\n");
14705 
14706       ast_cli(fd, "  Auto-Framing :  %s \n", cli_yesno(peer->autoframing));
14707       ast_cli(fd, "  100 on REG   : %s\n", ast_test_flag(&peer->flags[1], SIP_PAGE2_REGISTERTRYING) ? "Yes" : "No");
14708       ast_cli(fd, "  Status       : ");
14709       peer_status(peer, status, sizeof(status));
14710       ast_cli(fd, "%s\n", status);
14711       ast_cli(fd, "  Useragent    : %s\n", peer->useragent);
14712       ast_cli(fd, "  Reg. Contact : %s\n", peer->fullcontact);
14713       ast_cli(fd, "  Qualify Freq : %d ms\n", peer->qualifyfreq);
14714       if (peer->chanvars) {
14715          ast_cli(fd, "  Variables    :\n");
14716          for (v = peer->chanvars ; v ; v = v->next)
14717             ast_cli(fd, "                 %s = %s\n", v->name, v->value);
14718       }
14719 
14720       ast_cli(fd, "  Sess-Timers  : %s\n", stmode2str(peer->stimer.st_mode_oper));
14721       ast_cli(fd, "  Sess-Refresh : %s\n", strefresher2str(peer->stimer.st_ref));
14722       ast_cli(fd, "  Sess-Expires : %d secs\n", peer->stimer.st_max_se);
14723       ast_cli(fd, "  Min-Sess     : %d secs\n", peer->stimer.st_min_se);
14724       ast_cli(fd, "  Parkinglot   : %s\n", peer->parkinglot);
14725       ast_cli(fd, "\n");
14726       peer = unref_peer(peer, "sip_show_peer: unref_peer: done with peer ptr");
14727    } else  if (peer && type == 1) { /* manager listing */
14728       char buffer[256];
14729       struct ast_str *mailbox_str = ast_str_alloca(512);
14730       astman_append(s, "Channeltype: SIP\r\n");
14731       astman_append(s, "ObjectName: %s\r\n", peer->name);
14732       astman_append(s, "ChanObjectType: peer\r\n");
14733       astman_append(s, "SecretExist: %s\r\n", ast_strlen_zero(peer->secret)?"N":"Y");
14734       astman_append(s, "MD5SecretExist: %s\r\n", ast_strlen_zero(peer->md5secret)?"N":"Y");
14735       astman_append(s, "Context: %s\r\n", peer->context);
14736       astman_append(s, "Language: %s\r\n", peer->language);
14737       if (!ast_strlen_zero(peer->accountcode))
14738          astman_append(s, "Accountcode: %s\r\n", peer->accountcode);
14739       astman_append(s, "AMAflags: %s\r\n", ast_cdr_flags2str(peer->amaflags));
14740       astman_append(s, "CID-CallingPres: %s\r\n", ast_describe_caller_presentation(peer->callingpres));
14741       if (!ast_strlen_zero(peer->fromuser))
14742          astman_append(s, "SIP-FromUser: %s\r\n", peer->fromuser);
14743       if (!ast_strlen_zero(peer->fromdomain))
14744          astman_append(s, "SIP-FromDomain: %s\r\n", peer->fromdomain);
14745       astman_append(s, "Callgroup: ");
14746       astman_append(s, "%s\r\n", ast_print_group(buffer, sizeof(buffer), peer->callgroup));
14747       astman_append(s, "Pickupgroup: ");
14748       astman_append(s, "%s\r\n", ast_print_group(buffer, sizeof(buffer), peer->pickupgroup));
14749       peer_mailboxes_to_str(&mailbox_str, peer);
14750       astman_append(s, "VoiceMailbox: %s\r\n", mailbox_str->str);
14751       astman_append(s, "TransferMode: %s\r\n", transfermode2str(peer->allowtransfer));
14752       astman_append(s, "LastMsgsSent: %d\r\n", peer->lastmsgssent);
14753       astman_append(s, "Call-limit: %d\r\n", peer->call_limit);
14754       astman_append(s, "Busy-level: %d\r\n", peer->busy_level);
14755       astman_append(s, "MaxCallBR: %d kbps\r\n", peer->maxcallbitrate);
14756       astman_append(s, "Dynamic: %s\r\n", peer->host_dynamic?"Y":"N");
14757       astman_append(s, "Callerid: %s\r\n", ast_callerid_merge(cbuf, sizeof(cbuf), peer->cid_name, peer->cid_num, ""));
14758       astman_append(s, "RegExpire: %ld seconds\r\n", ast_sched_when(sched, peer->expire));
14759       astman_append(s, "SIP-AuthInsecure: %s\r\n", insecure2str(ast_test_flag(&peer->flags[0], SIP_INSECURE)));
14760       astman_append(s, "SIP-NatSupport: %s\r\n", nat2str(ast_test_flag(&peer->flags[0], SIP_NAT)));
14761       astman_append(s, "ACL: %s\r\n", (peer->ha?"Y":"N"));
14762       astman_append(s, "SIP-CanReinvite: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_CAN_REINVITE)?"Y":"N"));
14763       astman_append(s, "SIP-PromiscRedir: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_PROMISCREDIR)?"Y":"N"));
14764       astman_append(s, "SIP-UserPhone: %s\r\n", (ast_test_flag(&peer->flags[0], SIP_USEREQPHONE)?"Y":"N"));
14765       astman_append(s, "SIP-VideoSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT)?"Y":"N"));
14766       astman_append(s, "SIP-TextSupport: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT)?"Y":"N"));
14767       astman_append(s, "SIP-T.38Support: %s\r\n", (ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)?"Y":"N"));
14768       astman_append(s, "SIP-T.38EC: %s\r\n", faxec2str(ast_test_flag(&peer->flags[1], SIP_PAGE2_T38SUPPORT)));
14769       astman_append(s, "SIP-T.38MaxDtgrm: %d\r\n", peer->t38_maxdatagram);
14770       astman_append(s, "SIP-Sess-Timers: %s\r\n", stmode2str(peer->stimer.st_mode_oper));
14771       astman_append(s, "SIP-Sess-Refresh: %s\r\n", strefresher2str(peer->stimer.st_ref));
14772       astman_append(s, "SIP-Sess-Expires: %d\r\n", peer->stimer.st_max_se);
14773       astman_append(s, "SIP-Sess-Min: %d\r\n", peer->stimer.st_min_se);
14774 
14775       /* - is enumerated */
14776       astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
14777       astman_append(s, "ToHost: %s\r\n", peer->tohost);
14778       astman_append(s, "Address-IP: %s\r\nAddress-Port: %d\r\n",  peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", ntohs(peer->addr.sin_port));
14779       astman_append(s, "Default-addr-IP: %s\r\nDefault-addr-port: %d\r\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
14780       astman_append(s, "Default-Username: %s\r\n", peer->username);
14781       if (!ast_strlen_zero(global_regcontext))
14782          astman_append(s, "RegExtension: %s\r\n", peer->regexten);
14783       astman_append(s, "Codecs: ");
14784       ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
14785       astman_append(s, "%s\r\n", codec_buf);
14786       astman_append(s, "CodecOrder: ");
14787       pref = &peer->prefs;
14788       for(x = 0; x < 32 ; x++) {
14789          codec = ast_codec_pref_index(pref, x);
14790          if (!codec)
14791             break;
14792          astman_append(s, "%s", ast_getformatname(codec));
14793          if (x < 31 && ast_codec_pref_index(pref, x+1))
14794             astman_append(s, ",");
14795       }
14796 
14797       astman_append(s, "\r\n");
14798       astman_append(s, "Status: ");
14799       peer_status(peer, status, sizeof(status));
14800       astman_append(s, "%s\r\n", status);
14801       astman_append(s, "SIP-Useragent: %s\r\n", peer->useragent);
14802       astman_append(s, "Reg-Contact: %s\r\n", peer->fullcontact);
14803       astman_append(s, "QualifyFreq: %d ms\r\n", peer->qualifyfreq);
14804       astman_append(s, "Parkinglot: %s\r\n", peer->parkinglot);
14805       if (peer->chanvars) {
14806          for (v = peer->chanvars ; v ; v = v->next) {
14807             astman_append(s, "ChanVariable: %s=%s\r\n", v->name, v->value);
14808          }
14809       }
14810 
14811       peer = unref_peer(peer, "sip_show_peer: unref_peer: done with peer");
14812 
14813    } else {
14814       ast_cli(fd, "Peer %s not found.\n", argv[3]);
14815       ast_cli(fd, "\n");
14816    }
14817 
14818    return CLI_SUCCESS;
14819 }

static char * _sip_show_peers ( int  fd,
int *  total,
struct mansession s,
const struct message m,
int  argc,
const char *  argv[] 
) [static]

Execute sip show peers command.

Definition at line 13889 of file chan_sip.c.

References sip_peer::addr, ao2_container_count(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock(), ao2_t_iterator_next, ao2_unlock(), ast_calloc, ast_check_realtime(), ast_cli(), ast_copy_string(), ast_free, ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, astman_append(), astman_get_header(), CLI_SHOWUSAGE, CLI_SUCCESS, FALSE, sip_peer::flags, FORMAT, FORMAT2, sip_peer::ha, sip_peer::host_dynamic, id, sip_peer::is_realtime, sip_peer::name, name, peer_status(), peercomparefunc(), peers, s, SIP_NAT_ROUTE, SIP_PAGE2_TEXTSUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_TYPE_PEER, status, TRUE, sip_peer::type, unref_peer(), and sip_peer::username.

Referenced by manager_sip_show_peers(), and sip_show_peers().

13890 {
13891    regex_t regexbuf;
13892    int havepattern = FALSE;
13893    struct sip_peer *peer;
13894    struct ao2_iterator i;
13895    
13896 /* the last argument is left-aligned, so we don't need a size anyways */
13897 #define FORMAT2 "%-25.25s  %-15.15s %-3.3s %-3.3s %-3.3s %-8s %-10s %s\n"
13898 #define FORMAT  "%-25.25s  %-15.15s %-3.3s %-3.3s %-3.3s %-8d %-10s %s\n"
13899 
13900    char name[256];
13901    int total_peers = 0;
13902    int peers_mon_online = 0;
13903    int peers_mon_offline = 0;
13904    int peers_unmon_offline = 0;
13905    int peers_unmon_online = 0;
13906    const char *id;
13907    char idtext[256] = "";
13908    int realtimepeers;
13909    int objcount = ao2_container_count(peers);
13910    struct sip_peer **peerarray;
13911    int k;
13912    
13913    
13914    realtimepeers = ast_check_realtime("sippeers");
13915    peerarray = ast_calloc(sizeof(struct sip_peer *), objcount);
13916 
13917    if (s) { /* Manager - get ActionID */
13918       id = astman_get_header(m, "ActionID");
13919       if (!ast_strlen_zero(id))
13920          snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
13921    }
13922 
13923    switch (argc) {
13924    case 5:
13925       if (!strcasecmp(argv[3], "like")) {
13926          if (regcomp(&regexbuf, argv[4], REG_EXTENDED | REG_NOSUB))
13927             return CLI_SHOWUSAGE;
13928          havepattern = TRUE;
13929       } else
13930          return CLI_SHOWUSAGE;
13931    case 3:
13932       break;
13933    default:
13934       return CLI_SHOWUSAGE;
13935    }
13936 
13937    if (!s) /* Normal list */
13938       ast_cli(fd, FORMAT2, "Name/username", "Host", "Dyn", "Nat", "ACL", "Port", "Status", (realtimepeers ? "Realtime" : ""));
13939    
13940 
13941    i = ao2_iterator_init(peers, 0);
13942    while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) {  
13943       ao2_lock(peer);
13944 
13945       if (!(peer->type & SIP_TYPE_PEER)) {
13946          ao2_unlock(peer);
13947          unref_peer(peer, "unref peer because it's actually a user");
13948          continue;
13949       }
13950 
13951       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0)) {
13952          objcount--;
13953          ao2_unlock(peer);
13954          unref_peer(peer, "toss iterator peer ptr before continue");
13955          continue;
13956       }
13957 
13958       peerarray[total_peers++] = peer;
13959       ao2_unlock(peer);
13960    }
13961    ao2_iterator_destroy(&i);
13962    
13963    qsort(peerarray, total_peers, sizeof(struct sip_peer *), peercomparefunc);
13964 
13965    for(k=0; k < total_peers; k++) {
13966       char status[20] = "";
13967       char srch[2000];
13968       char pstatus;
13969       peer = peerarray[k];
13970       
13971       ao2_lock(peer);
13972       if (havepattern && regexec(&regexbuf, peer->name, 0, NULL, 0)) {
13973          ao2_unlock(peer);
13974          unref_peer(peer, "toss iterator peer ptr before continue");
13975          continue;
13976       }
13977 
13978       if (!ast_strlen_zero(peer->username) && !s)
13979          snprintf(name, sizeof(name), "%s/%s", peer->name, peer->username);
13980       else
13981          ast_copy_string(name, peer->name, sizeof(name));
13982       
13983       pstatus = peer_status(peer, status, sizeof(status));
13984       if (pstatus == 1)
13985          peers_mon_online++;
13986       else if (pstatus == 0)
13987          peers_mon_offline++;
13988       else {
13989          if (peer->addr.sin_port == 0)
13990             peers_unmon_offline++;
13991          else
13992             peers_unmon_online++;
13993       }
13994 
13995       snprintf(srch, sizeof(srch), FORMAT, name,
13996          peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
13997          peer->host_dynamic ? " D " : "   ",    /* Dynamic or not? */
13998          ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE) ? " N " : "   ", /* NAT=yes? */
13999          peer->ha ? " A " : "   ",  /* permit/deny */
14000          ntohs(peer->addr.sin_port), status,
14001          realtimepeers ? (peer->is_realtime ? "Cached RT":"") : "");
14002 
14003       if (!s)  {/* Normal CLI list */
14004          ast_cli(fd, FORMAT, name, 
14005          peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "(Unspecified)",
14006          peer->host_dynamic ? " D " : "   ",    /* Dynamic or not? */
14007          ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE) ? " N " : "   ", /* NAT=yes? */
14008          peer->ha ? " A " : "   ",       /* permit/deny */
14009          
14010          ntohs(peer->addr.sin_port), status,
14011          realtimepeers ? (peer->is_realtime ? "Cached RT":"") : "");
14012       } else { /* Manager format */
14013          /* The names here need to be the same as other channels */
14014          astman_append(s, 
14015          "Event: PeerEntry\r\n%s"
14016          "Channeltype: SIP\r\n"
14017          "ObjectName: %s\r\n"
14018          "ChanObjectType: peer\r\n" /* "peer" or "user" */
14019          "IPaddress: %s\r\n"
14020          "IPport: %d\r\n"
14021          "Dynamic: %s\r\n"
14022          "Natsupport: %s\r\n"
14023          "VideoSupport: %s\r\n"
14024          "TextSupport: %s\r\n"
14025          "ACL: %s\r\n"
14026          "Status: %s\r\n"
14027          "RealtimeDevice: %s\r\n\r\n", 
14028          idtext,
14029          peer->name, 
14030          peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "-none-",
14031          ntohs(peer->addr.sin_port), 
14032          peer->host_dynamic ? "yes" : "no",  /* Dynamic or not? */
14033          ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE) ? "yes" : "no",  /* NAT=yes? */
14034          ast_test_flag(&peer->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "yes" : "no",  /* VIDEOSUPPORT=yes? */
14035          ast_test_flag(&peer->flags[1], SIP_PAGE2_TEXTSUPPORT) ? "yes" : "no",   /* TEXTSUPPORT=yes? */
14036          peer->ha ? "yes" : "no",       /* permit/deny */
14037          status,
14038          realtimepeers ? (peer->is_realtime ? "yes":"no") : "no");
14039       }
14040       ao2_unlock(peer);
14041       unref_peer(peer, "toss iterator peer ptr");
14042    }
14043    
14044    if (!s)
14045       ast_cli(fd, "%d sip peers [Monitored: %d online, %d offline Unmonitored: %d online, %d offline]\n",
14046               total_peers, peers_mon_online, peers_mon_offline, peers_unmon_online, peers_unmon_offline);
14047 
14048    if (havepattern)
14049       regfree(&regexbuf);
14050 
14051    if (total)
14052       *total = total_peers;
14053    
14054    ast_free(peerarray);
14055    
14056    return CLI_SUCCESS;
14057 #undef FORMAT
14058 #undef FORMAT2
14059 }

static void * _sip_tcp_helper_thread ( struct sip_pvt pvt,
struct ast_tcptls_session_instance tcptls_session 
) [static]

SIP TCP thread management function.

Todo:
XXX If there's no Content-Length or if the content-length and what we receive is not the same - we should generate an error

Definition at line 2544 of file chan_sip.c.

References ao2_lock(), ao2_ref, ao2_t_find, ao2_t_ref, ao2_t_unlink, ao2_unlock(), ast_debug, ast_free, AST_LIST_REMOVE_HEAD, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_poll, ast_str_append(), ast_str_buffer, ast_str_create(), ast_str_reset(), ast_tcptls_client_start(), ast_tcptls_server_write(), buf, cleanup(), ast_tcptls_session_instance::client, copy_request(), tcptls_packet::data, sip_request::data, tcptls_packet::entry, errno, ast_tcptls_session_instance::f, ast_tcptls_session_instance::fd, get_header(), handle_request_do(), tcptls_packet::len, ast_tcptls_session_instance::lock, LOG_ERROR, LOG_WARNING, me, MIN, OBJ_POINTER, ast_tcptls_session_instance::parent, parse_request(), ast_tcptls_session_instance::remote_address, REQ_OFFSET_TO_STR, set_socket_transport(), SIP_MIN_PACKET, sip_threadinfo_create(), SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, ast_tcptls_session_instance::ssl, TCPTLS_ALERT_DATA, TCPTLS_ALERT_STOP, sip_threadinfo::tcptls_session, and threadt.

Referenced by sip_tcp_worker_fn().

02545 {
02546    int res, cl;
02547    struct sip_request req = { 0, } , reqcpy = { 0, };
02548    struct sip_threadinfo *me = NULL;
02549    char buf[1024] = "";
02550    struct pollfd fds[2] = { { 0 }, { 0 }, };
02551    struct ast_tcptls_session_args *ca = NULL;
02552 
02553    /* If this is a server session, then the connection has already been setup,
02554     * simply create the threadinfo object so we can access this thread for writing.
02555     * 
02556     * if this is a client connection more work must be done.
02557     * 1. We own the parent session args for a client connection.  This pointer needs
02558     *    to be held on to so we can decrement it's ref count on thread destruction.
02559     * 2. The threadinfo object was created before this thread was launched, however
02560     *    it must be found within the threadt table.
02561     * 3. Last, the tcptls_session must be started.
02562     */
02563    if (!tcptls_session->client) {
02564       if (!(me = sip_threadinfo_create(tcptls_session, tcptls_session->ssl ? SIP_TRANSPORT_TLS : SIP_TRANSPORT_TCP))) {
02565          goto cleanup;
02566       }
02567       ao2_t_ref(me, +1, "Adding threadinfo ref for tcp_helper_thread");
02568    } else {
02569       struct sip_threadinfo tmp = {
02570          .tcptls_session = tcptls_session,
02571       };
02572 
02573       if ((!(ca = tcptls_session->parent)) ||
02574          (!(me = ao2_t_find(threadt, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread"))) ||
02575          (!(tcptls_session = ast_tcptls_client_start(tcptls_session)))) {
02576          goto cleanup;
02577       }
02578    }
02579 
02580    me->threadid = pthread_self();
02581    ast_debug(2, "Starting thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP");
02582 
02583    /* set up pollfd to watch for reads on both the socket and the alert_pipe */
02584    fds[0].fd = tcptls_session->fd;
02585    fds[1].fd = me->alert_pipe[0];
02586    fds[0].events = fds[1].events = POLLIN | POLLPRI;
02587 
02588    if (!(req.data = ast_str_create(SIP_MIN_PACKET)))
02589       goto cleanup;
02590    if (!(reqcpy.data = ast_str_create(SIP_MIN_PACKET)))
02591       goto cleanup;
02592 
02593    for (;;) {
02594       struct ast_str *str_save;
02595 
02596       res = ast_poll(fds, 2, -1); /* polls for both socket and alert_pipe */
02597       if (res < 0) {
02598          ast_debug(2, "SIP %s server :: ast_wait_for_input returned %d\n", tcptls_session->ssl ? "SSL": "TCP", res);
02599          goto cleanup;
02600       }
02601 
02602       /* handle the socket event, check for both reads from the socket fd,
02603        * and writes from alert_pipe fd */
02604       if (fds[0].revents) { /* there is data on the socket to be read */
02605 
02606          fds[0].revents = 0;
02607 
02608          /* clear request structure */
02609          str_save = req.data;
02610          memset(&req, 0, sizeof(req));
02611          req.data = str_save;
02612          ast_str_reset(req.data);
02613 
02614          str_save = reqcpy.data;
02615          memset(&reqcpy, 0, sizeof(reqcpy));
02616          reqcpy.data = str_save;
02617          ast_str_reset(reqcpy.data);
02618 
02619          memset(buf, 0, sizeof(buf));
02620 
02621          if (tcptls_session->ssl) {
02622             set_socket_transport(&req.socket, SIP_TRANSPORT_TLS);
02623             req.socket.port = htons(ourport_tls);
02624          } else {
02625             set_socket_transport(&req.socket, SIP_TRANSPORT_TCP);
02626             req.socket.port = htons(ourport_tcp);
02627          }
02628          req.socket.fd = tcptls_session->fd;
02629 
02630          /* Read in headers one line at a time */
02631          while (req.len < 4 || strncmp(REQ_OFFSET_TO_STR(&req, len - 4), "\r\n\r\n", 4)) {
02632             ast_mutex_lock(&tcptls_session->lock);
02633             if (!fgets(buf, sizeof(buf), tcptls_session->f)) {
02634                ast_mutex_unlock(&tcptls_session->lock);
02635                goto cleanup;
02636             }
02637             ast_mutex_unlock(&tcptls_session->lock);
02638             if (me->stop)
02639                 goto cleanup;
02640             ast_str_append(&req.data, 0, "%s", buf);
02641             req.len = req.data->used;
02642          }
02643          copy_request(&reqcpy, &req);
02644          parse_request(&reqcpy);
02645          /* In order to know how much to read, we need the content-length header */
02646          if (sscanf(get_header(&reqcpy, "Content-Length"), "%30d", &cl)) {
02647             while (cl > 0) {
02648                size_t bytes_read;
02649                ast_mutex_lock(&tcptls_session->lock);
02650                if (!(bytes_read = fread(buf, 1, MIN(sizeof(buf) - 1, cl), tcptls_session->f))) {
02651                   ast_mutex_unlock(&tcptls_session->lock);
02652                   goto cleanup;
02653                }
02654                buf[bytes_read] = '\0';
02655                ast_mutex_unlock(&tcptls_session->lock);
02656                if (me->stop)
02657                   goto cleanup;
02658                cl -= strlen(buf);
02659                ast_str_append(&req.data, 0, "%s", buf);
02660                req.len = req.data->used;
02661             }
02662          }
02663          /*! \todo XXX If there's no Content-Length or if the content-length and what
02664                we receive is not the same - we should generate an error */
02665 
02666          req.socket.tcptls_session = tcptls_session;
02667          handle_request_do(&req, &tcptls_session->remote_address);
02668       }
02669       if (fds[1].revents) { /* alert_pipe indicates there is data in the send queue to be sent */
02670          enum sip_tcptls_alert alert;
02671          struct tcptls_packet *packet;
02672 
02673          fds[1].revents = 0;
02674 
02675          if (read(me->alert_pipe[0], &alert, sizeof(alert)) == -1) {
02676             ast_log(LOG_ERROR, "read() failed: %s\n", strerror(errno));
02677             continue;
02678          }
02679 
02680          switch (alert) {
02681          case TCPTLS_ALERT_STOP:
02682             goto cleanup;
02683          case TCPTLS_ALERT_DATA:
02684             ao2_lock(me);
02685             if (!(packet = AST_LIST_REMOVE_HEAD(&me->packet_q, entry))) {
02686                ast_log(LOG_WARNING, "TCPTLS thread alert_pipe indicated packet should be sent, but frame_q is empty");
02687             } else if (ast_tcptls_server_write(tcptls_session, ast_str_buffer(packet->data), packet->len) == -1) {
02688                ast_log(LOG_WARNING, "Failure to write to tcp/tls socket\n");
02689             }
02690 
02691             if (packet) {
02692                ao2_t_ref(packet, -1, "tcptls packet sent, this is no longer needed");
02693             }
02694             ao2_unlock(me);
02695             break;
02696          default:
02697             ast_log(LOG_ERROR, "Unknown tcptls thread alert '%d'\n", alert);
02698          }
02699       }
02700    }
02701 
02702    ast_debug(2, "Shutting down thread for %s server\n", tcptls_session->ssl ? "SSL" : "TCP");
02703 
02704 cleanup:
02705    if (me) {
02706       ao2_t_unlink(threadt, me, "Removing tcptls helper thread, thread is closing");
02707       ao2_t_ref(me, -1, "Removing tcp_helper_threads threadinfo ref");
02708    }
02709    if (reqcpy.data) {
02710       ast_free(reqcpy.data);
02711    }
02712 
02713    if (req.data) {
02714       ast_free(req.data);
02715       req.data = NULL;
02716    }
02717 
02718    /* if client, we own the parent session arguments and must decrement ref */
02719    if (ca) {
02720       ao2_t_ref(ca, -1, "closing tcptls thread, getting rid of client tcptls_session arguments");
02721    }
02722 
02723    if (tcptls_session) {
02724       ast_mutex_lock(&tcptls_session->lock);
02725       if (tcptls_session->f) {
02726          fclose(tcptls_session->f);
02727          tcptls_session->f = NULL;
02728       }
02729       if (tcptls_session->fd != -1) {
02730          close(tcptls_session->fd);
02731          tcptls_session->fd = -1;
02732       }
02733       tcptls_session->parent = NULL;
02734       ast_mutex_unlock(&tcptls_session->lock);
02735 
02736       ao2_ref(tcptls_session, -1);
02737       tcptls_session = NULL;
02738    }
02739 
02740    return NULL;
02741 }

static int acf_channel_read ( struct ast_channel chan,
const char *  funcname,
char *  preparse,
char *  buf,
size_t  buflen 
) [static]

Definition at line 20004 of file chan_sip.c.

References AST_APP_ARG, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_inet_ntoa(), ast_log(), ast_rtp_get_peer(), ast_rtp_get_qos(), ast_rtp_get_quality(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), chan, sip_pvt::from, IS_SIP_TECH, LOG_ERROR, LOG_WARNING, parse(), sip_pvt::peername, qos, sip_pvt::recv, sip_pvt::rtp, RTPQOS_SUMMARY, sip_pvt::sa, t38properties::state, sip_pvt::t38, T38_DISABLED, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::trtp, sip_pvt::uri, sip_pvt::useragent, and sip_pvt::vrtp.

20005 {
20006    struct sip_pvt *p = chan->tech_pvt;
20007    char *all = "", *parse = ast_strdupa(preparse);
20008    int res = 0;
20009    AST_DECLARE_APP_ARGS(args,
20010       AST_APP_ARG(param);
20011       AST_APP_ARG(type);
20012       AST_APP_ARG(field);
20013    );
20014    AST_STANDARD_APP_ARGS(args, parse);
20015 
20016    /* Sanity check */
20017    if (!IS_SIP_TECH(chan->tech)) {
20018       ast_log(LOG_ERROR, "Cannot call %s on a non-SIP channel\n", funcname);
20019       return 0;
20020    }
20021 
20022    memset(buf, 0, buflen);
20023 
20024    if (p == NULL) {
20025       return -1;
20026    }
20027 
20028    if (!strcasecmp(args.param, "peerip")) {
20029       ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", buflen);
20030    } else if (!strcasecmp(args.param, "recvip")) {
20031       ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", buflen);
20032    } else if (!strcasecmp(args.param, "from")) {
20033       ast_copy_string(buf, p->from, buflen);
20034    } else if (!strcasecmp(args.param, "uri")) {
20035       ast_copy_string(buf, p->uri, buflen);
20036    } else if (!strcasecmp(args.param, "useragent")) {
20037       ast_copy_string(buf, p->useragent, buflen);
20038    } else if (!strcasecmp(args.param, "peername")) {
20039       ast_copy_string(buf, p->peername, buflen);
20040    } else if (!strcasecmp(args.param, "t38passthrough")) {
20041       ast_copy_string(buf, (p->t38.state == T38_DISABLED) ? "0" : "1", buflen);
20042    } else if (!strcasecmp(args.param, "rtpdest")) {
20043       struct sockaddr_in sin;
20044       struct ast_rtp *stream = NULL;
20045 
20046       if (ast_strlen_zero(args.type))
20047          args.type = "audio";
20048 
20049       if (!strcasecmp(args.type, "audio")) {
20050          stream = p->rtp;
20051       } else if (!strcasecmp(args.type, "video")) {
20052          stream = p->vrtp;
20053       } else if (!strcasecmp(args.type, "text")) {
20054          stream = p->trtp;
20055       } else {
20056          return -1;
20057       }
20058 
20059       if (!stream) {
20060          return -1;
20061       }
20062 
20063       ast_rtp_get_peer(stream, &sin);
20064       snprintf(buf, buflen, "%s:%d", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
20065    } else if (!strcasecmp(args.param, "rtpqos")) {
20066       struct ast_rtp_quality qos;
20067       struct ast_rtp *rtp = p->rtp;
20068       
20069       memset(&qos, 0, sizeof(qos));
20070 
20071       if (ast_strlen_zero(args.type))
20072          args.type = "audio";
20073       if (ast_strlen_zero(args.field))
20074          args.field = "all";
20075       
20076       if (!strcasecmp(args.type, "AUDIO")) {
20077          all = ast_rtp_get_quality(rtp = p->rtp, &qos, RTPQOS_SUMMARY);
20078       } else if (!strcasecmp(args.type, "VIDEO")) {
20079          all = ast_rtp_get_quality(rtp = p->vrtp, &qos, RTPQOS_SUMMARY);
20080       } else if (!strcasecmp(args.type, "TEXT")) {
20081          all = ast_rtp_get_quality(rtp = p->trtp, &qos, RTPQOS_SUMMARY);
20082       } else {
20083          return -1;
20084       }
20085       
20086       if (!strcasecmp(args.field, "local_ssrc"))
20087          snprintf(buf, buflen, "%u", qos.local_ssrc);
20088       else if (!strcasecmp(args.field, "local_lostpackets"))
20089          snprintf(buf, buflen, "%u", qos.local_lostpackets);
20090       else if (!strcasecmp(args.field, "local_jitter"))
20091          snprintf(buf, buflen, "%.0f", qos.local_jitter * 1000.0);
20092       else if (!strcasecmp(args.field, "local_count"))
20093          snprintf(buf, buflen, "%u", qos.local_count);
20094       else if (!strcasecmp(args.field, "remote_ssrc"))
20095          snprintf(buf, buflen, "%u", qos.remote_ssrc);
20096       else if (!strcasecmp(args.field, "remote_lostpackets"))
20097          snprintf(buf, buflen, "%u", qos.remote_lostpackets);
20098       else if (!strcasecmp(args.field, "remote_jitter"))
20099          snprintf(buf, buflen, "%.0f", qos.remote_jitter * 1000.0);
20100       else if (!strcasecmp(args.field, "remote_count"))
20101          snprintf(buf, buflen, "%u", qos.remote_count);
20102       else if (!strcasecmp(args.field, "rtt"))
20103          snprintf(buf, buflen, "%.0f", qos.rtt * 1000.0);
20104       else if (!strcasecmp(args.field, "all"))
20105          ast_copy_string(buf, all, buflen);
20106       else if (!ast_rtp_get_qos(rtp, args.field, buf, buflen))
20107           ;
20108       else {
20109          ast_log(LOG_WARNING, "Unrecognized argument '%s' to %s\n", preparse, funcname);
20110          return -1;
20111       }
20112    } else {
20113       res = -1;
20114    }
20115    return res;
20116 }

static void add_blank ( struct sip_request req  )  [static]

add a blank line if no body

Definition at line 3763 of file chan_sip.c.

References ast_str_append(), sip_request::data, sip_request::len, sip_request::lines, and ast_str::used.

Referenced by send_request(), and send_response().

03764 {
03765    if (!req->lines) {
03766       /* Add extra empty return. add_header() reserves 4 bytes so cannot be truncated */
03767       ast_str_append(&req->data, 0, "\r\n");
03768       req->len = req->data->used;
03769    }
03770 }

static void add_codec_to_sdp ( const struct sip_pvt p,
int  codec,
int  sample_rate,
struct ast_str **  m_buf,
struct ast_str **  a_buf,
int  debug,
int *  min_packet_size 
) [static]

Add codec offer to SDP offer/answer body in INVITE or 200 OK.

Definition at line 9190 of file chan_sip.c.

References ast_codec_pref_getsize(), AST_FORMAT_G723_1, AST_FORMAT_G729A, AST_FORMAT_ILBC, ast_getformatname(), ast_rtp_codec_getpref(), ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), AST_RTP_OPT_G726_NONSTANDARD, ast_str_append(), ast_test_flag, ast_verbose, ast_format_list::cur_ms, sip_pvt::flags, sip_pvt::rtp, and SIP_G726_NONSTANDARD.

Referenced by add_sdp().

09193 {
09194    int rtp_code;
09195    struct ast_format_list fmt;
09196 
09197 
09198    if (debug)
09199       ast_verbose("Adding codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec));
09200    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 1, codec)) == -1)
09201       return;
09202 
09203    if (p->rtp) {
09204       struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp);
09205       fmt = ast_codec_pref_getsize(pref, codec);
09206    } else /* I dont see how you couldn't have p->rtp, but good to check for and error out if not there like earlier code */
09207       return;
09208    ast_str_append(m_buf, 0, " %d", rtp_code);
09209    ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
09210           ast_rtp_lookup_mime_subtype(1, codec,
09211                        ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0),
09212           sample_rate);
09213    if (codec == AST_FORMAT_G729A) {
09214       /* Indicate that we don't support VAD (G.729 annex B) */
09215       ast_str_append(a_buf, 0, "a=fmtp:%d annexb=no\r\n", rtp_code);
09216    } else if (codec == AST_FORMAT_G723_1) {
09217       /* Indicate that we don't support VAD (G.723.1 annex A) */
09218       ast_str_append(a_buf, 0, "a=fmtp:%d annexa=no\r\n", rtp_code);
09219    } else if (codec == AST_FORMAT_ILBC) {
09220       /* Add information about us using only 20/30 ms packetization */
09221       ast_str_append(a_buf, 0, "a=fmtp:%d mode=%d\r\n", rtp_code, fmt.cur_ms);
09222    }
09223 
09224    if (fmt.cur_ms && (fmt.cur_ms < *min_packet_size))
09225       *min_packet_size = fmt.cur_ms;
09226 
09227    /* Our first codec packetization processed cannot be zero */
09228    if ((*min_packet_size)==0 && fmt.cur_ms)
09229       *min_packet_size = fmt.cur_ms;
09230 }

static int add_digit ( struct sip_request req,
char  digit,
unsigned int  duration,
int  mode 
) [static]

Add DTMF INFO tone to sip message Mode = 0 for application/dtmf-relay (Cisco) 1 for application/dtmf.

Definition at line 9141 of file chan_sip.c.

References add_header(), add_header_contentLength(), and add_line().

Referenced by transmit_info_with_digit().

09142 {
09143    char tmp[256];
09144    int event;
09145    if (mode) {
09146       /* Application/dtmf short version used by some implementations */
09147       if (digit == '*')
09148          event = 10;
09149       else if (digit == '#')
09150          event = 11;
09151       else if ((digit >= 'A') && (digit <= 'D'))
09152          event = 12 + digit - 'A';
09153       else
09154          event = atoi(&digit);
09155       snprintf(tmp, sizeof(tmp), "%d\r\n", event);
09156       add_header(req, "Content-Type", "application/dtmf");
09157       add_header_contentLength(req, strlen(tmp));
09158       add_line(req, tmp);
09159    } else {
09160       /* Application/dtmf-relay as documented by Cisco */
09161       snprintf(tmp, sizeof(tmp), "Signal=%c\r\nDuration=%u\r\n", digit, duration);
09162       add_header(req, "Content-Type", "application/dtmf-relay");
09163       add_header_contentLength(req, strlen(tmp));
09164       add_line(req, tmp);
09165    }
09166    return 0;
09167 }

static int add_header ( struct sip_request req,
const char *  var,
const char *  value 
) [static]

Add header to SIP message.

Definition at line 8392 of file chan_sip.c.

References ast_log(), ast_str_append(), sip_request::data, find_alias(), sip_request::header, sip_request::headers, sip_request::len, sip_request::lines, LOG_WARNING, SIP_MAX_HEADERS, and ast_str::used.

08393 {
08394    if (req->headers == SIP_MAX_HEADERS) {
08395       ast_log(LOG_WARNING, "Out of SIP header space\n");
08396       return -1;
08397    }
08398 
08399    if (req->lines) {
08400       ast_log(LOG_WARNING, "Can't add more headers when lines have been added\n");
08401       return -1;
08402    }
08403 
08404    if (compactheaders)
08405       var = find_alias(var, var);
08406 
08407    ast_str_append(&req->data, 0, "%s: %s\r\n", var, value);
08408    req->header[req->headers] = req->len;
08409 
08410    req->len = req->data->used;
08411    req->headers++;
08412 
08413    return 0;   
08414 }

static int add_header_contentLength ( struct sip_request req,
int  len 
) [static]

Add 'Content-Length' header to SIP message.

Definition at line 8417 of file chan_sip.c.

References add_header().

Referenced by __transmit_response(), add_digit(), add_sdp(), add_text(), add_vidupdate(), transmit_invite(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), transmit_request(), transmit_request_with_auth(), transmit_response_with_allow(), transmit_response_with_auth(), transmit_response_with_date(), transmit_response_with_minse(), transmit_response_with_unsupported(), and transmit_state_notify().

08418 {
08419    char clen[10];
08420 
08421    snprintf(clen, sizeof(clen), "%d", len);
08422    return add_header(req, "Content-Length", clen);
08423 }

static int add_line ( struct sip_request req,
const char *  line 
) [static]

Add content (not header) to SIP message.

Definition at line 8426 of file chan_sip.c.

References ast_log(), ast_str_append(), sip_request::data, sip_request::len, sip_request::line, sip_request::lines, LOG_WARNING, SIP_MAX_LINES, and ast_str::used.

08427 {
08428    if (req->lines == SIP_MAX_LINES)  {
08429       ast_log(LOG_WARNING, "Out of SIP line space\n");
08430       return -1;
08431    }
08432    if (!req->lines)
08433       /* Add extra empty return */
08434       req->len += ast_str_append(&req->data, 0, "\r\n");
08435    req->line[req->lines] = req->len;
08436    ast_str_append(&req->data, 0, "%s", line);
08437    req->len = req->data->used;
08438    req->lines++;
08439    return 0;   
08440 }

static void add_noncodec_to_sdp ( const struct sip_pvt p,
int  format,
int  sample_rate,
struct ast_str **  m_buf,
struct ast_str **  a_buf,
int  debug 
) [static]

Add RFC 2833 DTMF offer to SDP.

Definition at line 9308 of file chan_sip.c.

References AST_RTP_DTMF, ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), ast_str_append(), ast_verbose, and sip_pvt::rtp.

Referenced by add_sdp().

09311 {
09312    int rtp_code;
09313 
09314    if (debug)
09315       ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype(0, format, 0));
09316    if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1)
09317       return;
09318 
09319    ast_str_append(m_buf, 0, " %d", rtp_code);
09320    ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
09321           ast_rtp_lookup_mime_subtype(0, format, 0),
09322           sample_rate);
09323    if (format == AST_RTP_DTMF)   /* Indicate we support DTMF and FLASH... */
09324       ast_str_append(a_buf, 0, "a=fmtp:%d 0-16\r\n", rtp_code);
09325 }

static void add_peer_mailboxes ( struct sip_peer peer,
const char *  value 
) [static]

Todo:
document this function

Definition at line 22740 of file chan_sip.c.

References ast_calloc, ast_free, AST_LIST_INSERT_TAIL, ast_strdup, ast_strdupa, ast_strlen_zero(), context, sip_mailbox::entry, mailbox, sip_peer::mailboxes, mbox(), and strsep().

Referenced by build_peer().

22741 {
22742    char *next, *mbox, *context;
22743 
22744    next = ast_strdupa(value);
22745 
22746    while ((mbox = context = strsep(&next, ","))) {
22747       struct sip_mailbox *mailbox;
22748 
22749       if (!(mailbox = ast_calloc(1, sizeof(*mailbox))))
22750          continue;
22751 
22752       strsep(&context, "@");
22753       if (ast_strlen_zero(mbox)) {
22754          ast_free(mailbox);
22755          continue;
22756       }
22757       mailbox->mailbox = ast_strdup(mbox);
22758       mailbox->context = ast_strdup(context);
22759 
22760       AST_LIST_INSERT_TAIL(&peer->mailboxes, mailbox, entry);
22761    }
22762 }

static void add_peer_mwi_subs ( struct sip_peer peer  )  [static]

Definition at line 20257 of file chan_sip.c.

References AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, ast_event_subscribe(), AST_LIST_TRAVERSE, sip_mailbox::entry, mailbox, sip_peer::mailboxes, mwi_event_cb(), and S_OR.

Referenced by build_peer(), and handle_request_subscribe().

20258 {
20259    struct sip_mailbox *mailbox;
20260 
20261    AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
20262       mailbox->event_sub = ast_event_subscribe(AST_EVENT_MWI, mwi_event_cb, peer,
20263          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox,
20264          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"),
20265          AST_EVENT_IE_END);
20266    }
20267 }

static struct sip_auth * add_realm_authentication ( struct sip_auth authlist,
const char *  configuration,
int  lineno 
) [static]

Add realm authentication in list.

Definition at line 22564 of file chan_sip.c.

References ast_calloc, ast_copy_string(), ast_debug, ast_log(), ast_strlen_zero(), ast_verb, LOG_WARNING, sip_auth::md5secret, sip_auth::next, sip_auth::realm, secret, and sip_auth::username.

Referenced by build_peer().

22565 {
22566    char authcopy[256];
22567    char *username=NULL, *realm=NULL, *secret=NULL, *md5secret=NULL;
22568    struct sip_auth *a, *b, *auth;
22569 
22570    if (ast_strlen_zero(configuration))
22571       return authlist;
22572 
22573    ast_debug(1, "Auth config ::  %s\n", configuration);
22574 
22575    ast_copy_string(authcopy, configuration, sizeof(authcopy));
22576    username = authcopy;
22577 
22578    /* split user[:secret] and relm */
22579    realm = strrchr(username, '@');
22580    if (realm)
22581       *realm++ = '\0';
22582    if (ast_strlen_zero(username) || ast_strlen_zero(realm)) {
22583       ast_log(LOG_WARNING, "Format for authentication entry is user[:secret]@realm at line %d\n", lineno);
22584       return authlist;
22585    }
22586 
22587    /* parse username at ':' for secret, or '#" for md5secret */
22588    if ((secret = strchr(username, ':'))) {
22589       *secret++ = '\0';
22590    } else if ((md5secret = strchr(username, '#'))) {
22591       *md5secret++ = '\0';
22592    }
22593 
22594    if (!(auth = ast_calloc(1, sizeof(*auth))))
22595       return authlist;
22596 
22597    ast_copy_string(auth->realm, realm, sizeof(auth->realm));
22598    ast_copy_string(auth->username, username, sizeof(auth->username));
22599    if (secret)
22600       ast_copy_string(auth->secret, secret, sizeof(auth->secret));
22601    if (md5secret)
22602       ast_copy_string(auth->md5secret, md5secret, sizeof(auth->md5secret));
22603 
22604    /* find the end of the list */
22605    for (b = NULL, a = authlist; a ; b = a, a = a->next)
22606       ;
22607    if (b)
22608       b->next = auth;   /* Add structure add end of list */
22609    else
22610       authlist = auth;
22611 
22612    ast_verb(3, "Added authentication for realm %s\n", realm);
22613 
22614    return authlist;
22615 
22616 }

static void add_route ( struct sip_request req,
struct sip_route route 
) [static]

Add route header into request per learned route.

Definition at line 8543 of file chan_sip.c.

References add_header(), ast_copy_string(), sip_route::hop, sip_route::next, and SIPBUFSIZE.

Referenced by initreqprep(), and reqprep().

08544 {
08545    char r[SIPBUFSIZE*2], *p;
08546    int n, rem = sizeof(r);
08547 
08548    if (!route)
08549       return;
08550 
08551    p = r;
08552    for (;route ; route = route->next) {
08553       n = strlen(route->hop);
08554       if (rem < n+3) /* we need room for ",<route>" */
08555          break;
08556       if (p != r) {  /* add a separator after fist route */
08557          *p++ = ',';
08558          --rem;
08559       }
08560       *p++ = '<';
08561       ast_copy_string(p, route->hop, rem); /* cannot fail */
08562       p += n;
08563       *p++ = '>';
08564       rem -= (n+2);
08565    }
08566    *p = '\0';
08567    add_header(req, "Route", r);
08568 }

static enum sip_result add_sdp ( struct sip_request resp,
struct sip_pvt p,
int  oldsdp,
int  add_audio,
int  add_t38 
) [static]

Add Session Description Protocol message.

If oldsdp is TRUE, then the SDP version number is not incremented. This mechanism is used in Session-Timers where RE-INVITEs are used for refreshing SIP sessions without modifying the media session in any way.

Definition at line 9376 of file chan_sip.c.

References add_codec_to_sdp(), add_header(), add_header_contentLength(), add_line(), add_noncodec_to_sdp(), add_tcodec_to_sdp(), add_vcodec_to_sdp(), ast_codec_pref_index(), ast_debug, AST_FAILURE, AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_inet_ntoa(), ast_internal_timing_enabled(), ast_log(), ast_random(), AST_RTP_MAX, ast_str_alloca, ast_str_append(), ast_strlen_zero(), AST_SUCCESS, AST_T38_RATE_MANAGEMENT_LOCAL_TCF, AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF, ast_test_flag, ast_udptl_get_error_correction_scheme(), ast_udptl_get_local_max_datagram(), ast_udptl_get_us(), ast_verbose, buf, sip_request::debug, FALSE, ast_control_t38_parameters::fill_bit_removal, sip_pvt::flags, get_our_media_address(), sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastrtprx, sip_pvt::lastrtptx, ast_str::len, LOG_WARNING, sip_pvt::maxcallbitrate, sip_pvt::notext, sip_pvt::novideo, sip_pvt::offered_media, t38properties::our_parms, sip_pvt::ourip, sip_pvt::owner, sip_pvt::prefcodec, sip_pvt::prefs, ast_control_t38_parameters::rate, ast_control_t38_parameters::rate_management, sip_pvt::rtp, SDP_AUDIO, SDP_IMAGE, SDP_SAMPLE_RATE, SDP_TEXT, SDP_VIDEO, sip_pvt::sessionid, sip_pvt::sessionversion, sip_debug_test_pvt(), SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, SIPBUFSIZE, ast_str::str, sip_pvt::t38, t38_get_rate(), ast_control_t38_parameters::transcoding_jbig, ast_control_t38_parameters::transcoding_mmr, sip_pvt::tredirip, sip_pvt::trtp, TRUE, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, sip_pvt::udptlredirip, ast_str::used, ast_control_t38_parameters::version, version, and sip_pvt::vrtp.

09377 {
09378    int len = 0;
09379    int alreadysent = 0;
09380 
09381    struct sockaddr_in sin;
09382    struct sockaddr_in vsin;
09383    struct sockaddr_in tsin;
09384    struct sockaddr_in dest;
09385    struct sockaddr_in udptlsin;
09386    struct sockaddr_in vdest = { 0, };
09387    struct sockaddr_in tdest = { 0, };
09388    struct sockaddr_in udptldest = { 0, };
09389 
09390    /* SDP fields */
09391    char *version =   "v=0\r\n";     /* Protocol version */
09392    char subject[256];            /* Subject of the session */
09393    char owner[256];           /* Session owner/creator */
09394    char connection[256];            /* Connection data */
09395    char *session_time = "t=0 0\r\n";         /* Time the session is active */
09396    char bandwidth[256] = "";        /* Max bitrate */
09397    char *hold = "";
09398    struct ast_str *m_audio = ast_str_alloca(256);  /* Media declaration line for audio */
09399    struct ast_str *m_video = ast_str_alloca(256);  /* Media declaration line for video */
09400    struct ast_str *m_text = ast_str_alloca(256);   /* Media declaration line for text */
09401    struct ast_str *m_modem = ast_str_alloca(256);  /* Media declaration line for modem */
09402    struct ast_str *a_audio = ast_str_alloca(1024); /* Attributes for audio */
09403    struct ast_str *a_video = ast_str_alloca(1024); /* Attributes for video */
09404    struct ast_str *a_text = ast_str_alloca(1024);  /* Attributes for text */
09405    struct ast_str *a_modem = ast_str_alloca(1024); /* Attributes for modem */
09406 
09407    int x;
09408    int capability = 0;
09409    int needaudio = FALSE;
09410    int needvideo = FALSE;
09411    int needtext = FALSE;
09412    int debug = sip_debug_test_pvt(p);
09413    int min_audio_packet_size = 0;
09414    int min_video_packet_size = 0;
09415    int min_text_packet_size = 0;
09416 
09417    char codecbuf[SIPBUFSIZE];
09418    char buf[SIPBUFSIZE];
09419    char dummy_answer[256];
09420 
09421    /* Set the SDP session name */
09422    snprintf(subject, sizeof(subject), "s=%s\r\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession);
09423 
09424    if (!p->rtp) {
09425       ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
09426       return AST_FAILURE;
09427    }
09428    /* XXX We should not change properties in the SIP dialog until 
09429       we have acceptance of the offer if this is a re-invite */
09430 
09431    /* Set RTP Session ID and version */
09432    if (!p->sessionid) {
09433       p->sessionid = (int)ast_random();
09434       p->sessionversion = p->sessionid;
09435    } else {
09436       if (oldsdp == FALSE)
09437          p->sessionversion++;
09438    }
09439 
09440    if (add_audio) {
09441       /* Check if we need video in this call */
09442       if ((p->jointcapability & AST_FORMAT_VIDEO_MASK) && !p->novideo) {
09443          if (p->vrtp) {
09444             needvideo = TRUE;
09445             ast_debug(2, "This call needs video offers!\n");
09446          } else
09447             ast_debug(2, "This call needs video offers, but there's no video support enabled!\n");
09448       }
09449       /* Check if we need text in this call */
09450       if ((p->jointcapability & AST_FORMAT_TEXT_MASK) && !p->notext) {
09451          if (sipdebug_text)
09452             ast_verbose("We think we can do text\n");
09453          if (p->trtp) {
09454             if (sipdebug_text) {
09455                ast_verbose("And we have a text rtp object\n");
09456             }
09457             needtext = TRUE;
09458             ast_debug(2, "This call needs text offers! \n");
09459          } else {
09460             ast_debug(2, "This call needs text offers, but there's no text support enabled ! \n");
09461          }
09462       }
09463    }
09464 
09465    get_our_media_address(p, needvideo, &sin, &vsin, &tsin, &dest, &vdest);
09466 
09467    snprintf(owner, sizeof(owner), "o=%s %d %d IN IP4 %s\r\n", ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner, p->sessionid, p->sessionversion, ast_inet_ntoa(dest.sin_addr));
09468    snprintf(connection, sizeof(connection), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));
09469 
09470    if (add_audio) {
09471       capability = p->jointcapability;
09472 
09473       /* XXX note, Video and Text are negated - 'true' means 'no' */
09474       ast_debug(1, "** Our capability: %s Video flag: %s Text flag: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability), 
09475            p->novideo ? "True" : "False", p->notext ? "True" : "False");
09476       ast_debug(1, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec));
09477 
09478       /* Check if we need audio */
09479       if (capability & AST_FORMAT_AUDIO_MASK)
09480          needaudio = TRUE;
09481 
09482       if (debug) 
09483          ast_verbose("Audio is at %s port %d\n", ast_inet_ntoa(p->ourip.sin_addr), ntohs(sin.sin_port)); 
09484 
09485       /* Ok, we need video. Let's add what we need for video and set codecs.
09486          Video is handled differently than audio since we can not transcode. */
09487       if (needvideo) {
09488          ast_str_append(&m_video, 0, "m=video %d RTP/AVP", ntohs(vsin.sin_port));
09489 
09490          /* Build max bitrate string */
09491          if (p->maxcallbitrate)
09492             snprintf(bandwidth, sizeof(bandwidth), "b=CT:%d\r\n", p->maxcallbitrate);
09493          if (debug) 
09494             ast_verbose("Video is at %s port %d\n", ast_inet_ntoa(p->ourip.sin_addr), ntohs(vdest.sin_port));  
09495       }
09496 
09497       /* Ok, we need text. Let's add what we need for text and set codecs.
09498          Text is handled differently than audio since we can not transcode. */
09499       if (needtext) {
09500          if (sipdebug_text)
09501             ast_verbose("Lets set up the text sdp\n");
09502          /* Determine text destination */
09503          if (p->tredirip.sin_addr.s_addr) {
09504             tdest.sin_addr = p->tredirip.sin_addr;
09505             tdest.sin_port = p->tredirip.sin_port;
09506          } else {
09507             tdest.sin_addr = p->ourip.sin_addr;
09508             tdest.sin_port = tsin.sin_port;
09509          }
09510          ast_str_append(&m_text, 0, "m=text %d RTP/AVP", ntohs(tdest.sin_port));
09511 
09512          if (debug) /* XXX should I use tdest below ? */
09513             ast_verbose("Text is at %s port %d\n", ast_inet_ntoa(p->ourip.sin_addr), ntohs(tsin.sin_port)); 
09514 
09515       }
09516 
09517       /* Start building generic SDP headers */
09518 
09519       /* We break with the "recommendation" and send our IP, in order that our
09520          peer doesn't have to ast_gethostbyname() us */
09521 
09522       ast_str_append(&m_audio, 0, "m=audio %d RTP/AVP", ntohs(dest.sin_port));
09523 
09524       if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_ONEDIR)
09525          hold = "a=recvonly\r\n";
09526       else if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) == SIP_PAGE2_CALL_ONHOLD_INACTIVE)
09527          hold = "a=inactive\r\n";
09528       else
09529          hold = "a=sendrecv\r\n";
09530 
09531       /* Now, start adding audio codecs. These are added in this order:
09532          - First what was requested by the calling channel
09533          - Then preferences in order from sip.conf device config for this peer/user
09534          - Then other codecs in capabilities, including video
09535       */
09536 
09537       /* Prefer the audio codec we were requested to use, first, no matter what 
09538          Note that p->prefcodec can include video codecs, so mask them out
09539       */
09540       if (capability & p->prefcodec) {
09541          int codec = p->prefcodec & AST_FORMAT_AUDIO_MASK;
09542 
09543          add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec),
09544                 &m_audio, &a_audio,
09545                 debug, &min_audio_packet_size);
09546          alreadysent |= codec;
09547       }
09548 
09549       /* Start by sending our preferred audio/video codecs */
09550       for (x = 0; x < 32; x++) {
09551          int codec;
09552 
09553          if (!(codec = ast_codec_pref_index(&p->prefs, x)))
09554             break; 
09555 
09556          if (!(capability & codec))
09557             continue;
09558 
09559          if (alreadysent & codec)
09560          continue;
09561 
09562          add_codec_to_sdp(p, codec, SDP_SAMPLE_RATE(codec),
09563                 &m_audio, &a_audio,
09564                 debug, &min_audio_packet_size);
09565          alreadysent |= codec;
09566       }
09567 
09568       /* Now send any other common audio and video codecs, and non-codec formats: */
09569       for (x = 1; x <= (needtext ? AST_FORMAT_TEXT_MASK : (needvideo ? AST_FORMAT_VIDEO_MASK : AST_FORMAT_AUDIO_MASK)); x <<= 1) {
09570          if (!(capability & x))  /* Codec not requested */
09571             continue;
09572 
09573          if (alreadysent & x) /* Already added to SDP */
09574             continue;
09575 
09576          if (x & AST_FORMAT_AUDIO_MASK)
09577             add_codec_to_sdp(p, x, SDP_SAMPLE_RATE(x),
09578                    &m_audio, &a_audio, debug, &min_audio_packet_size);
09579          else if (x & AST_FORMAT_VIDEO_MASK) 
09580             add_vcodec_to_sdp(p, x, 90000,
09581                     &m_video, &a_video, debug, &min_video_packet_size);
09582          else if (x & AST_FORMAT_TEXT_MASK)
09583             add_tcodec_to_sdp(p, x, 1000,
09584                     &m_text, &a_text, debug, &min_text_packet_size);
09585       }
09586 
09587       /* Now add DTMF RFC2833 telephony-event as a codec */
09588       for (x = 1; x <= AST_RTP_MAX; x <<= 1) {
09589          if (!(p->jointnoncodeccapability & x))
09590             continue;
09591 
09592          add_noncodec_to_sdp(p, x, 8000, &m_audio, &a_audio, debug);
09593       }
09594 
09595       ast_debug(3, "-- Done with adding codecs to SDP\n");
09596 
09597       if (!p->owner || !ast_internal_timing_enabled(p->owner))
09598          ast_str_append(&a_audio, 0, "a=silenceSupp:off - - - -\r\n");
09599 
09600       if (min_audio_packet_size)
09601          ast_str_append(&a_audio, 0, "a=ptime:%d\r\n", min_audio_packet_size);
09602 
09603       /* XXX don't think you can have ptime for video */
09604       if (min_video_packet_size)
09605          ast_str_append(&a_video, 0, "a=ptime:%d\r\n", min_video_packet_size);
09606 
09607       /* XXX don't think you can have ptime for text */
09608       if (min_text_packet_size)
09609          ast_str_append(&a_text, 0, "a=ptime:%d\r\n", min_text_packet_size);
09610    }
09611 
09612    if (add_t38) {
09613       ast_udptl_get_us(p->udptl, &udptlsin);
09614 
09615       /* Determine T.38 UDPTL destination */
09616       if (p->udptlredirip.sin_addr.s_addr) {
09617          udptldest.sin_port = p->udptlredirip.sin_port;
09618          udptldest.sin_addr = p->udptlredirip.sin_addr;
09619       } else {
09620          udptldest.sin_addr = p->ourip.sin_addr;
09621          udptldest.sin_port = udptlsin.sin_port;
09622       }
09623 
09624       if (debug)
09625          ast_debug(1, "T.38 UDPTL is at %s port %d\n", ast_inet_ntoa(p->ourip.sin_addr), ntohs(udptlsin.sin_port));
09626 
09627       /* We break with the "recommendation" and send our IP, in order that our
09628          peer doesn't have to ast_gethostbyname() us */
09629 
09630       ast_str_append(&m_modem, 0, "m=image %d udptl t38\r\n", ntohs(udptldest.sin_port));
09631 
09632       ast_str_append(&a_modem, 0, "a=T38FaxVersion:%d\r\n", p->t38.our_parms.version);
09633       ast_str_append(&a_modem, 0, "a=T38MaxBitRate:%d\r\n", t38_get_rate(p->t38.our_parms.rate));
09634       if (p->t38.our_parms.fill_bit_removal) {
09635          ast_str_append(&a_modem, 0, "a=T38FaxFillBitRemoval\r\n");
09636       }
09637       if (p->t38.our_parms.transcoding_mmr) {
09638          ast_str_append(&a_modem, 0, "a=T38FaxTranscodingMMR\r\n");
09639       }
09640       if (p->t38.our_parms.transcoding_jbig) {
09641          ast_str_append(&a_modem, 0, "a=T38FaxTranscodingJBIG\r\n");
09642       }
09643       switch (p->t38.our_parms.rate_management) {
09644       case AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF:
09645          ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:transferredTCF\r\n");
09646          break;
09647       case AST_T38_RATE_MANAGEMENT_LOCAL_TCF:
09648          ast_str_append(&a_modem, 0, "a=T38FaxRateManagement:localTCF\r\n");
09649          break;
09650       }
09651       ast_str_append(&a_modem, 0, "a=T38FaxMaxDatagram:%u\r\n", ast_udptl_get_local_max_datagram(p->udptl));
09652       switch (ast_udptl_get_error_correction_scheme(p->udptl)) {
09653       case UDPTL_ERROR_CORRECTION_NONE:
09654          break;
09655       case UDPTL_ERROR_CORRECTION_FEC:
09656          ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:t38UDPFEC\r\n");
09657          break;
09658       case UDPTL_ERROR_CORRECTION_REDUNDANCY:
09659          ast_str_append(&a_modem, 0, "a=T38FaxUdpEC:t38UDPRedundancy\r\n");
09660          break;
09661       }
09662    }
09663 
09664    if (m_audio->len - m_audio->used < 2 || m_video->len - m_video->used < 2 ||
09665        m_text->len - m_text->used < 2 || a_text->len - a_text->used < 2 ||
09666        a_audio->len - a_audio->used < 2 || a_video->len - a_video->used < 2)
09667       ast_log(LOG_WARNING, "SIP SDP may be truncated due to undersized buffer!!\n");
09668 
09669    if (needaudio)
09670       ast_str_append(&m_audio, 0, "\r\n");
09671    if (needvideo)
09672       ast_str_append(&m_video, 0, "\r\n");
09673    if (needtext)
09674       ast_str_append(&m_text, 0, "\r\n");
09675 
09676    len = strlen(version) + strlen(subject) + strlen(owner) +
09677       strlen(connection) + strlen(session_time);
09678    if (needaudio)
09679       len += m_audio->used + a_audio->used + strlen(hold);
09680    if (needvideo) /* only if video response is appropriate */
09681       len += m_video->used + a_video->used + strlen(bandwidth) + strlen(hold);
09682    if (needtext) /* only if text response is appropriate */
09683       len += m_text->used + a_text->used + strlen(hold);
09684    if (add_t38)
09685       len += m_modem->used + a_modem->used;
09686 
09687    add_header(resp, "Content-Type", "application/sdp");
09688    add_header_contentLength(resp, len);
09689    add_line(resp, version);
09690    add_line(resp, owner);
09691    add_line(resp, subject);
09692    add_line(resp, connection);
09693    if (needvideo)    /* only if video response is appropriate */
09694       add_line(resp, bandwidth);
09695    add_line(resp, session_time);
09696    if (needaudio) {
09697       add_line(resp, m_audio->str);
09698       add_line(resp, a_audio->str);
09699       add_line(resp, hold);
09700    } else if (p->offered_media[SDP_AUDIO].offered) {
09701       snprintf(dummy_answer, sizeof(dummy_answer), "m=audio 0 RTP/AVP %s\r\n", p->offered_media[SDP_AUDIO].text);
09702       add_line(resp, dummy_answer);
09703    }
09704    if (needvideo) { /* only if video response is appropriate */
09705       add_line(resp, m_video->str);
09706       add_line(resp, a_video->str);
09707       add_line(resp, hold);   /* Repeat hold for the video stream */
09708    } else if (p->offered_media[SDP_VIDEO].offered) {
09709       snprintf(dummy_answer, sizeof(dummy_answer), "m=video 0 RTP/AVP %s\r\n", p->offered_media[SDP_VIDEO].text);
09710       add_line(resp, dummy_answer);
09711    }
09712    if (needtext) { /* only if text response is appropriate */
09713       add_line(resp, m_text->str);
09714       add_line(resp, a_text->str);
09715       add_line(resp, hold);   /* Repeat hold for the text stream */
09716    } else if (p->offered_media[SDP_TEXT].offered) {
09717       snprintf(dummy_answer, sizeof(dummy_answer), "m=text 0 RTP/AVP %s\r\n", p->offered_media[SDP_TEXT].text);
09718       add_line(resp, dummy_answer);
09719    }
09720    if (add_t38) {
09721       add_line(resp, m_modem->str);
09722       add_line(resp, a_modem->str);
09723    } else if (p->offered_media[SDP_IMAGE].offered) {
09724       add_line(resp, "m=image 0 udptl t38\r\n");
09725    }
09726 
09727    /* Update lastrtprx when we send our SDP */
09728    p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
09729 
09730    ast_debug(3, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability));
09731 
09732    return AST_SUCCESS;
09733 }

static int add_sip_domain ( const char *  domain,
const enum domain_mode  mode,
const char *  context 
) [static]

Add SIP domain to list of domains we are responsible for.

Definition at line 22500 of file chan_sip.c.

References ast_calloc, ast_copy_string(), ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), ast_strlen_zero(), domain::list, and LOG_WARNING.

22501 {
22502    struct domain *d;
22503 
22504    if (ast_strlen_zero(domain)) {
22505       ast_log(LOG_WARNING, "Zero length domain.\n");
22506       return 1;
22507    }
22508 
22509    if (!(d = ast_calloc(1, sizeof(*d))))
22510       return 0;
22511 
22512    ast_copy_string(d->domain, domain, sizeof(d->domain));
22513 
22514    if (!ast_strlen_zero(context))
22515       ast_copy_string(d->context, context, sizeof(d->context));
22516 
22517    d->mode = mode;
22518 
22519    AST_LIST_LOCK(&domain_list);
22520    AST_LIST_INSERT_TAIL(&domain_list, d, list);
22521    AST_LIST_UNLOCK(&domain_list);
22522 
22523    if (sipdebug)  
22524       ast_debug(1, "Added local SIP domain '%s'\n", domain);
22525 
22526    return 1;
22527 }

static void add_tcodec_to_sdp ( const struct sip_pvt p,
int  codec,
int  sample_rate,
struct ast_str **  m_buf,
struct ast_str **  a_buf,
int  debug,
int *  min_packet_size 
) [static]

Add text codec offer to SDP offer/answer body in INVITE or 200 OK.

Definition at line 9256 of file chan_sip.c.

References AST_FORMAT_T140, AST_FORMAT_T140RED, ast_getformatname(), ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), ast_str_append(), ast_verbose, and sip_pvt::trtp.

Referenced by add_sdp().

09259 {
09260    int rtp_code;
09261 
09262    if (!p->trtp)
09263       return;
09264 
09265    if (debug)
09266       ast_verbose("Adding text codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec));
09267 
09268    if ((rtp_code = ast_rtp_lookup_code(p->trtp, 1, codec)) == -1)
09269       return;
09270 
09271    ast_str_append(m_buf, 0, " %d", rtp_code);
09272    ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
09273           ast_rtp_lookup_mime_subtype(1, codec, 0), sample_rate);
09274    /* Add fmtp code here */
09275 
09276    if (codec == AST_FORMAT_T140RED) {
09277       ast_str_append(a_buf, 0, "a=fmtp:%d %d/%d/%d\r\n", rtp_code, 
09278           ast_rtp_lookup_code(p->trtp, 1, AST_FORMAT_T140),
09279           ast_rtp_lookup_code(p->trtp, 1, AST_FORMAT_T140),
09280           ast_rtp_lookup_code(p->trtp, 1, AST_FORMAT_T140));
09281 
09282    }
09283 }

static int add_text ( struct sip_request req,
const char *  text 
) [static]

Add text body to SIP message.

Definition at line 9128 of file chan_sip.c.

References add_header(), add_header_contentLength(), and add_line().

Referenced by transmit_message_with_text().

09129 {
09130    /* XXX Convert \n's to \r\n's XXX */
09131    add_header(req, "Content-Type", "text/plain;charset=UTF-8");
09132    add_header_contentLength(req, strlen(text));
09133    add_line(req, text);
09134    return 0;
09135 }

static struct ast_variable* add_var ( const char *  buf,
struct ast_variable list 
) [static]

implement the setvar config line

Definition at line 22649 of file chan_sip.c.

References ast_strdupa, ast_variable_new(), and ast_variable::next.

Referenced by build_device(), and build_peer().

22650 {
22651    struct ast_variable *tmpvar = NULL;
22652    char *varname = ast_strdupa(buf), *varval = NULL;
22653    
22654    if ((varval = strchr(varname, '='))) {
22655       *varval++ = '\0';
22656       if ((tmpvar = ast_variable_new(varname, varval, ""))) {
22657          tmpvar->next = list;
22658          list = tmpvar;
22659       }
22660    }
22661    return list;
22662 }

static void add_vcodec_to_sdp ( const struct sip_pvt p,
int  codec,
int  sample_rate,
struct ast_str **  m_buf,
struct ast_str **  a_buf,
int  debug,
int *  min_packet_size 
) [static]

Add video codec offer to SDP offer/answer body in INVITE or 200 OK.

Definition at line 9234 of file chan_sip.c.

References ast_getformatname(), ast_rtp_lookup_code(), ast_rtp_lookup_mime_subtype(), ast_str_append(), ast_verbose, and sip_pvt::vrtp.

Referenced by add_sdp().

09237 {
09238    int rtp_code;
09239 
09240    if (!p->vrtp)
09241       return;
09242 
09243    if (debug)
09244       ast_verbose("Adding video codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec));
09245 
09246    if ((rtp_code = ast_rtp_lookup_code(p->vrtp, 1, codec)) == -1)
09247       return;
09248 
09249    ast_str_append(m_buf, 0, " %d", rtp_code);
09250    ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
09251           ast_rtp_lookup_mime_subtype(1, codec, 0), sample_rate);
09252    /* Add fmtp code here */
09253 }

static int add_vidupdate ( struct sip_request req  )  [static]

add XML encoded media control with update

Note:
XML: The only way to turn 0 bits of information into a few hundred. (markster)

Definition at line 9171 of file chan_sip.c.

References add_header(), add_header_contentLength(), and add_line().

Referenced by transmit_info_with_vidupdate().

09172 {
09173    const char *xml_is_a_huge_waste_of_space =
09174       "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
09175       " <media_control>\r\n"
09176       "  <vc_primitive>\r\n"
09177       "   <to_encoder>\r\n"
09178       "    <picture_fast_update>\r\n"
09179       "    </picture_fast_update>\r\n"
09180       "   </to_encoder>\r\n"
09181       "  </vc_primitive>\r\n"
09182       " </media_control>\r\n";
09183    add_header(req, "Content-Type", "application/media_control+xml");
09184    add_header_contentLength(req, strlen(xml_is_a_huge_waste_of_space));
09185    add_line(req, xml_is_a_huge_waste_of_space);
09186    return 0;
09187 }

static void append_date ( struct sip_request req  )  [static]

Append date to SIP message.

Definition at line 9062 of file chan_sip.c.

References add_header().

Referenced by build_csv_record(), transmit_invite(), transmit_response_with_date(), transmit_response_with_minse(), and transmit_response_with_unsupported().

09063 {
09064    char tmpdat[256];
09065    struct tm tm;
09066    time_t t = time(NULL);
09067 
09068    gmtime_r(&t, &tm);
09069    strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T GMT", &tm);
09070    add_header(req, "Date", tmpdat);
09071 }

static void append_history_full ( struct sip_pvt p,
const char *  fmt,
  ... 
) [static]

Append to SIP dialog history with arg list.

Definition at line 3326 of file chan_sip.c.

References append_history_va(), and sip_pvt::do_history.

03327 {
03328    va_list ap;
03329 
03330    if (!p)
03331       return;
03332 
03333    if (!p->do_history && !recordhistory && !dumphistory)
03334       return;
03335 
03336    va_start(ap, fmt);
03337    append_history_va(p, fmt, ap);
03338    va_end(ap);
03339 
03340    return;
03341 }

static void append_history_va ( struct sip_pvt p,
const char *  fmt,
va_list  ap 
) [static]

Append to SIP dialog history with arg list.

Definition at line 3299 of file chan_sip.c.

References ast_calloc, ast_free, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, buf, sip_history::list, MAX_HISTORY_ENTRIES, and strsep().

Referenced by append_history_full().

03300 {
03301    char buf[80], *c = buf; /* max history length */
03302    struct sip_history *hist;
03303    int l;
03304 
03305    vsnprintf(buf, sizeof(buf), fmt, ap);
03306    strsep(&c, "\r\n"); /* Trim up everything after \r or \n */
03307    l = strlen(buf) + 1;
03308    if (!(hist = ast_calloc(1, sizeof(*hist) + l)))
03309       return;
03310    if (!p->history && !(p->history = ast_calloc(1, sizeof(*p->history)))) {
03311       ast_free(hist);
03312       return;
03313    }
03314    memcpy(hist->event, buf, l);
03315    if (p->history_entries == MAX_HISTORY_ENTRIES) {
03316       struct sip_history *oldest;
03317       oldest = AST_LIST_REMOVE_HEAD(p->history, list);
03318       p->history_entries--;
03319       ast_free(oldest);
03320    }
03321    AST_LIST_INSERT_TAIL(p->history, hist, list);
03322    p->history_entries++;
03323 }

static void ast_quiet_chan ( struct ast_channel chan  )  [static]

Turn off generator data XXX Does this function belong in the SIP channel?

Definition at line 18066 of file chan_sip.c.

References ast_channel::_state, ast_deactivate_generator(), AST_FLAG_MOH, ast_moh_stop(), AST_STATE_UP, ast_test_flag, and chan.

Referenced by attempt_transfer(), and handle_invite_replaces().

18067 {
18068    if (chan && chan->_state == AST_STATE_UP) {
18069       if (ast_test_flag(chan, AST_FLAG_MOH))
18070          ast_moh_stop(chan);
18071       else if (chan->generatordata)
18072          ast_deactivate_generator(chan);
18073    }
18074 }

static void ast_sip_ouraddrfor ( struct in_addr *  them,
struct sockaddr_in *  us,
struct sip_pvt p 
) [static]

NAT fix - decide which IP address to use for Asterisk server?

Using the localaddr structure built up with localnet statements in sip.conf apply it to their address to see if we need to substitute our externip or can get away with our internal bindaddr 'us' is always overwritten.

Definition at line 3224 of file chan_sip.c.

References ast_apply_ha(), ast_debug, ast_inet_ntoa(), ast_log(), ast_ouraddrfor(), ast_parse_arg(), AST_SENSE_ALLOW, ast_stun_request(), get_transport(), ast_tcptls_session_args::local_address, localaddr, LOG_NOTICE, LOG_WARNING, PARSE_INADDR, sip_tcp_desc, sip_tls_desc, SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, SIP_TRANSPORT_UDP, sip_pvt::socket, and sip_socket::type.

Referenced by manager_sipnotify(), sip_alloc(), sip_cli_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_register(), and transmit_response_using_temp().

03225 {
03226    struct sockaddr_in theirs;
03227    /* Set want_remap to non-zero if we want to remap 'us' to an externally
03228     * reachable IP address and port. This is done if:
03229     * 1. we have a localaddr list (containing 'internal' addresses marked
03230     *    as 'deny', so ast_apply_ha() will return AST_SENSE_DENY on them,
03231     *    and AST_SENSE_ALLOW on 'external' ones);
03232     * 2. either stunaddr or externip is set, so we know what to use as the
03233     *    externally visible address;
03234     * 3. the remote address, 'them', is external;
03235     * 4. the address returned by ast_ouraddrfor() is 'internal' (AST_SENSE_DENY
03236     *    when passed to ast_apply_ha() so it does need to be remapped.
03237     *    This fourth condition is checked later.
03238     */
03239    int want_remap;
03240 
03241    *us = internip;      /* starting guess for the internal address */
03242    /* now ask the system what would it use to talk to 'them' */
03243    ast_ouraddrfor(them, &us->sin_addr);
03244    theirs.sin_addr = *them;
03245 
03246    want_remap = localaddr &&
03247       (externip.sin_addr.s_addr || stunaddr.sin_addr.s_addr) &&
03248       ast_apply_ha(localaddr, &theirs) == AST_SENSE_ALLOW ;
03249 
03250    if (want_remap &&
03251        (!global_matchexterniplocally || !ast_apply_ha(localaddr, us)) ) {
03252       /* if we used externhost or stun, see if it is time to refresh the info */
03253       if (externexpire && time(NULL) >= externexpire) {
03254          if (stunaddr.sin_addr.s_addr) {
03255             ast_stun_request(sipsock, &stunaddr, NULL, &externip);
03256          } else {
03257             if (ast_parse_arg(externhost, PARSE_INADDR, &externip))
03258                ast_log(LOG_NOTICE, "Warning: Re-lookup of '%s' failed!\n", externhost);
03259          }
03260          externexpire = time(NULL) + externrefresh;
03261       }
03262       if (externip.sin_addr.s_addr)
03263          *us = externip;
03264       else
03265          ast_log(LOG_WARNING, "stun failed\n");
03266       ast_debug(1, "Target address %s is not local, substituting externip\n", 
03267          ast_inet_ntoa(*(struct in_addr *)&them->s_addr));
03268    } else if (p) {
03269       /* no remapping, but we bind to a specific address, so use it. */
03270       switch (p->socket.type) {
03271       case SIP_TRANSPORT_TCP:
03272          if (sip_tcp_desc.local_address.sin_addr.s_addr) {
03273             *us = sip_tcp_desc.local_address;
03274          } else {
03275             us->sin_port = sip_tcp_desc.local_address.sin_port;
03276          }
03277          break;
03278       case SIP_TRANSPORT_TLS:
03279          if (sip_tls_desc.local_address.sin_addr.s_addr) {
03280             *us = sip_tls_desc.local_address;
03281          } else {
03282             us->sin_port = sip_tls_desc.local_address.sin_port;
03283          }
03284             break;
03285       case SIP_TRANSPORT_UDP:
03286          /* fall through on purpose */
03287       default:
03288          if (bindaddr.sin_addr.s_addr) {
03289             *us = bindaddr;
03290          }
03291       }
03292    } else if (bindaddr.sin_addr.s_addr) {
03293       *us = bindaddr;
03294    }
03295    ast_debug(3, "Setting SIP_TRANSPORT_%s with address %s:%d\n", get_transport(p->socket.type), ast_inet_ntoa(us->sin_addr), ntohs(us->sin_port));
03296 }

static int attempt_transfer ( struct sip_dual transferer,
struct sip_dual target 
) [static]

Attempt transfer of SIP call This fix for attended transfers on a local PBX.

Definition at line 18078 of file chan_sip.c.

References ast_channel::_state, ast_channel_masquerade(), ast_debug, ast_log(), ast_quiet_chan(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), ast_state2str(), sip_dual::chan1, sip_dual::chan2, LOG_NOTICE, LOG_WARNING, and ast_channel::name.

18079 {
18080    int res = 0;
18081    struct ast_channel *peera = NULL,   
18082       *peerb = NULL,
18083       *peerc = NULL,
18084       *peerd = NULL;
18085 
18086 
18087    /* We will try to connect the transferee with the target and hangup
18088       all channels to the transferer */   
18089    ast_debug(4, "Sip transfer:--------------------\n");
18090    if (transferer->chan1)
18091       ast_debug(4, "-- Transferer to PBX channel: %s State %s\n", transferer->chan1->name, ast_state2str(transferer->chan1->_state));
18092    else
18093       ast_debug(4, "-- No transferer first channel - odd??? \n");
18094    if (target->chan1)
18095       ast_debug(4, "-- Transferer to PBX second channel (target): %s State %s\n", target->chan1->name, ast_state2str(target->chan1->_state));
18096    else
18097       ast_debug(4, "-- No target first channel ---\n");
18098    if (transferer->chan2)
18099       ast_debug(4, "-- Bridged call to transferee: %s State %s\n", transferer->chan2->name, ast_state2str(transferer->chan2->_state));
18100    else
18101       ast_debug(4, "-- No bridged call to transferee\n");
18102    if (target->chan2)
18103       ast_debug(4, "-- Bridged call to transfer target: %s State %s\n", target->chan2 ? target->chan2->name : "<none>", target->chan2 ? ast_state2str(target->chan2->_state) : "(none)");
18104    else
18105       ast_debug(4, "-- No target second channel ---\n");
18106    ast_debug(4, "-- END Sip transfer:--------------------\n");
18107    if (transferer->chan2) { /* We have a bridge on the transferer's channel */
18108       peera = transferer->chan1; /* Transferer - PBX -> transferee channel * the one we hangup */
18109       peerb = target->chan1;     /* Transferer - PBX -> target channel - This will get lost in masq */
18110       peerc = transferer->chan2; /* Asterisk to Transferee */
18111       peerd = target->chan2;     /* Asterisk to Target */
18112       ast_debug(3, "SIP transfer: Four channels to handle\n");
18113    } else if (target->chan2) {   /* Transferer has no bridge (IVR), but transferee */
18114       peera = target->chan1;     /* Transferer to PBX -> target channel */
18115       peerb = transferer->chan1; /* Transferer to IVR*/
18116       peerc = target->chan2;     /* Asterisk to Target */
18117       peerd = transferer->chan2; /* Nothing */
18118       ast_debug(3, "SIP transfer: Three channels to handle\n");
18119    }
18120 
18121    if (peera && peerb && peerc && (peerb != peerc)) {
18122       ast_quiet_chan(peera);     /* Stop generators */
18123       ast_quiet_chan(peerb);  
18124       ast_quiet_chan(peerc);
18125       if (peerd)
18126          ast_quiet_chan(peerd);
18127 
18128       ast_debug(4, "SIP transfer: trying to masquerade %s into %s\n", peerc->name, peerb->name);
18129       if (ast_channel_masquerade(peerb, peerc)) {
18130          ast_log(LOG_WARNING, "Failed to masquerade %s into %s\n", peerb->name, peerc->name);
18131          res = -1;
18132       } else
18133          ast_debug(4, "SIP transfer: Succeeded to masquerade channels.\n");
18134       return res;
18135    } else {
18136       ast_log(LOG_NOTICE, "SIP Transfer attempted with no appropriate bridged calls to transfer\n");
18137       if (transferer->chan1)
18138          ast_softhangup_nolock(transferer->chan1, AST_SOFTHANGUP_DEV);
18139       if (target->chan1)
18140          ast_softhangup_nolock(target->chan1, AST_SOFTHANGUP_DEV);
18141       return -1;
18142    }
18143    return 0;
18144 }

static void auth_headers ( enum sip_auth_type  code,
char **  header,
char **  respheader 
) [static]

return the request and response heade for a 401 or 407 code

Definition at line 11153 of file chan_sip.c.

References ast_verbose, PROXY_AUTH, and WWW_AUTH.

Referenced by check_auth(), do_proxy_auth(), do_register_auth(), and transmit_request_with_auth().

11154 {
11155    if (code == WWW_AUTH) {       /* 401 */
11156       *header = "WWW-Authenticate";
11157       *respheader = "Authorization";
11158    } else if (code == PROXY_AUTH) { /* 407 */
11159       *header = "Proxy-Authenticate";
11160       *respheader = "Proxy-Authorization";
11161    } else {
11162       ast_verbose("-- wrong response code %d\n", code);
11163       *header = *respheader = "Invalid";
11164    }
11165 }

static int auto_congest ( const void *  arg  )  [static]

Scheduled congestion on a call. Only called by the scheduler, must return the reference when done.

Definition at line 4964 of file chan_sip.c.

References append_history, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_CONGESTION, ast_queue_control(), DEFAULT_TRANS_TIMEOUT, dialog_unref(), sip_pvt_lock, sip_pvt_unlock, and sip_scheddestroy().

04965 {
04966    struct sip_pvt *p = (struct sip_pvt *)arg;
04967 
04968    sip_pvt_lock(p);
04969    p->initid = -1;   /* event gone, will not be rescheduled */
04970    if (p->owner) {
04971       /* XXX fails on possible deadlock */
04972       if (!ast_channel_trylock(p->owner)) {
04973          append_history(p, "Cong", "Auto-congesting (timer)");
04974          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
04975          ast_channel_unlock(p->owner);
04976       }
04977 
04978       /* Give the channel a chance to act before we proceed with destruction */
04979       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
04980    }
04981    sip_pvt_unlock(p);
04982    dialog_unref(p, "unreffing arg passed into auto_congest callback (p->initid)");
04983    return 0;
04984 }

static void build_callid_pvt ( struct sip_pvt pvt  )  [static]

Build SIP Call-ID value for a non-REGISTER transaction.

Definition at line 6687 of file chan_sip.c.

References ast_inet_ntoa(), ast_string_field_build, buf, sip_pvt::callid, sip_pvt::fromdomain, generate_random_string(), sip_pvt::ourip, and S_OR.

Referenced by manager_sipnotify(), sip_alloc(), sip_cli_notify(), sip_poke_peer(), sip_request_call(), and sip_send_mwi_to_peer().

06688 {
06689    char buf[33];
06690 
06691    const char *host = S_OR(pvt->fromdomain, ast_inet_ntoa(pvt->ourip.sin_addr));
06692    
06693    ast_string_field_build(pvt, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
06694 
06695 }

static void build_callid_registry ( struct sip_registry reg,
struct in_addr  ourip,
const char *  fromdomain 
) [static]

Build SIP Call-ID value for a REGISTER transaction.

Definition at line 6698 of file chan_sip.c.

References ast_inet_ntoa(), ast_string_field_build, buf, sip_pvt::callid, generate_random_string(), and S_OR.

Referenced by transmit_register().

06699 {
06700    char buf[33];
06701 
06702    const char *host = S_OR(fromdomain, ast_inet_ntoa(ourip));
06703 
06704    ast_string_field_build(reg, callid, "%s@%s", generate_random_string(buf, sizeof(buf)), host);
06705 }

static void build_contact ( struct sip_pvt p  )  [static]

Build contact header - the contact header we send out.

Definition at line 9926 of file chan_sip.c.

References ast_inet_ntoa(), ast_string_field_build, ast_strlen_zero(), sip_pvt::exten, get_transport(), sip_pvt::ourip, ourport, sip_standard_port(), SIP_TRANSPORT_UDP, sip_pvt::socket, and sip_socket::type.

Referenced by check_user_full(), handle_request_invite(), handle_request_options(), handle_request_subscribe(), initreqprep(), register_verify(), and transmit_register().

09927 {
09928    int ourport = ntohs(p->ourip.sin_port);
09929    /* only add port if it's non-standard for the transport type */
09930    if (!sip_standard_port(p->socket.type, ourport)) {
09931       if (p->socket.type == SIP_TRANSPORT_UDP)
09932          ast_string_field_build(p, our_contact, "<sip:%s%s%s:%d>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip.sin_addr), ourport);
09933       else
09934          ast_string_field_build(p, our_contact, "<sip:%s%s%s:%d;transport=%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip.sin_addr), ourport, get_transport(p->socket.type));
09935    } else {
09936       if (p->socket.type == SIP_TRANSPORT_UDP)
09937          ast_string_field_build(p, our_contact, "<sip:%s%s%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip.sin_addr));
09938       else
09939          ast_string_field_build(p, our_contact, "<sip:%s%s%s;transport=%s>", p->exten, ast_strlen_zero(p->exten) ? "" : "@", ast_inet_ntoa(p->ourip.sin_addr), get_transport(p->socket.type));
09940    }
09941 }

static struct sip_peer * build_peer ( const char *  name,
struct ast_variable v,
struct ast_variable alt,
int  realtime,
int  devstate_only 
) [static]

Build peer from configuration (file or realtime static/dynamic).

< The first transport listed should be default outbound

Definition at line 22765 of file chan_sip.c.

References __set_address_from_contact(), sip_peer::accountcode, add_peer_mailboxes(), add_peer_mwi_subs(), add_realm_authentication(), add_var(), sip_peer::addr, sip_peer::allowtransfer, sip_peer::amaflags, ao2_t_alloc, ao2_t_find, asprintf, ast_append_ha(), ast_atomic_fetchadd_int(), ast_callerid_split(), ast_cdr_amaflags2int(), ast_copy_flags, ast_copy_string(), ast_debug, ast_dnsmgr_lookup(), ast_free, ast_free_ha(), ast_get_group(), ast_get_ip(), ast_get_time_t(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_parse_allow_disallow(), ast_parse_caller_presentation(), AST_SCHED_DEL_UNREF, ast_set2_flag, ast_set_flag, ast_skip_blanks(), ast_str_alloca, ast_str_append(), ast_str_reset(), ast_str_set(), ast_str_strlen, ast_strdupa, ast_strlen_zero(), ast_test_flag, ast_true(), ast_variables_destroy(), sip_peer::auth, sip_peer::autoframing, sip_peer::busy_level, sip_peer::call_limit, sip_peer::callgroup, sip_peer::callingpres, sip_peer::capability, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, clear_realm_authentication(), sip_peer::contactha, sip_peer::context, sip_peer::defaddr, DEFAULT_MAXMS, sip_peer::default_outbound_transport, sip_peer::deprecated_username, destroy_association(), sip_peer::dnsmgr, errno, sip_peer::expire, FALSE, ast_flags::flags, sip_peer::flags, format, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, get_transport(), global_contact_ha, global_flags, sip_peer::ha, handle_common_options(), handle_t38_options(), sip_peer::host_dynamic, sip_settings::ignore_regexpire, inet_aton(), sip_peer::is_realtime, sip_peer::language, sip_peer::lastms, sip_peer::lastmsgssent, ast_variable::lineno, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_peer::mailboxes, sip_peer::maxcallbitrate, MAXHOSTNAMELEN, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, ast_variable::name, sip_peer::name, ast_variable::next, OBJ_POINTER, OBJ_UNLINK, sip_peer::outboundproxy, sip_peer::parkinglot, peers, sip_peer::pickupgroup, sip_socket::port, port_str2int(), sip_peer::portinuri, sip_peer::prefs, proxy_allocate(), sip_peer::qualifyfreq, ref_peer(), reg_source_db(), sip_peer::regexten, sip_peer::rt_fromcontact, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sched, sip_peer::secret, set_peer_defaults(), set_socket_transport(), sip_cfg, sip_destroy_peer_fn(), SIP_NAT_ROUTE, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_HAVEPEERCONTEXT, SIP_PAGE2_REGISTERTRYING, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_SUBSCRIBEMWIONLY, sip_poke_peer(), sip_register(), sip_send_mwi_to_peer(), SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, SIP_TRANSPORT_UDP, SIP_TYPE_PEER, SIP_TYPE_USER, SIP_USEREQPHONE, sip_peer::socket, srvlookup, sip_st_cfg::st_max_se, sip_st_cfg::st_min_se, sip_st_cfg::st_mode_oper, sip_st_cfg::st_ref, STANDARD_SIP_PORT, STANDARD_TLS_PORT, sip_peer::stimer, ast_str::str, str2stmode(), str2strefresher(), strsep(), sip_peer::subscribecontext, sip_peer::t38_maxdatagram, sip_peer::the_mark, sip_peer::timer_b, sip_peer::timer_t1, sip_peer::tohost, TRANSFER_CLOSED, TRANSFER_OPENFORALL, sip_peer::transports, TRUE, sip_socket::type, sip_peer::type, unref_peer(), ast_str::used, sip_peer::username, ast_variable::value, and sip_peer::vmexten.

22766 {
22767    struct sip_peer *peer = NULL;
22768    struct ast_ha *oldha = NULL;
22769    int found = 0;
22770    int firstpass = 1;
22771    uint16_t port = 0;
22772    int format = 0;      /* Ama flags */
22773    time_t regseconds = 0;
22774    struct ast_flags peerflags[2] = {{(0)}};
22775    struct ast_flags mask[2] = {{(0)}};
22776    char callback[256] = "";
22777    struct sip_peer tmp_peer;
22778    const char *srvlookup = NULL;
22779    static int deprecation_warning = 1;
22780    int alt_fullcontact = alt ? 1 : 0;
22781    struct ast_str *fullcontact = ast_str_alloca(512);
22782 
22783    if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
22784       /* Note we do NOT use find_peer here, to avoid realtime recursion */
22785       /* We also use a case-sensitive comparison (unlike find_peer) so
22786          that case changes made to the peer name will be properly handled
22787          during reload
22788       */
22789       ast_copy_string(tmp_peer.name, name, sizeof(tmp_peer.name));
22790       peer = ao2_t_find(peers, &tmp_peer, OBJ_POINTER | OBJ_UNLINK, "find and unlink peer from peers table");
22791    }
22792 
22793    if (peer) {
22794       /* Already in the list, remove it and it will be added back (or FREE'd)  */
22795       found++;
22796       if (!(peer->the_mark))
22797          firstpass = 0;
22798    } else {
22799       if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct")))
22800          return NULL;
22801 
22802       if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
22803          ast_atomic_fetchadd_int(&rpeerobjs, 1);
22804          ast_debug(3, "-REALTIME- peer built. Name: %s. Peer objects: %d\n", name, rpeerobjs);
22805       } else
22806          ast_atomic_fetchadd_int(&speerobjs, 1);
22807    }
22808 
22809    /* Note that our peer HAS had its reference count increased */
22810    if (firstpass) {
22811       peer->lastmsgssent = -1;
22812       oldha = peer->ha;
22813       peer->ha = NULL;
22814       set_peer_defaults(peer);   /* Set peer defaults */
22815       peer->type = 0;
22816    }
22817    if (!found && name)
22818       ast_copy_string(peer->name, name, sizeof(peer->name));
22819 
22820    /* If we have channel variables, remove them (reload) */
22821    if (peer->chanvars) {
22822       ast_variables_destroy(peer->chanvars);
22823       peer->chanvars = NULL;
22824       /* XXX should unregister ? */
22825    }
22826 
22827    if (found)
22828       peer->portinuri = 0;
22829 
22830    /* If we have realm authentication information, remove them (reload) */
22831    clear_realm_authentication(peer->auth);
22832    peer->auth = NULL;
22833    peer->default_outbound_transport = 0;
22834    peer->transports = 0;
22835 
22836    for (; v || ((v = alt) && !(alt=NULL)); v = v->next) {
22837       if (!devstate_only) {
22838          if (handle_common_options(&peerflags[0], &mask[0], v)) {
22839             continue;
22840          }
22841          if (handle_t38_options(&peerflags[0], &mask[0], v, &peer->t38_maxdatagram)) {
22842             continue;
22843          }
22844          if (!strcasecmp(v->name, "transport") && !ast_strlen_zero(v->value)) {
22845             char *val = ast_strdupa(v->value);
22846             char *trans;
22847 
22848             while ((trans = strsep(&val, ","))) {
22849                trans = ast_skip_blanks(trans);
22850 
22851                if (!strncasecmp(trans, "udp", 3)) {
22852                   peer->transports |= SIP_TRANSPORT_UDP;
22853                } else if (!strncasecmp(trans, "tcp", 3)) {
22854                   peer->transports |= SIP_TRANSPORT_TCP;
22855                } else if (!strncasecmp(trans, "tls", 3)) {
22856                   peer->transports |= SIP_TRANSPORT_TLS;
22857                } else {
22858                   ast_log(LOG_NOTICE, "'%s' is not a valid transport type. if no other is specified, udp will be used.\n", trans);
22859                }
22860 
22861                if (!peer->default_outbound_transport) { /*!< The first transport listed should be default outbound */
22862                   peer->default_outbound_transport = peer->transports;
22863                }
22864             }
22865          } else if (realtime && !strcasecmp(v->name, "regseconds")) {
22866             ast_get_time_t(v->value, &regseconds, 0, NULL);
22867          } else if (realtime && !strcasecmp(v->name, "name")) {
22868             ast_copy_string(peer->name, v->value, sizeof(peer->name));
22869          } else if (!strcasecmp(v->name, "type")) {
22870             if (!strcasecmp(v->value, "peer")) {
22871                peer->type |= SIP_TYPE_PEER;
22872             } else if (!strcasecmp(v->value, "user")) {
22873                peer->type |= SIP_TYPE_USER;
22874             } else if (!strcasecmp(v->value, "friend")) {
22875                peer->type = SIP_TYPE_USER | SIP_TYPE_PEER;
22876             }
22877          } else if (!strcasecmp(v->name, "secret")) {
22878             ast_copy_string(peer->secret, v->value, sizeof(peer->secret));
22879          } else if (!strcasecmp(v->name, "md5secret")) {
22880             ast_copy_string(peer->md5secret, v->value, sizeof(peer->md5secret));
22881          } else if (!strcasecmp(v->name, "auth")) {
22882             peer->auth = add_realm_authentication(peer->auth, v->value, v->lineno);
22883          } else if (!strcasecmp(v->name, "callerid")) {
22884             ast_callerid_split(v->value, peer->cid_name, sizeof(peer->cid_name), peer->cid_num, sizeof(peer->cid_num));
22885          } else if (!strcasecmp(v->name, "fullname")) {
22886             ast_copy_string(peer->cid_name, v->value, sizeof(peer->cid_name));
22887          } else if (!strcasecmp(v->name, "trunkname")) {
22888             /* This is actually for a trunk, so we don't want to override callerid */
22889             ast_copy_string(peer->cid_name, "", sizeof(peer->cid_name));
22890          } else if (!strcasecmp(v->name, "cid_number")) {
22891             ast_copy_string(peer->cid_num, v->value, sizeof(peer->cid_num));
22892          } else if (!strcasecmp(v->name, "context")) {
22893             ast_copy_string(peer->context, v->value, sizeof(peer->context));
22894             ast_set_flag(&peer->flags[1], SIP_PAGE2_HAVEPEERCONTEXT);
22895          } else if (!strcasecmp(v->name, "subscribecontext")) {
22896             ast_copy_string(peer->subscribecontext, v->value, sizeof(peer->subscribecontext));
22897          } else if (!strcasecmp(v->name, "fromdomain")) {
22898             ast_copy_string(peer->fromdomain, v->value, sizeof(peer->fromdomain));
22899          } else if (!strcasecmp(v->name, "usereqphone")) {
22900             ast_set2_flag(&peer->flags[0], ast_true(v->value), SIP_USEREQPHONE);
22901          } else if (!strcasecmp(v->name, "fromuser")) {
22902             ast_copy_string(peer->fromuser, v->value, sizeof(peer->fromuser));
22903          } else if (!strcasecmp(v->name, "outboundproxy")) {
22904             char *port, *next, *force, *proxyname;
22905             int forceopt = FALSE;
22906             /* Set peer channel variable */
22907             next = proxyname = ast_strdupa(v->value);
22908             if ((port = strchr(proxyname, ':'))) {
22909                *port++ = '\0';
22910                next = port;
22911             }
22912             if ((force = strchr(next, ','))) {
22913                *force++ = '\0';
22914                forceopt = strcmp(force, "force");
22915             }
22916             /* Allocate proxy object */
22917             peer->outboundproxy = proxy_allocate(proxyname, port, forceopt);
22918          } else if (!strcasecmp(v->name, "host")) {
22919             if (!strcasecmp(v->value, "dynamic")) {
22920                /* They'll register with us */
22921                if (!found || !peer->host_dynamic) {
22922                   /* Initialize stuff if this is a new peer, or if it used to
22923                    * not be dynamic before the reload. */
22924                   memset(&peer->addr.sin_addr, 0, 4);
22925                   peer->addr.sin_port = 0;
22926                }
22927                peer->host_dynamic = TRUE;
22928             } else {
22929                /* Non-dynamic.  Make sure we become that way if we're not */
22930                AST_SCHED_DEL_UNREF(sched, peer->expire,
22931                      unref_peer(peer, "removing register expire ref"));
22932                /* the port will either be set to a default value or a config specified value once all option parsing is complete */
22933                peer->addr.sin_port = 0;
22934                peer->host_dynamic = FALSE;
22935                srvlookup = v->value;
22936                if (global_dynamic_exclude_static) {
22937                   int err = 0;
22938                   global_contact_ha = ast_append_ha("deny", (char *)ast_inet_ntoa(peer->addr.sin_addr), global_contact_ha, &err);
22939                   if (err) {
22940                      ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
22941                   }
22942                }
22943             }
22944          } else if (!strcasecmp(v->name, "defaultip")) {
22945             if (!ast_strlen_zero(v->value) && ast_get_ip(&peer->defaddr, v->value)) {
22946                unref_peer(peer, "unref_peer: from build_peer defaultip");
22947                return NULL;
22948             }
22949          } else if (!strcasecmp(v->name, "permit") || !strcasecmp(v->name, "deny")) {
22950             int ha_error = 0;
22951             if (!ast_strlen_zero(v->value)) {
22952                peer->ha = ast_append_ha(v->name, v->value, peer->ha, &ha_error);
22953             }
22954             if (ha_error) {
22955                ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
22956             }
22957          } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) {
22958             int ha_error = 0;
22959             if (!ast_strlen_zero(v->value)) {
22960                peer->contactha = ast_append_ha(v->name + 7, v->value, peer->contactha, &ha_error);
22961             }
22962             if (ha_error) {
22963                ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
22964             }
22965          } else if (!strcasecmp(v->name, "port")) {
22966             peer->portinuri = 1;
22967             if (!(port = port_str2int(v->value, 0))) {
22968                if (realtime) {
22969                   /* If stored as integer, could be 0 for some DBs (notably MySQL) */
22970                   peer->portinuri = 0;
22971                } else {
22972                   ast_log(LOG_WARNING, "Invalid peer port configuration at line %d : %s\n", v->lineno, v->value);
22973                }
22974             }
22975          } else if (!strcasecmp(v->name, "callingpres")) {
22976             peer->callingpres = ast_parse_caller_presentation(v->value);
22977             if (peer->callingpres == -1) {
22978                peer->callingpres = atoi(v->value);
22979             }
22980          } else if (!strcasecmp(v->name, "username") || !strcmp(v->name, "defaultuser")) {   /* "username" is deprecated */
22981             ast_copy_string(peer->username, v->value, sizeof(peer->username));
22982             if (!strcasecmp(v->name, "username")) {
22983                if (deprecation_warning) {
22984                   ast_log(LOG_NOTICE, "The 'username' field for sip peers has been deprecated in favor of the term 'defaultuser'\n");
22985                   deprecation_warning = 0;
22986                }
22987                peer->deprecated_username = 1;
22988             }
22989          } else if (!strcasecmp(v->name, "language")) {
22990             ast_copy_string(peer->language, v->value, sizeof(peer->language));
22991          } else if (!strcasecmp(v->name, "regexten")) {
22992             ast_copy_string(peer->regexten, v->value, sizeof(peer->regexten));
22993          } else if (!strcasecmp(v->name, "callbackextension")) {
22994             ast_copy_string(callback, v->value, sizeof(callback));
22995          } else if (!strcasecmp(v->name, "amaflags")) {
22996             format = ast_cdr_amaflags2int(v->value);
22997             if (format < 0) {
22998                ast_log(LOG_WARNING, "Invalid AMA Flags for peer: %s at line %d\n", v->value, v->lineno);
22999             } else {
23000                peer->amaflags = format;
23001             }
23002          } else if (!strcasecmp(v->name, "accountcode")) {
23003             ast_copy_string(peer->accountcode, v->value, sizeof(peer->accountcode));
23004          } else if (!strcasecmp(v->name, "mohinterpret")) {
23005             ast_copy_string(peer->mohinterpret, v->value, sizeof(peer->mohinterpret));
23006          } else if (!strcasecmp(v->name, "mohsuggest")) {
23007             ast_copy_string(peer->mohsuggest, v->value, sizeof(peer->mohsuggest));
23008          } else if (!strcasecmp(v->name, "parkinglot")) {
23009             ast_copy_string(peer->parkinglot, v->value, sizeof(peer->parkinglot));
23010          } else if (!strcasecmp(v->name, "mailbox")) {
23011             add_peer_mailboxes(peer, v->value);
23012          } else if (!strcasecmp(v->name, "hasvoicemail")) {
23013             /* People expect that if 'hasvoicemail' is set, that the mailbox will
23014              * be also set, even if not explicitly specified. */
23015             if (ast_true(v->value) && AST_LIST_EMPTY(&peer->mailboxes)) {
23016                add_peer_mailboxes(peer, name);
23017             }
23018          } else if (!strcasecmp(v->name, "subscribemwi")) {
23019             ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_SUBSCRIBEMWIONLY);
23020          } else if (!strcasecmp(v->name, "vmexten")) {
23021             ast_copy_string(peer->vmexten, v->value, sizeof(peer->vmexten));
23022          } else if (!strcasecmp(v->name, "callgroup")) {
23023             peer->callgroup = ast_get_group(v->value);
23024          } else if (!strcasecmp(v->name, "allowtransfer")) {
23025             peer->allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
23026          } else if (!strcasecmp(v->name, "pickupgroup")) {
23027             peer->pickupgroup = ast_get_group(v->value);
23028          } else if (!strcasecmp(v->name, "allow")) {
23029             int error =  ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, TRUE);
23030             if (error) {
23031                ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
23032             }
23033          } else if (!strcasecmp(v->name, "disallow")) {
23034             int error =  ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, FALSE);
23035             if (error) {
23036                ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
23037             }
23038          } else if (!strcasecmp(v->name, "registertrying")) {
23039             ast_set2_flag(&peer->flags[1], ast_true(v->value), SIP_PAGE2_REGISTERTRYING);
23040          } else if (!strcasecmp(v->name, "autoframing")) {
23041             peer->autoframing = ast_true(v->value);
23042          } else if (!strcasecmp(v->name, "rtptimeout")) {
23043             if ((sscanf(v->value, "%30d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) {
23044                ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
23045                peer->rtptimeout = global_rtptimeout;
23046             }
23047          } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
23048             if ((sscanf(v->value, "%30d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) {
23049                ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
23050                peer->rtpholdtimeout = global_rtpholdtimeout;
23051             }
23052          } else if (!strcasecmp(v->name, "rtpkeepalive")) {
23053             if ((sscanf(v->value, "%30d", &peer->rtpkeepalive) != 1) || (peer->rtpkeepalive < 0)) {
23054                ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
23055                peer->rtpkeepalive = global_rtpkeepalive;
23056             }
23057          } else if (!strcasecmp(v->name, "timert1")) {
23058             if ((sscanf(v->value, "%30d", &peer->timer_t1) != 1) || (peer->timer_t1 < 0)) {
23059                ast_log(LOG_WARNING, "'%s' is not a valid T1 time at line %d.  Using default.\n", v->value, v->lineno);
23060                peer->timer_t1 = global_t1;
23061             }
23062             /* Note that Timer B is dependent upon T1 and MUST NOT be lower
23063              * than T1 * 64, according to RFC 3261, Section 17.1.1.2 */
23064             if (peer->timer_b < peer->timer_t1 * 64) {
23065                peer->timer_b = peer->timer_t1 * 64;
23066             }
23067          } else if (!strcasecmp(v->name, "timerb")) {
23068             if ((sscanf(v->value, "%30d", &peer->timer_b) != 1) || (peer->timer_b < 0)) {
23069                ast_log(LOG_WARNING, "'%s' is not a valid Timer B time at line %d.  Using default.\n", v->value, v->lineno);
23070                peer->timer_b = global_timer_b;
23071             }
23072             if (peer->timer_b < peer->timer_t1 * 64) {
23073                static int warning = 0;
23074                if (warning++ % 20 == 0) {
23075                   ast_log(LOG_WARNING, "Timer B has been set lower than recommended. (RFC 3261, 17.1.1.2)\n");
23076                }
23077             }
23078          } else if (!strcasecmp(v->name, "setvar")) {
23079             peer->chanvars = add_var(v->value, peer->chanvars);
23080          } else if (!strcasecmp(v->name, "qualifyfreq")) {
23081             int i;
23082             if (sscanf(v->value, "%30d", &i) == 1) {
23083                peer->qualifyfreq = i * 1000;
23084             } else {
23085                ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config);
23086                peer->qualifyfreq = global_qualifyfreq;
23087             }
23088          } else if (!strcasecmp(v->name, "maxcallbitrate")) {
23089             peer->maxcallbitrate = atoi(v->value);
23090             if (peer->maxcallbitrate < 0) {
23091                peer->maxcallbitrate = default_maxcallbitrate;
23092             }
23093          } else if (!strcasecmp(v->name, "session-timers")) {
23094             int i = (int) str2stmode(v->value);
23095             if (i < 0) {
23096                ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config);
23097                peer->stimer.st_mode_oper = global_st_mode;
23098             } else {
23099                peer->stimer.st_mode_oper = i;
23100             }
23101          } else if (!strcasecmp(v->name, "session-expires")) {
23102             if (sscanf(v->value, "%30d", &peer->stimer.st_max_se) != 1) {
23103                ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config);
23104                peer->stimer.st_max_se = global_max_se;
23105             }
23106          } else if (!strcasecmp(v->name, "session-minse")) {
23107             if (sscanf(v->value, "%30d", &peer->stimer.st_min_se) != 1) {
23108                ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config);
23109                peer->stimer.st_min_se = global_min_se;
23110             }
23111             if (peer->stimer.st_min_se < 90) {
23112                ast_log(LOG_WARNING, "session-minse '%s' at line %d of %s is not allowed to be < 90 secs\n", v->value, v->lineno, config);
23113                peer->stimer.st_min_se = global_min_se;
23114             }
23115          } else if (!strcasecmp(v->name, "session-refresher")) {
23116             int i = (int) str2strefresher(v->value);
23117             if (i < 0) {
23118                ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config);
23119                peer->stimer.st_ref = global_st_refresher;
23120             } else {
23121                peer->stimer.st_ref = i;
23122             }
23123          }
23124       }
23125 
23126       /* These apply to devstate lookups */
23127       if (realtime && !strcasecmp(v->name, "lastms")) {
23128          sscanf(v->value, "%30d", &peer->lastms);
23129       } else if (realtime && !strcasecmp(v->name, "ipaddr") && !ast_strlen_zero(v->value) ) {
23130          inet_aton(v->value, &(peer->addr.sin_addr));
23131       } else if (realtime && !strcasecmp(v->name, "fullcontact")) {
23132          if (alt_fullcontact && !alt) {
23133             /* Reset, because the alternate also has a fullcontact and we
23134              * do NOT want the field value to be doubled. It might be
23135              * tempting to skip this, but the first table might not have
23136              * fullcontact and since we're here, we know that the alternate
23137              * absolutely does. */
23138             alt_fullcontact = 0;
23139             ast_str_reset(fullcontact);
23140          }
23141          /* Reconstruct field, because realtime separates our value at the ';' */
23142          if (fullcontact->used > 0) {
23143             ast_str_append(&fullcontact, 0, ";%s", v->value);
23144          } else {
23145             ast_str_set(&fullcontact, 0, "%s", v->value);
23146          }
23147       } else if (!strcasecmp(v->name, "qualify")) {
23148          if (!strcasecmp(v->value, "no")) {
23149             peer->maxms = 0;
23150          } else if (!strcasecmp(v->value, "yes")) {
23151             peer->maxms = default_qualify ? default_qualify : DEFAULT_MAXMS;
23152          } else if (sscanf(v->value, "%30d", &peer->maxms) != 1) {
23153             ast_log(LOG_WARNING, "Qualification of peer '%s' should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", peer->name, v->lineno);
23154             peer->maxms = 0;
23155          }
23156          if (realtime && !ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->maxms > 0) {
23157             /* This would otherwise cause a network storm, where the
23158              * qualify response refreshes the peer from the database,
23159              * which in turn causes another qualify to be sent, ad
23160              * infinitum. */
23161             ast_log(LOG_WARNING, "Qualify is incompatible with dynamic uncached realtime.  Please either turn rtcachefriends on or turn qualify off on peer '%s'\n", peer->name);
23162             peer->maxms = 0;
23163          }
23164       } else if (!strcasecmp(v->name, "callcounter")) {
23165          peer->call_limit = ast_true(v->value) ? INT_MAX : 0;
23166       } else if (!strcasecmp(v->name, "call-limit")) {
23167          peer->call_limit = atoi(v->value);
23168          if (peer->call_limit < 0) {
23169             peer->call_limit = 0;
23170          }
23171       } else if (!strcasecmp(v->name, "busylevel")) {
23172          peer->busy_level = atoi(v->value);
23173          if (peer->busy_level < 0) {
23174             peer->busy_level = 0;
23175          }
23176       }
23177    }
23178 
23179    if (!peer->default_outbound_transport) {
23180       peer->transports = SIP_TRANSPORT_UDP;
23181       peer->default_outbound_transport = SIP_TRANSPORT_UDP;
23182    }
23183 
23184    /* The default transport type set during build_peer should only replace the socket.type when...
23185     * 1. Registration is not present and the socket.type and default transport types are different.
23186     * 2. The socket.type is not an acceptable transport type after rebuilding peer.
23187     * 3. The socket.type is not set yet. */
23188    if (((peer->socket.type != peer->default_outbound_transport) && (peer->expire == -1)) ||
23189       !(peer->socket.type & peer->transports) || !(peer->socket.type)) {
23190 
23191       set_socket_transport(&peer->socket, peer->default_outbound_transport);
23192    }
23193 
23194    if (port && !realtime && peer->host_dynamic) {
23195       peer->defaddr.sin_port = htons(port);
23196    } else if (port) {
23197       peer->addr.sin_port = htons(port);
23198    }
23199 
23200    if (ast_str_strlen(fullcontact)) {
23201       ast_copy_string(peer->fullcontact, fullcontact->str, sizeof(peer->fullcontact));
23202       peer->rt_fromcontact = TRUE;
23203       /* We have a hostname in the fullcontact, but if we don't have an
23204        * address listed on the entry (or if it's 'dynamic'), then we need to
23205        * parse the entry to obtain the IP address, so a dynamic host can be
23206        * contacted immediately after reload (as opposed to waiting for it to
23207        * register once again). But if we have an address for this peer and NAT was
23208        * specified, use that address instead. */
23209       /* XXX May need to revisit the final argument; does the realtime DB store whether
23210        * the original contact was over TLS or not? XXX */
23211       if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE) || !peer->addr.sin_addr.s_addr) {
23212          __set_address_from_contact(fullcontact->str, &peer->addr, 0);
23213       }
23214    }
23215 
23216    if (srvlookup && peer->dnsmgr == NULL) {
23217       char transport[MAXHOSTNAMELEN];
23218       char _srvlookup[MAXHOSTNAMELEN];
23219       char *params;
23220 
23221       ast_copy_string(_srvlookup, srvlookup, sizeof(_srvlookup));
23222       if ((params = strchr(_srvlookup, ';'))) {
23223          *params++ = '\0';
23224       }
23225 
23226       snprintf(transport, sizeof(transport), "_sip._%s", get_transport(peer->socket.type));
23227 
23228       if (ast_dnsmgr_lookup(_srvlookup, &peer->addr, &peer->dnsmgr, global_srvlookup && !peer->portinuri ? transport : NULL)) {
23229          ast_log(LOG_ERROR, "srvlookup failed for host: %s, on peer %s, removing peer\n", _srvlookup, peer->name);
23230          unref_peer(peer, "getting rid of a peer pointer");
23231          return NULL;
23232       }
23233 
23234       ast_copy_string(peer->tohost, srvlookup, sizeof(peer->tohost));
23235    }
23236 
23237    if (!peer->addr.sin_port) {
23238       peer->addr.sin_port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT));
23239    }
23240    if (!peer->defaddr.sin_port) {
23241       peer->defaddr.sin_port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT));
23242    }
23243    if (!peer->socket.port) {
23244       peer->socket.port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT));
23245    }
23246 
23247    if (!sip_cfg.ignore_regexpire && peer->host_dynamic && realtime) {
23248       time_t nowtime = time(NULL);
23249 
23250       if ((nowtime - regseconds) > 0) {
23251          destroy_association(peer);
23252          memset(&peer->addr, 0, sizeof(peer->addr));
23253          peer->lastms = -1;
23254          ast_debug(1, "Bah, we're expired (%d/%d/%d)!\n", (int)(nowtime - regseconds), (int)regseconds, (int)nowtime);
23255       }
23256    }
23257 
23258    /* Startup regular pokes */
23259    if (!devstate_only && realtime && peer->lastms > 0) {
23260       ref_peer(peer, "schedule qualify");
23261       sip_poke_peer(peer, 0);
23262    }
23263 
23264    ast_copy_flags(&peer->flags[0], &peerflags[0], mask[0].flags);
23265    ast_copy_flags(&peer->flags[1], &peerflags[1], mask[1].flags);
23266    if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
23267       global_allowsubscribe = TRUE; /* No global ban any more */
23268    }
23269    if (!found && peer->host_dynamic && !peer->is_realtime) {
23270       reg_source_db(peer);
23271    }
23272 
23273    /* If they didn't request that MWI is sent *only* on subscribe, go ahead and
23274     * subscribe to it now. */
23275    if (!devstate_only && !ast_test_flag(&peer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY) &&
23276       !AST_LIST_EMPTY(&peer->mailboxes)) {
23277       add_peer_mwi_subs(peer);
23278       /* Send MWI from the event cache only.  This is so we can send initial
23279        * MWI if app_voicemail got loaded before chan_sip.  If it is the other
23280        * way, then we will get events when app_voicemail gets loaded. */
23281       sip_send_mwi_to_peer(peer, NULL, 1);
23282    }
23283 
23284    peer->the_mark = 0;
23285 
23286    ast_free_ha(oldha);
23287    if (!ast_strlen_zero(callback)) { /* build string from peer info */
23288       char *reg_string;
23289 
23290       if (asprintf(&reg_string, "%s?%s:%s@%s/%s", peer->name, peer->username, peer->secret, peer->tohost, callback) < 0) {
23291          ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
23292       } else if (reg_string) {
23293          sip_register(reg_string, 0); /* XXX TODO: count in registry_count */
23294          ast_free(reg_string);
23295       }
23296    }
23297    return peer;
23298 }

static int build_reply_digest ( struct sip_pvt p,
int  method,
char *  digest,
int  digest_len 
) [static]

Build reply digest.

Returns:
Returns -1 if we have no auth
Note:
Build digest challenge for authentication of registrations and calls Also used for authentication of BYE

Definition at line 16335 of file chan_sip.c.

References append_history, ast_copy_string(), ast_debug, ast_inet_ntoa(), ast_log(), ast_md5_hash(), ast_random(), ast_strlen_zero(), authl, sip_pvt::authname, sip_pvt::callid, sip_pvt::domain, find_realm_authentication(), LOG_DEBUG, sip_auth::md5secret, sip_registry::md5secret, sip_pvt::nonce, sip_pvt::noncecount, sip_pvt::opaque, sip_registry::opaque, sip_pvt::peerauth, sip_pvt::peermd5secret, sip_pvt::peername, sip_pvt::peersecret, sip_pvt::qop, sip_pvt::realm, sip_pvt::sa, sip_auth::secret, secret, sip_methods, text, sip_pvt::uri, sip_auth::username, sip_pvt::username, and sip_registry::username.

Referenced by reply_digest(), transmit_register(), and transmit_request_with_auth().

16336 {
16337    char a1[256];
16338    char a2[256];
16339    char a1_hash[256];
16340    char a2_hash[256];
16341    char resp[256];
16342    char resp_hash[256];
16343    char uri[256];
16344    char opaque[256] = "";
16345    char cnonce[80];
16346    const char *username;
16347    const char *secret;
16348    const char *md5secret;
16349    struct sip_auth *auth = NULL; /* Realm authentication */
16350 
16351    if (!ast_strlen_zero(p->domain))
16352       ast_copy_string(uri, p->domain, sizeof(uri));
16353    else if (!ast_strlen_zero(p->uri))
16354       ast_copy_string(uri, p->uri, sizeof(uri));
16355    else
16356       snprintf(uri, sizeof(uri), "sip:%s@%s", p->username, ast_inet_ntoa(p->sa.sin_addr));
16357 
16358    snprintf(cnonce, sizeof(cnonce), "%08lx", ast_random());
16359 
16360    /* Check if we have separate auth credentials */
16361    if(!(auth = find_realm_authentication(p->peerauth, p->realm))) /* Start with peer list */
16362       auth = find_realm_authentication(authl, p->realm); /* If not, global list */
16363 
16364    if (auth) {
16365       ast_log(LOG_DEBUG, "use realm [%s] from peer [%s][%s]\n", auth->username, p->peername, p->username);
16366       username = auth->username;
16367       secret = auth->secret;
16368       md5secret = auth->md5secret;
16369       if (sipdebug)
16370          ast_debug(1, "Using realm %s authentication for call %s\n", p->realm, p->callid);
16371    } else {
16372       /* No authentication, use peer or register= config */
16373       username = p->authname;
16374       secret =  p->peersecret;
16375       md5secret = p->peermd5secret;
16376    }
16377    if (ast_strlen_zero(username))   /* We have no authentication */
16378       return -1;
16379 
16380    /* Calculate SIP digest response */
16381    snprintf(a1, sizeof(a1), "%s:%s:%s", username, p->realm, secret);
16382    snprintf(a2, sizeof(a2), "%s:%s", sip_methods[method].text, uri);
16383    if (!ast_strlen_zero(md5secret))
16384       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
16385    else
16386       ast_md5_hash(a1_hash, a1);
16387    ast_md5_hash(a2_hash, a2);
16388 
16389    p->noncecount++;
16390    if (!ast_strlen_zero(p->qop))
16391       snprintf(resp, sizeof(resp), "%s:%s:%08x:%s:%s:%s", a1_hash, p->nonce, p->noncecount, cnonce, "auth", a2_hash);
16392    else
16393       snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, p->nonce, a2_hash);
16394    ast_md5_hash(resp_hash, resp);
16395 
16396    /* only include the opaque string if it's set */
16397    if (!ast_strlen_zero(p->opaque)) {
16398      snprintf(opaque, sizeof(opaque), ", opaque=\"%s\"", p->opaque);
16399    }
16400 
16401    /* XXX We hard code our qop to "auth" for now.  XXX */
16402    if (!ast_strlen_zero(p->qop))
16403       snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s, qop=auth, cnonce=\"%s\", nc=%08x", username, p->realm, uri, p->nonce, resp_hash, opaque, cnonce, p->noncecount);
16404    else
16405       snprintf(digest, digest_len, "Digest username=\"%s\", realm=\"%s\", algorithm=MD5, uri=\"%s\", nonce=\"%s\", response=\"%s\"%s", username, p->realm, uri, p->nonce, resp_hash, opaque);
16406 
16407    append_history(p, "AuthResp", "Auth response sent for %s in realm %s - nc %d", username, p->realm, p->noncecount);
16408 
16409    return 0;
16410 }

static void build_route ( struct sip_pvt p,
struct sip_request req,
int  backwards 
) [static]

Build route list from Record-Route header.

Definition at line 11650 of file chan_sip.c.

References __get_header(), ast_copy_string(), ast_debug, ast_malloc, ast_strlen_zero(), free_old_route(), get_header(), sip_route::hop, list_route(), sip_route::next, sip_pvt::route, sip_pvt::route_persistant, and sip_debug_test_pvt().

Referenced by build_user_routes(), handle_request_invite(), handle_request_subscribe(), and handle_response_invite().

11651 {
11652    struct sip_route *thishop, *head, *tail;
11653    int start = 0;
11654    int len;
11655    const char *rr, *contact, *c;
11656 
11657    /* Once a persistant route is set, don't fool with it */
11658    if (p->route && p->route_persistant) {
11659       ast_debug(1, "build_route: Retaining previous route: <%s>\n", p->route->hop);
11660       return;
11661    }
11662 
11663    if (p->route) {
11664       free_old_route(p->route);
11665       p->route = NULL;
11666    }
11667 
11668    /* We only want to create the route set the first time this is called */
11669    p->route_persistant = 1;
11670    
11671    /* Build a tailq, then assign it to p->route when done.
11672     * If backwards, we add entries from the head so they end up
11673     * in reverse order. However, we do need to maintain a correct
11674     * tail pointer because the contact is always at the end.
11675     */
11676    head = NULL;
11677    tail = head;
11678    /* 1st we pass through all the hops in any Record-Route headers */
11679    for (;;) {
11680       /* Each Record-Route header */
11681       rr = __get_header(req, "Record-Route", &start);
11682       if (*rr == '\0')
11683          break;
11684       for (; (rr = strchr(rr, '<')) ; rr += len) { /* Each route entry */
11685          ++rr;
11686          len = strcspn(rr, ">") + 1;
11687          /* Make a struct route */
11688          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
11689             /* ast_calloc is not needed because all fields are initialized in this block */
11690             ast_copy_string(thishop->hop, rr, len);
11691             ast_debug(2, "build_route: Record-Route hop: <%s>\n", thishop->hop);
11692             /* Link in */
11693             if (backwards) {
11694                /* Link in at head so they end up in reverse order */
11695                thishop->next = head;
11696                head = thishop;
11697                /* If this was the first then it'll be the tail */
11698                if (!tail)
11699                   tail = thishop;
11700             } else {
11701                thishop->next = NULL;
11702                /* Link in at the end */
11703                if (tail)
11704                   tail->next = thishop;
11705                else
11706                   head = thishop;
11707                tail = thishop;
11708             }
11709          }
11710       }
11711    }
11712 
11713    /* Only append the contact if we are dealing with a strict router */
11714    if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop, ";lr") == NULL) ) {
11715       /* 2nd append the Contact: if there is one */
11716       /* Can be multiple Contact headers, comma separated values - we just take the first */
11717       contact = get_header(req, "Contact");
11718       if (!ast_strlen_zero(contact)) {
11719          ast_debug(2, "build_route: Contact hop: %s\n", contact);
11720          /* Look for <: delimited address */
11721          c = strchr(contact, '<');
11722          if (c) {
11723             /* Take to > */
11724             ++c;
11725             len = strcspn(c, ">") + 1;
11726          } else {
11727             /* No <> - just take the lot */
11728             c = contact;
11729             len = strlen(contact) + 1;
11730          }
11731          if ((thishop = ast_malloc(sizeof(*thishop) + len))) {
11732             /* ast_calloc is not needed because all fields are initialized in this block */
11733             ast_copy_string(thishop->hop, c, len);
11734             thishop->next = NULL;
11735             /* Goes at the end */
11736             if (tail)
11737                tail->next = thishop;
11738             else
11739                head = thishop;
11740          }
11741       }
11742    }
11743 
11744    /* Store as new route */
11745    p->route = head;
11746 
11747    /* For debugging dump what we ended up with */
11748    if (sip_debug_test_pvt(p))
11749       list_route(p->route);
11750 }

static void build_rpid ( struct sip_pvt p  )  [static]

Build the Remote Party-ID & From using callingpres options.

Definition at line 9944 of file chan_sip.c.

References ast_inet_ntoa(), ast_log(), AST_PRES_ALLOWED, AST_PRES_ALLOWED_NETWORK_NUMBER, AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN, AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN, AST_PRES_NUMBER_NOT_AVAILABLE, AST_PRES_PROHIB_NETWORK_NUMBER, AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN, AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED, AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN, AST_PRES_RESTRICTION, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), buf, sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, FALSE, sip_pvt::fromdomain, sip_pvt::fromuser, LOG_WARNING, sip_pvt::ourip, sip_pvt::owner, sip_pvt::rpid, sip_pvt::rpid_from, S_OR, sip_pvt::tag, and TRUE.

Referenced by initreqprep().

09945 {
09946    int send_pres_tags = TRUE;
09947    const char *privacy=NULL;
09948    const char *screen=NULL;
09949    char buf[256];
09950    const char *clid = default_callerid;
09951    const char *clin = NULL;
09952    const char *fromdomain;
09953 
09954    if (!ast_strlen_zero(p->rpid) || !ast_strlen_zero(p->rpid_from))  
09955       return;
09956 
09957    if (p->owner && !ast_strlen_zero(p->owner->cid.cid_num))
09958       clid = p->owner->cid.cid_num;
09959    if (p->owner && p->owner->cid.cid_name)
09960       clin = p->owner->cid.cid_name;
09961    if (ast_strlen_zero(clin))
09962       clin = clid;
09963 
09964    switch (p->callingpres) {
09965    case AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED:
09966       privacy = "off";
09967       screen = "no";
09968       break;
09969    case AST_PRES_ALLOWED_USER_NUMBER_PASSED_SCREEN:
09970       privacy = "off";
09971       screen = "yes";
09972       break;
09973    case AST_PRES_ALLOWED_USER_NUMBER_FAILED_SCREEN:
09974       privacy = "off";
09975       screen = "no";
09976       break;
09977    case AST_PRES_ALLOWED_NETWORK_NUMBER:
09978       privacy = "off";
09979       screen = "yes";
09980       break;
09981    case AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED:
09982       privacy = "full";
09983       screen = "no";
09984       break;
09985    case AST_PRES_PROHIB_USER_NUMBER_PASSED_SCREEN:
09986       privacy = "full";
09987       screen = "yes";
09988       break;
09989    case AST_PRES_PROHIB_USER_NUMBER_FAILED_SCREEN:
09990       privacy = "full";
09991       screen = "no";
09992       break;
09993    case AST_PRES_PROHIB_NETWORK_NUMBER:
09994       privacy = "full";
09995       screen = "yes";
09996       break;
09997    case AST_PRES_NUMBER_NOT_AVAILABLE:
09998       send_pres_tags = FALSE;
09999       break;
10000    default:
10001       ast_log(LOG_WARNING, "Unsupported callingpres (%d)\n", p->callingpres);
10002       if ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)
10003          privacy = "full";
10004       else
10005          privacy = "off";
10006       screen = "no";
10007       break;
10008    }
10009    
10010    fromdomain = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip.sin_addr));
10011 
10012    snprintf(buf, sizeof(buf), "\"%s\" <sip:%s@%s>", clin, clid, fromdomain);
10013    if (send_pres_tags)
10014       snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), ";privacy=%s;screen=%s", privacy, screen);
10015    ast_string_field_set(p, rpid, buf);
10016 
10017    ast_string_field_build(p, rpid_from, "\"%s\" <sip:%s@%s>;tag=%s", clin,
10018                 S_OR(p->fromuser, clid),
10019                 fromdomain, p->tag);
10020 }

static void build_via ( struct sip_pvt p  )  [static]

Build a Via header for a request.

Definition at line 3205 of file chan_sip.c.

References ast_inet_ntoa(), ast_test_flag, sip_pvt::branch, sip_pvt::flags, get_transport_pvt(), sip_pvt::ourip, SIP_NAT, SIP_NAT_RFC3581, and sip_pvt::via.

Referenced by manager_sipnotify(), reqprep(), sip_alloc(), sip_cli_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), transmit_invite(), transmit_register(), and transmit_response_using_temp().

03206 {
03207    /* Work around buggy UNIDEN UIP200 firmware */
03208    const char *rport = ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_RFC3581 ? ";rport" : "";
03209 
03210    /* z9hG4bK is a magic cookie.  See RFC 3261 section 8.1.1.7 */
03211    snprintf(p->via, sizeof(p->via), "SIP/2.0/%s %s:%d;branch=z9hG4bK%08x%s",
03212        get_transport_pvt(p),
03213        ast_inet_ntoa(p->ourip.sin_addr),
03214        ntohs(p->ourip.sin_port), (int) p->branch, rport);
03215 }

static int cb_extensionstate ( char *  context,
char *  exten,
int  state,
void *  data 
) [static]

Callback for the devicestate notification (SUBSCRIBE) support subsystem.

Note:
If you add an "hint" priority to the extension in the dial plan, you will get notifications on device state changes

Definition at line 11982 of file chan_sip.c.

References append_history, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_REMOVED, ast_extension_state2str(), ast_log(), ast_set_flag, ast_test_flag, ast_verb, sip_pvt::autokillid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, sip_pvt::laststate, LOG_WARNING, NONE, sip_pvt::pendinginvite, sip_cancel_destroy(), SIP_PAGE2_STATECHANGEQUEUE, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), sip_pvt::stateid, sip_pvt::subscribed, transmit_state_notify(), and sip_pvt::username.

Referenced by handle_request_subscribe(), handle_response(), and handle_response_notify().

11983 {
11984    struct sip_pvt *p = data;
11985 
11986    sip_pvt_lock(p);
11987 
11988    switch(state) {
11989    case AST_EXTENSION_DEACTIVATED:  /* Retry after a while */
11990    case AST_EXTENSION_REMOVED:   /* Extension is gone */
11991       if (p->autokillid > -1 && sip_cancel_destroy(p))   /* Remove subscription expiry for renewals */
11992          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
11993       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);  /* Delete subscription in 32 secs */
11994       ast_verb(2, "Extension state: Watcher for hint %s %s. Notify User %s\n", exten, state == AST_EXTENSION_DEACTIVATED ? "deactivated" : "removed", p->username);
11995       p->stateid = -1;
11996       p->subscribed = NONE;
11997       append_history(p, "Subscribestatus", "%s", state == AST_EXTENSION_REMOVED ? "HintRemoved" : "Deactivated");
11998       break;
11999    default: /* Tell user */
12000       p->laststate = state;
12001       break;
12002    }
12003    if (p->subscribed != NONE) {  /* Only send state NOTIFY if we know the format */
12004       if (!p->pendinginvite) {
12005          transmit_state_notify(p, state, 1, FALSE);
12006       } else {
12007          /* We already have a NOTIFY sent that is not answered. Queue the state up.
12008             if many state changes happen meanwhile, we will only send a notification of the last one */
12009          ast_set_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
12010       }
12011    }
12012    ast_verb(2, "Extension Changed %s[%s] new state %s for Notify User %s %s\n", exten, context, ast_extension_state2str(state), p->username,
12013          ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE) ? "(queued)" : "");
12014 
12015    sip_pvt_unlock(p);
12016 
12017    return 0;
12018 }

static void change_t38_state ( struct sip_pvt p,
int  state 
) [static]

Change the T38 state on a SIP dialog.

Definition at line 4644 of file chan_sip.c.

References AST_CONTROL_T38_PARAMETERS, ast_debug, ast_queue_control_data(), AST_T38_NEGOTIATED, AST_T38_REFUSED, AST_T38_REQUEST_NEGOTIATE, AST_T38_TERMINATED, ast_udptl_get_far_max_ifp(), ast_udptl_set_tag(), chan, ast_control_t38_parameters::max_ifp, ast_channel::name, sip_pvt::owner, ast_control_t38_parameters::request_response, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_REINVITE, T38_PEER_REINVITE, t38properties::their_parms, sip_pvt::udptl, and sip_pvt::username.

Referenced by handle_response_invite(), interpret_t38_parameters(), process_sdp(), and sip_t38_abort().

04645 {
04646    int old = p->t38.state;
04647    struct ast_channel *chan = p->owner;
04648    struct ast_control_t38_parameters parameters = { .request_response = 0 };
04649 
04650    /* Don't bother changing if we are already in the state wanted */
04651    if (old == state)
04652       return;
04653 
04654    p->t38.state = state;
04655    ast_debug(2, "T38 state changed to %d on channel %s\n", p->t38.state, chan ? chan->name : "<none>");
04656 
04657    /* If no channel was provided we can't send off a control frame */
04658    if (!chan)
04659       return;
04660 
04661    /* Given the state requested and old state determine what control frame we want to queue up */
04662    switch (state) {
04663    case T38_PEER_REINVITE:
04664       parameters = p->t38.their_parms;
04665       parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
04666       parameters.request_response = AST_T38_REQUEST_NEGOTIATE;
04667       ast_udptl_set_tag(p->udptl, "SIP/%s", p->username);
04668       break;
04669    case T38_ENABLED:
04670       parameters = p->t38.their_parms;
04671       parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl);
04672       parameters.request_response = AST_T38_NEGOTIATED;
04673       ast_udptl_set_tag(p->udptl, "SIP/%s", p->username);
04674       break;
04675    case T38_DISABLED:
04676       if (old == T38_ENABLED) {
04677          parameters.request_response = AST_T38_TERMINATED;
04678       } else if (old == T38_LOCAL_REINVITE) {
04679          parameters.request_response = AST_T38_REFUSED;
04680       }
04681       break;
04682    case T38_LOCAL_REINVITE:
04683       /* wait until we get a peer response before responding to local reinvite */
04684       break;
04685    }
04686 
04687    /* Woot we got a message, create a control frame and send it on! */
04688    if (parameters.request_response)
04689       ast_queue_control_data(chan, AST_CONTROL_T38_PARAMETERS, &parameters, sizeof(parameters));
04690 }

static enum check_auth_result check_auth ( struct sip_pvt p,
struct sip_request req,
const char *  username,
const char *  secret,
const char *  md5secret,
int  sipmethod,
char *  uri,
enum xmittype  reliable,
int  ignore 
) [static]

Check user authorization from peer definition Some actions, like REGISTER and INVITEs from peers require authentication (if peer have secret set).

Returns:
0 on success, non-zero on error

XXX

Todo:
need a better return code here

XXX

Todo:
need a better return code here

Definition at line 11774 of file chan_sip.c.

References append_history, ast_copy_string(), AST_DYNSTR_BUILD_FAILED, ast_log(), ast_md5_hash(), ast_skip_blanks(), ast_str_set(), ast_str_thread_get(), ast_strlen_zero(), AUTH_CHALLENGE_SENT, auth_headers(), AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, AUTH_USERNAME_MISMATCH, buf, check_auth_buf, CHECK_AUTH_BUF_INITLEN, DEFAULT_TRANS_TIMEOUT, FALSE, get_header(), sip_request::ignore, LOG_NOTICE, LOG_WARNING, sip_pvt::randdata, s, S_OR, set_nonce_randdata(), sip_methods, sip_scheddestroy(), sip_pvt::stalenonce, strsep(), text, transmit_response_with_auth(), TRUE, and WWW_AUTH.

Referenced by check_peer_ok(), and register_verify().

11777 {
11778    const char *response;
11779    char *reqheader, *respheader;
11780    const char *authtoken;
11781    char a1_hash[256];
11782    char resp_hash[256]="";
11783    char *c;
11784    int  wrongnonce = FALSE;
11785    int  good_response;
11786    const char *usednonce = p->randdata;
11787    struct ast_str *buf;
11788    int res;
11789 
11790    /* table of recognised keywords, and their value in the digest */
11791    enum keys { K_RESP, K_URI, K_USER, K_NONCE, K_LAST };
11792    struct x {
11793       const char *key;
11794       const char *s;
11795    } *i, keys[] = {
11796       [K_RESP] = { "response=", "" },
11797       [K_URI] = { "uri=", "" },
11798       [K_USER] = { "username=", "" },
11799       [K_NONCE] = { "nonce=", "" },
11800       [K_LAST] = { NULL, NULL}
11801    };
11802 
11803    /* Always OK if no secret */
11804    if (ast_strlen_zero(secret) && ast_strlen_zero(md5secret))
11805       return AUTH_SUCCESSFUL;
11806 
11807    /* Always auth with WWW-auth since we're NOT a proxy */
11808    /* Using proxy-auth in a B2BUA may block proxy authorization in the same transaction */
11809    response = "401 Unauthorized";
11810 
11811    /*
11812     * Note the apparent swap of arguments below, compared to other
11813     * usages of auth_headers().
11814     */
11815    auth_headers(WWW_AUTH, &respheader, &reqheader);
11816 
11817    authtoken =  get_header(req, reqheader);  
11818    if (ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
11819       /* This is a retransmitted invite/register/etc, don't reconstruct authentication
11820          information */
11821       if (!reliable) {
11822          /* Resend message if this was NOT a reliable delivery.   Otherwise the
11823             retransmission should get it */
11824          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
11825          /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
11826          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11827       }
11828       return AUTH_CHALLENGE_SENT;
11829    } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
11830       /* We have no auth, so issue challenge and request authentication */
11831       set_nonce_randdata(p, 1); /* Create nonce for challenge */
11832       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, 0);
11833       /* Schedule auto destroy in 32 seconds */
11834       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11835       return AUTH_CHALLENGE_SENT;
11836    } 
11837 
11838    /* --- We have auth, so check it */
11839 
11840    /* Whoever came up with the authentication section of SIP can suck my %&#$&* for not putting
11841       an example in the spec of just what it is you're doing a hash on. */
11842 
11843    if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN)))
11844       return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
11845 
11846    /* Make a copy of the response and parse it */
11847    res = ast_str_set(&buf, 0, "%s", authtoken);
11848 
11849    if (res == AST_DYNSTR_BUILD_FAILED)
11850       return AUTH_SECRET_FAILED; /*! XXX \todo need a better return code here */
11851 
11852    c = buf->str;
11853 
11854    while(c && *(c = ast_skip_blanks(c)) ) { /* lookup for keys */
11855       for (i = keys; i->key != NULL; i++) {
11856          const char *separator = ",";  /* default */
11857 
11858          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
11859             continue;
11860          /* Found. Skip keyword, take text in quotes or up to the separator. */
11861          c += strlen(i->key);
11862          if (*c == '"') { /* in quotes. Skip first and look for last */
11863             c++;
11864             separator = "\"";
11865          }
11866          i->s = c;
11867          strsep(&c, separator);
11868          break;
11869       }
11870       if (i->key == NULL) /* not found, jump after space or comma */
11871          strsep(&c, " ,");
11872    }
11873 
11874    /* Verify that digest username matches  the username we auth as */
11875    if (strcmp(username, keys[K_USER].s)) {
11876       ast_log(LOG_WARNING, "username mismatch, have <%s>, digest has <%s>\n",
11877          username, keys[K_USER].s);
11878       /* Oops, we're trying something here */
11879       return AUTH_USERNAME_MISMATCH;
11880    }
11881 
11882    /* Verify nonce from request matches our nonce, and the nonce has not already been responded to.
11883     * If this check fails, send 401 with new nonce */
11884    if (strcasecmp(p->randdata, keys[K_NONCE].s) || p->stalenonce) { /* XXX it was 'n'casecmp ? */
11885       wrongnonce = TRUE;
11886       usednonce = keys[K_NONCE].s;
11887    } else {
11888       p->stalenonce = 1; /* now, since the nonce has a response, mark it as stale so it can't be sent or responded to again */
11889    }
11890 
11891    if (!ast_strlen_zero(md5secret))
11892       ast_copy_string(a1_hash, md5secret, sizeof(a1_hash));
11893    else {
11894       char a1[256];
11895       snprintf(a1, sizeof(a1), "%s:%s:%s", username, global_realm, secret);
11896       ast_md5_hash(a1_hash, a1);
11897    }
11898 
11899    /* compute the expected response to compare with what we received */
11900    {
11901       char a2[256];
11902       char a2_hash[256];
11903       char resp[256];
11904 
11905       snprintf(a2, sizeof(a2), "%s:%s", sip_methods[sipmethod].text,
11906             S_OR(keys[K_URI].s, uri));
11907       ast_md5_hash(a2_hash, a2);
11908       snprintf(resp, sizeof(resp), "%s:%s:%s", a1_hash, usednonce, a2_hash);
11909       ast_md5_hash(resp_hash, resp);
11910    }
11911 
11912    good_response = keys[K_RESP].s &&
11913          !strncasecmp(keys[K_RESP].s, resp_hash, strlen(resp_hash));
11914    if (wrongnonce) {
11915       if (good_response) {
11916          if (sipdebug)
11917             ast_log(LOG_NOTICE, "Correct auth, but based on stale nonce received from '%s'\n", get_header(req, "To"));
11918          /* We got working auth token, based on stale nonce . */
11919          set_nonce_randdata(p, 0);
11920          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, TRUE);
11921       } else {
11922          /* Everything was wrong, so give the device one more try with a new challenge */
11923          if (!req->ignore) {
11924             if (sipdebug)
11925                ast_log(LOG_NOTICE, "Bad authentication received from '%s'\n", get_header(req, "To"));
11926             set_nonce_randdata(p, 1);
11927          } else {
11928             if (sipdebug)
11929                ast_log(LOG_NOTICE, "Duplicate authentication received from '%s'\n", get_header(req, "To"));
11930          }
11931          transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
11932       }
11933 
11934       /* Schedule auto destroy in 32 seconds */
11935       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
11936       return AUTH_CHALLENGE_SENT;
11937    } 
11938    if (good_response) {
11939       append_history(p, "AuthOK", "Auth challenge succesful for %s", username);
11940       return AUTH_SUCCESSFUL;
11941    }
11942 
11943    /* Ok, we have a bad username/secret pair */
11944    /* Tell the UAS not to re-send this authentication data, because
11945       it will continue to fail
11946    */
11947 
11948    return AUTH_SECRET_FAILED;
11949 }

static enum check_auth_result check_peer_ok ( struct sip_pvt p,
char *  of,
struct sip_request req,
int  sipmethod,
struct sockaddr_in *  sin,
struct sip_peer **  authpeer,
enum xmittype  reliable,
char *  rpid_num,
char *  calleridname,
char *  uri2 
) [static]

Validate device authentication.

Definition at line 13145 of file chan_sip.c.

References sip_peer::accountcode, accountcode, sip_peer::amaflags, sip_pvt::amaflags, ao2_t_ref, ast_apply_ha(), ast_copy_flags, ast_debug, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_is_shrinkable_phonenumber(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose, AUTH_ACL_FAILED, AUTH_DONT_KNOW, sip_peer::autoframing, sip_pvt::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_pvt::callgroup, sip_pvt::callingpres, sip_peer::callingpres, sip_peer::capability, sip_pvt::capability, sip_peer::chanvars, sip_pvt::chanvars, check_auth(), cid_name, sip_peer::cid_name, cid_num, sip_peer::cid_num, context, sip_peer::context, copy_vars(), debug, do_setnat(), FALSE, find_peer(), FINDALLDEVICES, FINDPEERS, FINDUSERS, sip_peer::flags, sip_pvt::flags, sip_peer::fullcontact, sip_peer::ha, sip_request::ignore, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, sip_peer::language, language, sip_peer::lastms, sip_peer::maxcallbitrate, sip_pvt::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, mohinterpret, sip_peer::mohsuggest, mohsuggest, sip_peer::name, sip_pvt::noncodeccapability, sip_peer::parkinglot, parkinglot, sip_pvt::peercapability, sip_pvt::peermd5secret, sip_pvt::peersecret, sip_peer::pickupgroup, sip_pvt::pickupgroup, sip_pvt::prefs, sip_peer::prefs, sip_pvt::recv, replace_cid(), sip_pvt::rtp, sip_peer::secret, set_t38_capabilities(), SIP_CALL_LIMIT, sip_debug_test_addr(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_INSECURE_INVITE, SIP_INVITE, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_TEXTSUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_PAGE2_VIDEOSUPPORT_ALWAYS, SIP_SUBSCRIBE, sip_peer::sipoptions, sip_pvt::sipoptions, sip_pvt::socket, sip_peer::subscribecontext, sip_peer::t38_maxdatagram, sip_pvt::t38_maxdatagram, sip_pvt::timer_b, sip_peer::timer_b, sip_peer::timer_t1, sip_pvt::timer_t1, sip_pvt::trtp, TRUE, sip_socket::type, sip_pvt::udptl, unref_peer(), sip_peer::username, and sip_pvt::vrtp.

Referenced by check_user_full().

13150 {
13151    enum check_auth_result res;
13152    int debug=sip_debug_test_addr(sin);
13153    struct sip_peer *peer;
13154 
13155    if (sipmethod == SIP_SUBSCRIBE) {
13156       /* For subscribes, match on device name only; for other methods,
13157       * match on IP address-port of the incoming request.
13158       */
13159       peer = find_peer(of, NULL, TRUE, FINDALLDEVICES, FALSE, 0);
13160    } else {
13161       /* First find devices based on username (avoid all type=peer's) */
13162       peer = find_peer(of, NULL, TRUE, FINDUSERS, FALSE, 0);
13163 
13164       /* Then find devices based on IP */
13165       if (!peer) {
13166          peer = find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type);
13167       }
13168    }
13169 
13170    if (!peer) {
13171       if (debug)
13172          ast_verbose("No matching peer for '%s' from '%s:%d'\n",
13173             of, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
13174       return AUTH_DONT_KNOW;
13175    }
13176    if (!ast_apply_ha(peer->ha, sin)) {
13177       ast_debug(2, "Found peer '%s' for '%s', but fails host access\n", peer->name, of);
13178       unref_peer(peer, "unref_peer: check_peer_ok: from find_peer call, early return of AUTH_ACL_FAILED");
13179       return AUTH_ACL_FAILED;
13180    }
13181    if (debug)
13182       ast_verbose("Found peer '%s' for '%s' from %s:%d\n",
13183          peer->name, of, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
13184 
13185    /* XXX what about p->prefs = peer->prefs; ? */
13186    /* Set Frame packetization */
13187    if (p->rtp) {
13188       ast_rtp_codec_setpref(p->rtp, &peer->prefs);
13189       p->autoframing = peer->autoframing;
13190    }
13191 
13192    /* Take the peer */
13193    ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
13194    ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
13195 
13196    if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && p->udptl) {
13197       p->t38_maxdatagram = peer->t38_maxdatagram;
13198       set_t38_capabilities(p);
13199    }
13200 
13201    /* Copy SIP extensions profile to peer */
13202    /* XXX is this correct before a successful auth ? */
13203    if (p->sipoptions)
13204       peer->sipoptions = p->sipoptions;
13205 
13206    replace_cid(p, rpid_num, calleridname);
13207    do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT_ROUTE));
13208 
13209    ast_string_field_set(p, peersecret, peer->secret);
13210    ast_string_field_set(p, peermd5secret, peer->md5secret);
13211    ast_string_field_set(p, subscribecontext, peer->subscribecontext);
13212    ast_string_field_set(p, mohinterpret, peer->mohinterpret);
13213    ast_string_field_set(p, mohsuggest, peer->mohsuggest);
13214    ast_string_field_set(p, parkinglot, peer->parkinglot);
13215    if (peer->callingpres)  /* Peer calling pres setting will override RPID */
13216       p->callingpres = peer->callingpres;
13217    if (peer->maxms && peer->lastms)
13218       p->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
13219    else
13220       p->timer_t1 = peer->timer_t1;
13221  
13222    /* Set timer B to control transaction timeouts */
13223    if (peer->timer_b)
13224       p->timer_b = peer->timer_b;
13225    else
13226       p->timer_b = 64 * p->timer_t1;
13227  
13228    if (ast_test_flag(&peer->flags[0], SIP_INSECURE_INVITE)) {
13229       /* Pretend there is no required authentication */
13230       ast_string_field_set(p, peersecret, NULL);
13231       ast_string_field_set(p, peermd5secret, NULL);
13232    }
13233    if (!(res = check_auth(p, req, peer->name, p->peersecret, p->peermd5secret, sipmethod, uri2, reliable, req->ignore))) {
13234       ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
13235       ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
13236       /* If we have a call limit, set flag */
13237       if (peer->call_limit)
13238          ast_set_flag(&p->flags[0], SIP_CALL_LIMIT);
13239       ast_string_field_set(p, peername, peer->name);
13240       ast_string_field_set(p, authname, peer->name);
13241 
13242       if (sipmethod == SIP_INVITE) {
13243          /* copy channel vars */
13244          p->chanvars = copy_vars(peer->chanvars);
13245       }
13246 
13247       if (authpeer) {
13248          ao2_t_ref(peer, 1, "copy pointer into (*authpeer)");
13249          (*authpeer) = peer;  /* Add a ref to the object here, to keep it in memory a bit longer if it is realtime */
13250       }
13251 
13252       if (!ast_strlen_zero(peer->username)) {
13253          ast_string_field_set(p, username, peer->username);
13254          /* Use the default username for authentication on outbound calls */
13255          /* XXX this takes the name from the caller... can we override ? */
13256          ast_string_field_set(p, authname, peer->username);
13257       }
13258       if (!ast_strlen_zero(peer->cid_num)) {
13259          char *tmp = ast_strdupa(peer->cid_num);
13260          if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp))
13261             ast_shrink_phone_number(tmp);
13262          ast_string_field_set(p, cid_num, tmp);
13263       }
13264       if (!ast_strlen_zero(peer->cid_name)) 
13265          ast_string_field_set(p, cid_name, peer->cid_name);
13266       ast_string_field_set(p, fullcontact, peer->fullcontact);
13267       if (!ast_strlen_zero(peer->context))
13268          ast_string_field_set(p, context, peer->context);
13269       ast_string_field_set(p, peersecret, peer->secret);
13270       ast_string_field_set(p, peermd5secret, peer->md5secret);
13271       ast_string_field_set(p, language, peer->language);
13272       ast_string_field_set(p, accountcode, peer->accountcode);
13273       p->amaflags = peer->amaflags;
13274       p->callgroup = peer->callgroup;
13275       p->pickupgroup = peer->pickupgroup;
13276       p->capability = peer->capability;
13277       p->prefs = peer->prefs;
13278       p->jointcapability = peer->capability;
13279       if (p->peercapability)
13280          p->jointcapability &= p->peercapability;
13281       p->maxcallbitrate = peer->maxcallbitrate;
13282       if (!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS) &&
13283             (!ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ||
13284                !(p->capability & AST_FORMAT_VIDEO_MASK)) &&
13285             p->vrtp) {
13286          ast_rtp_destroy(p->vrtp);
13287          p->vrtp = NULL;
13288       }
13289       if ((!ast_test_flag(&p->flags[1], SIP_PAGE2_TEXTSUPPORT) || !(p->capability & AST_FORMAT_TEXT_MASK)) && p->trtp) {
13290          ast_rtp_destroy(p->trtp);
13291          p->trtp = NULL;
13292       }
13293       if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
13294           (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
13295          p->noncodeccapability |= AST_RTP_DTMF;
13296       else
13297          p->noncodeccapability &= ~AST_RTP_DTMF;
13298       p->jointnoncodeccapability = p->noncodeccapability;
13299    }
13300    unref_peer(peer, "check_peer_ok: unref_peer: tossing temp ptr to peer from find_peer");
13301    return res;
13302 }

static void check_pendings ( struct sip_pvt p  )  [static]

Check pending actions on SIP call.

Definition at line 16782 of file chan_sip.c.

References ast_clear_flag, ast_debug, ast_test_flag, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, FALSE, sip_pvt::flags, INV_CALLING, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, sip_pvt::pendinginvite, SIP_BYE, SIP_CANCEL, SIP_NEEDREINVITE, SIP_PENDINGBYE, sip_scheddestroy(), t38properties::state, sip_pvt::t38, T38_LOCAL_REINVITE, transmit_reinvite_with_sdp(), transmit_request(), transmit_request_with_auth(), TRUE, sip_pvt::waitid, and XMIT_RELIABLE.

Referenced by handle_incoming(), handle_response_invite(), and sip_reinvite_retry().

16783 {
16784    if (ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
16785       /* if we can't BYE, then this is really a pending CANCEL */
16786       if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA)
16787          transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE);
16788          /* Actually don't destroy us yet, wait for the 487 on our original 
16789             INVITE, but do set an autodestruct just in case we never get it. */
16790       else {
16791          /* We have a pending outbound invite, don't send someting
16792             new in-transaction */
16793          if (p->pendinginvite)
16794             return;
16795 
16796          /* Perhaps there is an SD change INVITE outstanding */
16797          transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE);
16798       }
16799       ast_clear_flag(&p->flags[0], SIP_PENDINGBYE);   
16800       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
16801    } else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) {
16802       /* if we can't REINVITE, hold it for later */
16803       if (p->pendinginvite || p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA || p->waitid > 0) {
16804          ast_debug(2, "NOT Sending pending reinvite (yet) on '%s'\n", p->callid);
16805       } else {
16806          ast_debug(2, "Sending pending reinvite on '%s'\n", p->callid);
16807          /* Didn't get to reinvite yet, so do it now */
16808          transmit_reinvite_with_sdp(p, (p->t38.state == T38_LOCAL_REINVITE ? TRUE : FALSE), FALSE);
16809          ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 
16810       }
16811    }
16812 }

static void check_rtp_timeout ( struct sip_pvt dialog,
time_t  t 
) [static]

helper function for the monitoring thread -- seems to be called with the assumption that the dialog is locked

Todo:
Check video RTP keepalives
Do we need to move the lastrtptx to the RTP structure to have one for audio and one for video? It really does belong to the RTP structure.

Definition at line 21427 of file chan_sip.c.

References ast_channel::_state, ast_channel_trylock, ast_channel_unlock, ast_log(), ast_rtp_get_peer(), ast_rtp_get_rtpholdtimeout(), ast_rtp_get_rtpkeepalive(), ast_rtp_get_rtptimeout(), ast_rtp_sendcng(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtptimeout(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, ast_test_flag, sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lastrtptx, LOG_NOTICE, ast_channel::name, sip_pvt::owner, sip_pvt::redirip, sip_pvt::rtp, SIP_PAGE2_CALL_ONHOLD, sip_pvt_lock, sip_pvt_unlock, t38properties::state, sip_pvt::t38, T38_ENABLED, and sip_pvt::vrtp.

Referenced by dialog_needdestroy().

21428 {
21429    /* If we have no RTP or no active owner, no need to check timers */
21430    if (!dialog->rtp || !dialog->owner)
21431       return;
21432    /* If the call is not in UP state or redirected outside Asterisk, no need to check timers */
21433 
21434    if (dialog->owner->_state != AST_STATE_UP || dialog->redirip.sin_addr.s_addr)
21435       return;
21436 
21437    /* If the call is involved in a T38 fax session do not check RTP timeout */
21438    if (dialog->t38.state == T38_ENABLED)
21439       return;
21440 
21441    /* If we have no timers set, return now */
21442    if ((ast_rtp_get_rtpkeepalive(dialog->rtp) == 0) && (ast_rtp_get_rtptimeout(dialog->rtp) == 0) && (ast_rtp_get_rtpholdtimeout(dialog->rtp) == 0))
21443       return;
21444 
21445    /* Check AUDIO RTP keepalives */
21446    if (dialog->lastrtptx && ast_rtp_get_rtpkeepalive(dialog->rtp) &&
21447           (t > dialog->lastrtptx + ast_rtp_get_rtpkeepalive(dialog->rtp))) {
21448       /* Need to send an empty RTP packet */
21449       dialog->lastrtptx = time(NULL);
21450       ast_rtp_sendcng(dialog->rtp, 0);
21451    }
21452 
21453    /*! \todo Check video RTP keepalives
21454 
21455       Do we need to move the lastrtptx to the RTP structure to have one for audio and one
21456       for video? It really does belong to the RTP structure.
21457    */
21458 
21459    /* Check AUDIO RTP timers */
21460    if (dialog->lastrtprx && (ast_rtp_get_rtptimeout(dialog->rtp) || ast_rtp_get_rtpholdtimeout(dialog->rtp)) &&
21461           (t > dialog->lastrtprx + ast_rtp_get_rtptimeout(dialog->rtp))) {
21462 
21463       /* Might be a timeout now -- see if we're on hold */
21464       struct sockaddr_in sin;
21465       ast_rtp_get_peer(dialog->rtp, &sin);
21466       if (!ast_test_flag(&dialog->flags[1], SIP_PAGE2_CALL_ONHOLD) || (ast_rtp_get_rtpholdtimeout(dialog->rtp) &&
21467            (t > dialog->lastrtprx + ast_rtp_get_rtpholdtimeout(dialog->rtp)))) {
21468          /* Needs a hangup */
21469          if (ast_rtp_get_rtptimeout(dialog->rtp)) {
21470             while (dialog->owner && ast_channel_trylock(dialog->owner)) {
21471                sip_pvt_unlock(dialog);
21472                usleep(1);
21473                sip_pvt_lock(dialog);
21474             }
21475             ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n",
21476                dialog->owner->name, (long) (t - dialog->lastrtprx));
21477             /* Issue a softhangup */
21478             ast_softhangup_nolock(dialog->owner, AST_SOFTHANGUP_DEV);
21479             ast_channel_unlock(dialog->owner);
21480             /* forget the timeouts for this call, since a hangup
21481                has already been requested and we don't want to
21482                repeatedly request hangups
21483             */
21484             ast_rtp_set_rtptimeout(dialog->rtp, 0);
21485             ast_rtp_set_rtpholdtimeout(dialog->rtp, 0);
21486             if (dialog->vrtp) {
21487                ast_rtp_set_rtptimeout(dialog->vrtp, 0);
21488                ast_rtp_set_rtpholdtimeout(dialog->vrtp, 0);
21489             }
21490          }
21491       }
21492    }
21493 }

static int check_sip_domain ( const char *  domain,
char *  context,
size_t  len 
) [static]

check_sip_domain: Check if domain part of uri is local to our server

Definition at line 22530 of file chan_sip.c.

References ast_copy_string(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_strlen_zero(), domain::context, domain::domain, and domain::list.

Referenced by func_check_sipdomain(), get_destination(), handle_request_refer(), and register_verify().

22531 {
22532    struct domain *d;
22533    int result = 0;
22534 
22535    AST_LIST_LOCK(&domain_list);
22536    AST_LIST_TRAVERSE(&domain_list, d, list) {
22537       if (strcasecmp(d->domain, domain))
22538          continue;
22539 
22540       if (len && !ast_strlen_zero(d->context))
22541          ast_copy_string(context, d->context, len);
22542       
22543       result = 1;
22544       break;
22545    }
22546    AST_LIST_UNLOCK(&domain_list);
22547 
22548    return result;
22549 }

static int check_user ( struct sip_pvt p,
struct sip_request req,
int  sipmethod,
char *  uri,
enum xmittype  reliable,
struct sockaddr_in *  sin 
) [static]

Find user If we get a match, this will add a reference pointer to the user object in ASTOBJ, that needs to be unreferenced.

Definition at line 13427 of file chan_sip.c.

References check_user_full().

Referenced by handle_request_invite().

13428 {
13429    return check_user_full(p, req, sipmethod, uri, reliable, sin, NULL);
13430 }

static enum check_auth_result check_user_full ( struct sip_pvt p,
struct sip_request req,
int  sipmethod,
char *  uri,
enum xmittype  reliable,
struct sockaddr_in *  sin,
struct sip_peer **  authpeer 
) [static]

Check if matching user or peer is defined Match user on From: user name and peer on IP/port This is used on first invite (not re-invites) and subscribe requests.

Returns:
0 on success, non-zero on failure

Definition at line 13310 of file chan_sip.c.

References ast_copy_string(), ast_is_shrinkable_phonenumber(), ast_log(), ast_set_flag, ast_shrink_phone_number(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), AUTH_DONT_KNOW, AUTH_FAKE_AUTH, AUTH_SECRET_FAILED, AUTH_SUCCESSFUL, build_contact(), check_peer_ok(), cid_name, cid_num, dummy(), exten, get_calleridname(), get_header(), get_in_brackets(), get_rpid_num(), LOG_NOTICE, parse_uri(), replace_cid(), SIP_NAT_ROUTE, SIP_PAGE2_RPORT_PRESENT, strsep(), and terminate_uri().

Referenced by check_user(), and handle_request_subscribe().

13313 {
13314    char from[256];
13315    char *dummy;   /* dummy return value for parse_uri */
13316    char *domain;  /* dummy return value for parse_uri */
13317    char *of;
13318    char rpid_num[50];
13319    const char *rpid;
13320    enum check_auth_result res;
13321    char calleridname[50];
13322    char *uri2 = ast_strdupa(uri);
13323 
13324    terminate_uri(uri2); /* trim extra stuff */
13325 
13326    ast_copy_string(from, get_header(req, "From"), sizeof(from));
13327    if (pedanticsipchecking)
13328       ast_uri_decode(from);
13329    /* XXX here tries to map the username for invite things */
13330    memset(calleridname, 0, sizeof(calleridname));
13331    get_calleridname(from, calleridname, sizeof(calleridname));
13332    if (calleridname[0])
13333       ast_string_field_set(p, cid_name, calleridname);
13334 
13335    rpid = get_header(req, "Remote-Party-ID");
13336    memset(rpid_num, 0, sizeof(rpid_num));
13337    if (!ast_strlen_zero(rpid)) 
13338       p->callingpres = get_rpid_num(rpid, rpid_num, sizeof(rpid_num));
13339 
13340    of = get_in_brackets(from);
13341    if (ast_strlen_zero(p->exten)) {
13342       char *t = uri2;
13343       if (!strncasecmp(t, "sip:", 4))
13344          t+= 4;
13345       else if (!strncasecmp(t, "sips:", 5))
13346          t += 5;
13347       ast_string_field_set(p, exten, t);
13348       t = strchr(p->exten, '@');
13349       if (t)
13350          *t = '\0';
13351       if (ast_strlen_zero(p->our_contact))
13352          build_contact(p);
13353    }
13354    /* save the URI part of the From header */
13355    ast_string_field_set(p, from, of);
13356 
13357 
13358    /* ignore all fields but name */
13359    if (parse_uri(of, "sip:,sips:", &of, &dummy, &domain, &dummy, &dummy, NULL)) {
13360       ast_log(LOG_NOTICE, "From address missing 'sip:', using it anyway\n");
13361    }
13362 
13363    if (ast_strlen_zero(of)) {
13364       /* XXX note: the original code considered a missing @host
13365        * as a username-only URI. The SIP RFC (19.1.1) says that
13366        * this is wrong, and it should be considered as a domain-only URI.
13367        * For backward compatibility, we keep this block, but it is
13368        * really a mistake and should go away.
13369        */
13370       of = domain;
13371    } else {
13372       char *tmp = ast_strdupa(of);
13373       /* We need to be able to handle auth-headers looking like
13374          <sip:8164444422;phone-context=+1@1.2.3.4:5060;user=phone;tag=SDadkoa01-gK0c3bdb43>
13375       */
13376       tmp = strsep(&tmp, ";");
13377       if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp))
13378          ast_shrink_phone_number(tmp);
13379       ast_string_field_set(p, cid_num, tmp);
13380    }
13381 
13382    if (global_match_auth_username) {
13383       /*
13384        * XXX This is experimental code to grab the search key from the
13385        * Auth header's username instead of the 'From' name, if available.
13386        * Do not enable this block unless you understand the side effects (if any!)
13387        * Note, the search for "username" should be done in a more robust way.
13388        * Note2, at the moment we check both fields, though maybe we should
13389        * pick one or another depending on the request ? XXX
13390        */
13391       const char *hdr = get_header(req, "Authorization");
13392       if (ast_strlen_zero(hdr))
13393          hdr = get_header(req, "Proxy-Authorization");
13394 
13395       if ( !ast_strlen_zero(hdr) && (hdr = strstr(hdr, "username=\"")) ) {
13396          ast_copy_string(from, hdr + strlen("username=\""), sizeof(from));
13397          of = from;
13398          of = strsep(&of, "\"");
13399       }
13400    }
13401 
13402    res = check_peer_ok(p, of, req, sipmethod, sin,
13403          authpeer, reliable, rpid_num, calleridname, uri2);
13404    if (res != AUTH_DONT_KNOW)
13405       return res;
13406 
13407    /* Finally, apply the guest policy */
13408    if (global_allowguest) {
13409       replace_cid(p, rpid_num, calleridname);
13410       res = AUTH_SUCCESSFUL;
13411    } else if (global_alwaysauthreject)
13412       res = AUTH_FAKE_AUTH; /* reject with fake authorization request */
13413    else
13414       res = AUTH_SECRET_FAILED; /* we don't want any guests, authentication will fail */
13415 
13416 
13417    if (ast_test_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT)) {
13418       ast_set_flag(&p->flags[0], SIP_NAT_ROUTE);
13419    }
13420 
13421    return res;
13422 }

static void check_via ( struct sip_pvt p,
struct sip_request req 
) [static]

check Via: header for hostname, port and rport request/answer

Definition at line 12977 of file chan_sip.c.

References ahp, ast_copy_string(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_set_flag, ast_skip_blanks(), ast_verbose, sip_pvt::flags, get_header(), hp, LOG_WARNING, port_str2int(), sip_pvt::sa, sip_debug_test_pvt(), sip_nat_mode(), SIP_PAGE2_RPORT_PRESENT, sip_real_dst(), and STANDARD_SIP_PORT.

Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_register(), and handle_request_subscribe().

12978 {
12979    char via[512];
12980    char *c, *pt, *maddr;
12981    struct hostent *hp;
12982    struct ast_hostent ahp;
12983 
12984    ast_copy_string(via, get_header(req, "Via"), sizeof(via));
12985 
12986    /* Work on the leftmost value of the topmost Via header */
12987    c = strchr(via, ',');
12988    if (c)
12989       *c = '\0';
12990 
12991    /* Check for rport */
12992    c = strstr(via, ";rport");
12993    if (c && (c[6] != '=')) /* rport query, not answer */
12994       ast_set_flag(&p->flags[1], SIP_PAGE2_RPORT_PRESENT);
12995 
12996    /* Check for maddr */
12997    maddr = strstr(via, "maddr=");
12998    if (maddr) {
12999       maddr += 6;
13000       c = maddr + strspn(maddr, "0123456789.");
13001       *c = '\0';
13002    }
13003 
13004    c = strchr(via, ';');
13005    if (c)
13006       *c = '\0';
13007 
13008    c = strchr(via, ' ');
13009    if (c) {
13010       *c = '\0';
13011       c = ast_skip_blanks(c+1);
13012       if (strcasecmp(via, "SIP/2.0/UDP") && strcasecmp(via, "SIP/2.0/TCP") && strcasecmp(via, "SIP/2.0/TLS")) {
13013          ast_log(LOG_WARNING, "Don't know how to respond via '%s'\n", via);
13014          return;
13015       }
13016       pt = strchr(c, ':');
13017       if (pt)
13018          *pt++ = '\0';  /* remember port pointer */
13019       /* Use maddr if found */
13020       if (maddr)
13021          c = maddr;
13022       hp = ast_gethostbyname(c, &ahp);
13023       if (!hp) {
13024          ast_log(LOG_WARNING, "'%s' is not a valid host\n", c);
13025          return;
13026       }
13027       memset(&p->sa, 0, sizeof(p->sa));
13028       p->sa.sin_family = AF_INET;
13029       memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
13030       p->sa.sin_port = htons(port_str2int(pt, STANDARD_SIP_PORT));
13031 
13032       if (sip_debug_test_pvt(p)) {
13033          const struct sockaddr_in *dst = sip_real_dst(p);
13034          ast_verbose("Sending to %s : %d (%s)\n", ast_inet_ntoa(dst->sin_addr), ntohs(dst->sin_port), sip_nat_mode(p));
13035       }
13036    }
13037 }

static attribute_unused void check_via_response ( struct sip_pvt p,
struct sip_request req 
) [static]

check received= and rport= in a SIP response. If we get a response with received= and/or rport= in the Via: line, use them as 'p->ourip' (see RFC 3581 for rport, and RFC 3261 for received). Using these two fields SIP can produce the correct address and port in the SIP headers without the need for STUN. The address part is also reused for the media sessions. Note that ast_sip_ouraddrfor() still rewrites p->ourip if you specify externip/seternaddr/stunaddr.

Definition at line 12947 of file chan_sip.c.

References ast_copy_string(), ast_parse_arg(), get_header(), sip_pvt::ourip, PARSE_INADDR, and strsep().

12948 {
12949    char via[256];
12950    char *cur, *opts;
12951 
12952    ast_copy_string(via, get_header(req, "Via"), sizeof(via));
12953 
12954    /* Work on the leftmost value of the topmost Via header */
12955    opts = strchr(via, ',');
12956    if (opts)
12957       *opts = '\0';
12958 
12959    /* parse all relevant options */
12960    opts = strchr(via, ';');
12961    if (!opts)
12962       return;  /* no options to parse */
12963    *opts++ = '\0';
12964    while ( (cur = strsep(&opts, ";")) ) {
12965       if (!strncmp(cur, "rport=", 6)) {
12966          int port = strtol(cur+6, NULL, 10);
12967          /* XXX add error checking */
12968          p->ourip.sin_port = ntohs(port);
12969       } else if (!strncmp(cur, "received=", 9)) {
12970          if (ast_parse_arg(cur+9, PARSE_INADDR, &p->ourip))
12971             ;  /* XXX add error checking */
12972       }
12973    }
12974 }

static void cleanup_stale_contexts ( char *  new,
char *  old 
) [static]

Destroy disused contexts between reloads Only used in reload_config so the code for regcontext doesn't get ugly.

Definition at line 14156 of file chan_sip.c.

References ast_context_destroy(), ast_context_find(), ast_copy_string(), AST_MAX_CONTEXT, and strsep().

Referenced by reload_config().

14157 {
14158    char *oldcontext, *newcontext, *stalecontext, *stringp, newlist[AST_MAX_CONTEXT];
14159 
14160    while ((oldcontext = strsep(&old, "&"))) {
14161       stalecontext = '\0';
14162       ast_copy_string(newlist, new, sizeof(newlist));
14163       stringp = newlist;
14164       while ((newcontext = strsep(&stringp, "&"))) {
14165          if (!strcmp(newcontext, oldcontext)) {
14166             /* This is not the context you're looking for */
14167             stalecontext = '\0';
14168             break;
14169          } else if (strcmp(newcontext, oldcontext)) {
14170             stalecontext = oldcontext;
14171          }
14172          
14173       }
14174       if (stalecontext)
14175          ast_context_destroy(ast_context_find(stalecontext), "SIP");
14176    }
14177 }

static void clear_peer_mailboxes ( struct sip_peer peer  )  [static]

Destroy all peer-related mailbox subscriptions

Definition at line 4250 of file chan_sip.c.

References AST_LIST_REMOVE_HEAD, destroy_mailbox(), sip_mailbox::entry, mailbox, and sip_peer::mailboxes.

Referenced by set_peer_defaults(), and sip_destroy_peer().

04251 {
04252    struct sip_mailbox *mailbox;
04253 
04254    while ((mailbox = AST_LIST_REMOVE_HEAD(&peer->mailboxes, entry)))
04255       destroy_mailbox(mailbox);
04256 }

static int clear_realm_authentication ( struct sip_auth authlist  )  [static]

Clear realm authentication list (at reload).

Definition at line 22619 of file chan_sip.c.

References ast_free, and sip_auth::next.

Referenced by build_peer(), reload_config(), sip_destroy_peer(), and unload_module().

22620 {
22621    struct sip_auth *a = authlist;
22622    struct sip_auth *b;
22623 
22624    while (a) {
22625       b = a;
22626       a = a->next;
22627       ast_free(b);
22628    }
22629 
22630    return 1;
22631 }

static void clear_sip_domains ( void   )  [static]

Clear our domain list (at reload).

Definition at line 22552 of file chan_sip.c.

References ast_free, AST_LIST_LOCK, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, and domain::list.

Referenced by reload_config(), and unload_module().

22553 {
22554    struct domain *d;
22555 
22556    AST_LIST_LOCK(&domain_list);
22557    while ((d = AST_LIST_REMOVE_HEAD(&domain_list, list)))
22558       ast_free(d);
22559    AST_LIST_UNLOCK(&domain_list);
22560 }

static const char* cli_yesno ( int  x  )  [static]

return Yes or No depending on the argument. This is used in many places in CLI command, having a function to generate this helps maintaining a consistent output (and possibly emitting the output in other languages, at some point).

Definition at line 13667 of file chan_sip.c.

Referenced by _sip_show_peer(), show_channels_cb(), sip_show_channel(), sip_show_settings(), sip_show_user(), and sip_show_users().

13668 {
13669    return x ? "Yes" : "No";
13670 }

static char * complete_sip_peer ( const char *  word,
int  state,
int  flags2 
) [static]

Do completion on peer name.

Definition at line 15500 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ast_strdup, ast_test_flag, sip_peer::flags, sip_peer::name, peers, and unref_peer().

Referenced by complete_sip_show_peer(), complete_sipnotify(), sip_do_debug(), and sip_prune_realtime().

15501 {
15502    char *result = NULL;
15503    int wordlen = strlen(word);
15504    int which = 0;
15505    struct ao2_iterator i = ao2_iterator_init(peers, 0);
15506    struct sip_peer *peer;
15507 
15508    while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
15509       /* locking of the object is not required because only the name and flags are being compared */
15510       if (!strncasecmp(word, peer->name, wordlen) &&
15511             (!flags2 || ast_test_flag(&peer->flags[1], flags2)) &&
15512             ++which > state)
15513          result = ast_strdup(peer->name);
15514       unref_peer(peer, "toss iterator peer ptr before break");
15515       if (result) {
15516          break;
15517       }
15518    }
15519    ao2_iterator_destroy(&i);
15520    return result;
15521 }

static char * complete_sip_registered_peer ( const char *  word,
int  state,
int  flags2 
) [static]

Do completion on registered peer name.

Definition at line 15524 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ast_strdup, ast_test_flag, sip_peer::expire, sip_peer::flags, sip_peer::name, peers, and unref_peer().

Referenced by complete_sip_unregister().

15525 {
15526        char *result = NULL;
15527        int wordlen = strlen(word);
15528        int which = 0;
15529        struct ao2_iterator i;
15530        struct sip_peer *peer;
15531        
15532        i = ao2_iterator_init(peers, 0);
15533        while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
15534           if (!strncasecmp(word, peer->name, wordlen) &&
15535          (!flags2 || ast_test_flag(&peer->flags[1], flags2)) &&
15536          ++which > state && peer->expire > 0)
15537              result = ast_strdup(peer->name);
15538           if (result) {
15539              unref_peer(peer, "toss iterator peer ptr before break");
15540              break;
15541           }
15542           unref_peer(peer, "toss iterator peer ptr");
15543        }
15544        ao2_iterator_destroy(&i);
15545        return result;
15546 }

static char * complete_sip_show_history ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Support routine for 'sip show history' CLI.

Definition at line 15549 of file chan_sip.c.

References complete_sipch().

Referenced by sip_show_history().

15550 {
15551    if (pos == 3)
15552       return complete_sipch(line, word, pos, state);
15553 
15554    return NULL;
15555 }

static char * complete_sip_show_peer ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Support routine for 'sip show peer' CLI.

Definition at line 15558 of file chan_sip.c.

References complete_sip_peer().

Referenced by sip_qualify_peer(), and sip_show_peer().

15559 {
15560    if (pos == 3) {
15561       return complete_sip_peer(word, state, 0);
15562    }
15563 
15564    return NULL;
15565 }

static char* complete_sip_show_user ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Support routine for 'sip show user' CLI.

Definition at line 14849 of file chan_sip.c.

References complete_sip_user().

Referenced by sip_show_user().

14850 {
14851    if (pos == 3)
14852       return complete_sip_user(word, state);
14853 
14854    return NULL;
14855 }

static char * complete_sip_unregister ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Support routine for 'sip unregister' CLI.

Definition at line 15568 of file chan_sip.c.

References complete_sip_registered_peer().

Referenced by sip_unregister().

15569 {
15570        if (pos == 2)
15571                return complete_sip_registered_peer(word, state, 0);
15572 
15573        return NULL;
15574 }

static char* complete_sip_user ( const char *  word,
int  state 
) [static]

Do completion on user name.

Definition at line 14822 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock(), ao2_unlock(), ast_strdup, peers, SIP_TYPE_USER, unref_peer(), and user.

Referenced by complete_sip_show_user().

14823 {
14824    char *result = NULL;
14825    int wordlen = strlen(word);
14826    int which = 0;
14827    struct ao2_iterator user_iter;
14828    struct sip_peer *user;
14829 
14830    user_iter = ao2_iterator_init(peers, 0);
14831    while ((user = ao2_iterator_next(&user_iter))) {
14832       ao2_lock(user);
14833       if (!(user->type & SIP_TYPE_USER)) {
14834          ao2_unlock(user);
14835          unref_peer(user, "complete sip user");
14836          continue;
14837       }
14838       /* locking of the object is not required because only the name and flags are being compared */
14839       if (!strncasecmp(word, user->name, wordlen) && ++which > state) {
14840          result = ast_strdup(user->name);
14841       }
14842       ao2_unlock(user);
14843       unref_peer(user, "complete sip user");
14844    }
14845    ao2_iterator_destroy(&user_iter);
14846    return result;
14847 }

static char* complete_sipch ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Support routine for 'sip show channel' and 'sip show history' CLI This is in charge of generating all strings that match a prefix in the given position. As many functions of this kind, each invokation has O(state) time complexity so be careful in using it.

Definition at line 15470 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ast_strdup, sip_pvt::callid, dialog_unref(), dialogs, sip_pvt_lock, and sip_pvt_unlock.

Referenced by complete_sip_show_history(), and sip_show_channel().

15471 {
15472    int which=0;
15473    struct sip_pvt *cur;
15474    char *c = NULL;
15475    int wordlen = strlen(word);
15476    struct ao2_iterator i;
15477 
15478    if (pos != 3) {
15479       return NULL;
15480    }
15481 
15482    i = ao2_iterator_init(dialogs, 0);
15483    while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
15484       sip_pvt_lock(cur);
15485       if (!strncasecmp(word, cur->callid, wordlen) && ++which > state) {
15486          c = ast_strdup(cur->callid);
15487          sip_pvt_unlock(cur);
15488          dialog_unref(cur, "drop ref in iterator loop break");
15489          break;
15490       }
15491       sip_pvt_unlock(cur);
15492       dialog_unref(cur, "drop ref in iterator loop");
15493    }
15494    ao2_iterator_destroy(&i);
15495    return c;
15496 }

static char * complete_sipnotify ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Support routine for 'sip notify' CLI.

Definition at line 15577 of file chan_sip.c.

References ast_category_browse(), ast_strdup, complete_sip_peer(), and notify_types.

Referenced by sip_cli_notify().

15578 {
15579    char *c = NULL;
15580 
15581    if (pos == 2) {
15582       int which = 0;
15583       char *cat = NULL;
15584       int wordlen = strlen(word);
15585 
15586       /* do completion for notify type */
15587 
15588       if (!notify_types)
15589          return NULL;
15590       
15591       while ( (cat = ast_category_browse(notify_types, cat)) ) {
15592          if (!strncasecmp(word, cat, wordlen) && ++which > state) {
15593             c = ast_strdup(cat);
15594             break;
15595          }
15596       }
15597       return c;
15598    }
15599 
15600    if (pos > 2)
15601       return complete_sip_peer(word, state, 0);
15602 
15603    return NULL;
15604 }

static int copy_all_header ( struct sip_request req,
const struct sip_request orig,
const char *  field 
) [static]

Copy all headers from one request to another.

Definition at line 8454 of file chan_sip.c.

References __get_header(), add_header(), and ast_strlen_zero().

Referenced by respprep().

08455 {
08456    int start = 0;
08457    int copied = 0;
08458    for (;;) {
08459       const char *tmp = __get_header(orig, field, &start);
08460 
08461       if (ast_strlen_zero(tmp))
08462          break;
08463       /* Add what we're responding to */
08464       add_header(req, field, tmp);
08465       copied++;
08466    }
08467    return copied ? 0 : -1;
08468 }

static int copy_header ( struct sip_request req,
const struct sip_request orig,
const char *  field 
) [static]

Copy one header field from one request to another.

Definition at line 8443 of file chan_sip.c.

References add_header(), ast_log(), ast_strlen_zero(), get_header(), and LOG_NOTICE.

Referenced by reqprep(), and respprep().

08444 {
08445    const char *tmp = get_header(orig, field);
08446 
08447    if (!ast_strlen_zero(tmp)) /* Add what we're responding to */
08448       return add_header(req, field, tmp);
08449    ast_log(LOG_NOTICE, "No field '%s' present to copy\n", field);
08450    return -1;
08451 }

static void copy_request ( struct sip_request dst,
const struct sip_request src 
) [static]

copy SIP request (mostly used to save request for responses)

Definition at line 9756 of file chan_sip.c.

References ast_str_create(), ast_str_make_space(), sip_request::data, ast_str::str, and ast_str::used.

Referenced by _sip_tcp_helper_thread(), handle_request_bye(), handle_request_invite(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), initialize_initreq(), parse_copy(), queue_request(), sip_park(), and sip_park_thread().

09757 {
09758    struct ast_str *duplicate = dst->data;
09759 
09760    /* First copy stuff */
09761    memcpy(dst, src, sizeof(*dst));
09762    dst->data = duplicate;
09763 
09764    /* All these + 1's are to account for the need to include the NULL terminator
09765     * Using typical string functions like ast_copy_string or ast_str_set will not
09766     * work in this case because the src's data string is riddled with \0's all over
09767     * the place and so a memcpy is the only way to accurately copy the string
09768     */
09769 
09770    if (!dst->data && !(dst->data = ast_str_create(src->data->used + 1)))
09771       return;
09772    else if (dst->data->len < src->data->used + 1)
09773       ast_str_make_space(&dst->data, src->data->used + 1);
09774       
09775    memcpy(dst->data->str, src->data->str, src->data->used + 1);
09776    dst->data->used = src->data->used;
09777 }

static void copy_socket_data ( struct sip_socket to_sock,
const struct sip_socket from_sock 
) [static]

Definition at line 4706 of file chan_sip.c.

References ao2_ref, and sip_socket::tcptls_session.

Referenced by create_addr_from_peer(), handle_request_do(), parse_register_contact(), sip_poke_peer(), and transmit_response_using_temp().

04707 {
04708    if (to_sock->tcptls_session) {
04709       ao2_ref(to_sock->tcptls_session, -1);
04710       to_sock->tcptls_session = NULL;
04711    }
04712 
04713    if (from_sock->tcptls_session) {
04714       ao2_ref(from_sock->tcptls_session, +1);
04715    }
04716 
04717    *to_sock = *from_sock;
04718 }

static struct ast_variable* copy_vars ( struct ast_variable src  )  [static]

duplicate a list of channel variables,

Returns:
the copy.

Definition at line 13117 of file chan_sip.c.

References ast_variable_new(), and ast_variable::next.

Referenced by check_peer_ok().

13118 {
13119    struct ast_variable *res = NULL, *tmp, *v = NULL;
13120 
13121    for (v = src ; v ; v = v->next) {
13122       if ((tmp = ast_variable_new(v->name, v->value, v->file))) {
13123          tmp->next = res;
13124          res = tmp;
13125       }
13126    }
13127    return res;
13128 }

static int copy_via_headers ( struct sip_pvt p,
struct sip_request req,
const struct sip_request orig,
const char *  field 
) [static]

Copy SIP VIA Headers from the request to the response.

Note:
If the client indicates that it wishes to know the port we received from, it adds ;rport without an argument to the topmost via header. We need to add the port number (from our point of view) to that parameter.
	We always add ;received=<ip address> to the topmost via header.
Received: RFC 3261, rport RFC 3581

Definition at line 8478 of file chan_sip.c.

References __get_header(), add_header(), ast_copy_string(), ast_inet_ntoa(), ast_log(), ast_strlen_zero(), ast_test_flag, sip_pvt::flags, LOG_NOTICE, sip_pvt::recv, SIP_NAT, SIP_NAT_ALWAYS, and SIP_NAT_RFC3581.

Referenced by respprep().

08479 {
08480    int copied = 0;
08481    int start = 0;
08482 
08483    for (;;) {
08484       char new[512];
08485       const char *oh = __get_header(orig, field, &start);
08486 
08487       if (ast_strlen_zero(oh))
08488          break;
08489 
08490       if (!copied) { /* Only check for empty rport in topmost via header */
08491          char leftmost[512], *others, *rport;
08492 
08493          /* Only work on leftmost value */
08494          ast_copy_string(leftmost, oh, sizeof(leftmost));
08495          others = strchr(leftmost, ',');
08496          if (others)
08497              *others++ = '\0';
08498 
08499          /* Find ;rport;  (empty request) */
08500          rport = strstr(leftmost, ";rport");
08501          if (rport && *(rport+6) == '=') 
08502             rport = NULL;     /* We already have a parameter to rport */
08503 
08504          /* Check rport if NAT=yes or NAT=rfc3581 (which is the default setting)  */
08505          if (rport && ((ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_ALWAYS) || (ast_test_flag(&p->flags[0], SIP_NAT) == SIP_NAT_RFC3581))) {
08506             /* We need to add received port - rport */
08507             char *end;
08508 
08509             rport = strstr(leftmost, ";rport");
08510 
08511             if (rport) {
08512                end = strchr(rport + 1, ';');
08513                if (end)
08514                   memmove(rport, end, strlen(end) + 1);
08515                else
08516                   *rport = '\0';
08517             }
08518 
08519             /* Add rport to first VIA header if requested */
08520             snprintf(new, sizeof(new), "%s;received=%s;rport=%d%s%s",
08521                leftmost, ast_inet_ntoa(p->recv.sin_addr),
08522                ntohs(p->recv.sin_port),
08523                others ? "," : "", others ? others : "");
08524          } else {
08525             /* We should *always* add a received to the topmost via */
08526             snprintf(new, sizeof(new), "%s;received=%s%s%s",
08527                leftmost, ast_inet_ntoa(p->recv.sin_addr),
08528                others ? "," : "", others ? others : "");
08529          }
08530          oh = new;   /* the header to copy */
08531       }  /* else add the following via headers untouched */
08532       add_header(req, field, oh);
08533       copied++;
08534    }
08535    if (!copied) {
08536       ast_log(LOG_NOTICE, "No header field '%s' present to copy\n", field);
08537       return -1;
08538    }
08539    return 0;
08540 }

static int create_addr ( struct sip_pvt dialog,
const char *  opeer,
struct sockaddr_in *  sin,
int  newdialog 
) [static]

create address structure from device name Or, if peer not found, find it in the global DNS returns TRUE (-1) on failure, FALSE on success

Todo:
Fix this function. When we ask SRC, we should check all transports In the future, we should first check NAPTR to find out transport preference

Definition at line 4868 of file chan_sip.c.

References ahp, ast_copy_string(), ast_get_srv(), ast_gethostbyname(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, create_addr_from_peer(), do_setnat(), FALSE, find_peer(), FINDPEERS, sip_pvt::flags, get_transport(), hp, LOG_WARNING, MAXHOSTNAMELEN, obproxy_get(), sip_socket::port, port_str2int(), sip_pvt::portinuri, sip_pvt::recv, ref_proxy(), sip_pvt::sa, service, set_socket_transport(), SIP_NAT, SIP_NAT_ROUTE, SIP_TRANSPORT_TLS, SIP_TRANSPORT_UDP, sip_pvt::socket, STANDARD_SIP_PORT, STANDARD_TLS_PORT, sip_pvt::timer_b, sip_pvt::timer_t1, sip_peer::tohost, TRUE, sip_socket::type, and unref_peer().

04869 {
04870    struct hostent *hp;
04871    struct ast_hostent ahp;
04872    struct sip_peer *peer;
04873    char *port;
04874    int portno = 0;
04875    char host[MAXHOSTNAMELEN], *hostn;
04876    char peername[256];
04877    int srv_ret = 0;
04878 
04879    ast_copy_string(peername, opeer, sizeof(peername));
04880    port = strchr(peername, ':');
04881    if (port) {
04882       *port++ = '\0';
04883       dialog->portinuri = 1;
04884    }
04885    dialog->sa.sin_family = AF_INET;
04886    dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */
04887    dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */
04888    peer = find_peer(peername, NULL, TRUE, FINDPEERS, FALSE, 0);
04889 
04890    if (peer) {
04891       int res;
04892       if (newdialog) {
04893          set_socket_transport(&dialog->socket, 0);
04894       }
04895       res = create_addr_from_peer(dialog, peer);
04896       if (!ast_strlen_zero(port)) {
04897          if ((portno = atoi(port))) {
04898             dialog->sa.sin_port = dialog->recv.sin_port = htons(portno);
04899          }
04900       }
04901       unref_peer(peer, "create_addr: unref peer from find_peer hashtab lookup");
04902       return res;
04903    }
04904 
04905    do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
04906 
04907    ast_string_field_set(dialog, tohost, peername);
04908 
04909    /* Get the outbound proxy information */
04910    ref_proxy(dialog, obproxy_get(dialog, NULL));
04911 
04912    if (sin) {
04913       /* This address should be updated using dnsmgr */
04914       memcpy(&dialog->sa.sin_addr, &sin->sin_addr, sizeof(dialog->sa.sin_addr));
04915       if (!sin->sin_port) {
04916          portno = port_str2int(port, (dialog->socket.type == SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT);
04917       } else {
04918          portno = ntohs(sin->sin_port);
04919       }
04920    } else {
04921 
04922       /* Let's see if we can find the host in DNS. First try DNS SRV records,
04923          then hostname lookup */
04924       /*! \todo Fix this function. When we ask SRC, we should check all transports 
04925            In the future, we should first check NAPTR to find out transport preference
04926        */
04927       hostn = peername;
04928       /* Section 4.2 of RFC 3263 specifies that if a port number is specified, then
04929        * an A record lookup should be used instead of SRV.
04930        */
04931       if (!port && global_srvlookup) {
04932          char service[MAXHOSTNAMELEN];
04933          int tportno;
04934    
04935          snprintf(service, sizeof(service), "_sip._%s.%s", get_transport(dialog->socket.type), peername);
04936          srv_ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service);
04937          if (srv_ret > 0) {
04938             hostn = host;
04939             portno = tportno;
04940          }
04941       }
04942       if (!portno)
04943          portno = port_str2int(port, (dialog->socket.type == SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT);
04944       hp = ast_gethostbyname(hostn, &ahp);
04945       if (!hp) {
04946          ast_log(LOG_WARNING, "No such host: %s\n", peername);
04947          return -1;
04948       }
04949       memcpy(&dialog->sa.sin_addr, hp->h_addr, sizeof(dialog->sa.sin_addr));
04950    }
04951 
04952    if (!dialog->socket.type)
04953       set_socket_transport(&dialog->socket, SIP_TRANSPORT_UDP);
04954    if (!dialog->socket.port)
04955       dialog->socket.port = bindaddr.sin_port;
04956    dialog->sa.sin_port = htons(portno);
04957    dialog->recv = dialog->sa;
04958    return 0;
04959 }

static int create_addr_from_peer ( struct sip_pvt dialog,
struct sip_peer peer 
) [static]

Create address structure from peer reference. This function copies data from peer to the dialog, so we don't have to look up the peer again from memory or database during the life time of the dialog.

Returns:
-1 on error, 0 on success.

Definition at line 4727 of file chan_sip.c.

References sip_peer::addr, sip_peer::allowtransfer, sip_pvt::allowtransfer, ao2_t_link, ao2_t_unlink, ast_copy_flags, AST_FORMAT_VIDEO_MASK, ast_inet_ntoa(), ast_rtp_codec_setpref(), ast_rtp_destroy(), AST_RTP_DTMF, ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_destroy(), ast_udptl_new_with_bindaddr(), sip_peer::auth, sip_peer::autoframing, sip_pvt::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_pvt::callgroup, sip_pvt::callid, sip_peer::capability, sip_pvt::capability, check_request_transport, sip_peer::context, context, copy_socket_data(), sip_peer::defaddr, dialogs, do_setnat(), sip_peer::flags, sip_pvt::flags, sip_peer::fromdomain, sip_peer::fromuser, sip_peer::fullcontact, sip_request::headers, sip_pvt::initreq, io, sip_pvt::jointnoncodeccapability, language, sip_peer::language, sip_peer::lastms, sip_peer::maxcallbitrate, sip_pvt::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, mohinterpret, sip_peer::mohsuggest, mohsuggest, sip_peer::name, sip_pvt::noncodeccapability, obproxy_get(), sip_peer::parkinglot, parkinglot, sip_pvt::peerauth, sip_peer::pickupgroup, sip_pvt::pickupgroup, sip_peer::portinuri, sip_pvt::portinuri, sip_peer::prefs, sip_pvt::prefs, sip_pvt::recv, ref_proxy(), sip_pvt::rtp, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_pvt::rtptimeout, sip_peer::rtptimeout, sip_pvt::sa, sched, sip_peer::secret, set_t38_capabilities(), SIP_CALL_LIMIT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, SIP_NAT, SIP_NAT_ROUTE, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_TEXTSUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_PAGE2_VIDEOSUPPORT_ALWAYS, sip_peer::socket, sip_pvt::socket, sip_peer::t38_maxdatagram, sip_pvt::t38_maxdatagram, sip_pvt::timer_b, sip_peer::timer_b, sip_peer::timer_t1, sip_pvt::timer_t1, sip_pvt::tohost, sip_peer::tohost, sip_pvt::trtp, sip_socket::type, sip_pvt::udptl, sip_peer::username, and sip_pvt::vrtp.

Referenced by create_addr(), and sip_send_mwi_to_peer().

04728 {
04729    /* this checks that the dialog is contacting the peer on a valid
04730     * transport type based on the peers transport configuration,
04731     * otherwise, this function bails out */
04732    if (dialog->socket.type && check_request_transport(peer, dialog))
04733       return -1;
04734    copy_socket_data(&dialog->socket, &peer->socket);
04735 
04736    if ((peer->addr.sin_addr.s_addr || peer->defaddr.sin_addr.s_addr) &&
04737        (!peer->maxms || ((peer->lastms >= 0)  && (peer->lastms <= peer->maxms)))) {
04738       dialog->sa = (peer->addr.sin_addr.s_addr) ? peer->addr : peer->defaddr;
04739       dialog->recv = dialog->sa;
04740    } else 
04741       return -1;
04742 
04743    ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
04744    ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
04745    dialog->capability = peer->capability;
04746    if (!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS) &&
04747          (!ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) ||
04748             !(dialog->capability & AST_FORMAT_VIDEO_MASK)) &&
04749          dialog->vrtp) {
04750       ast_rtp_destroy(dialog->vrtp);
04751       dialog->vrtp = NULL;
04752    }
04753    if (!ast_test_flag(&dialog->flags[1], SIP_PAGE2_TEXTSUPPORT) && dialog->trtp) {
04754       ast_rtp_destroy(dialog->trtp);
04755       dialog->trtp = NULL;
04756    }
04757    dialog->prefs = peer->prefs;
04758    if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) {
04759       if (!dialog->udptl) {
04760          /* t38pt_udptl was enabled in the peer and not in [general] */
04761          dialog->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr);
04762       }
04763       dialog->t38_maxdatagram = peer->t38_maxdatagram;
04764       set_t38_capabilities(dialog);
04765    } else if (dialog->udptl) {
04766       ast_udptl_destroy(dialog->udptl);
04767       dialog->udptl = NULL;
04768    }
04769    do_setnat(dialog, ast_test_flag(&dialog->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
04770 
04771    if (dialog->rtp) { /* Audio */
04772       ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
04773       ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
04774       ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout);
04775       ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout);
04776       ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive);
04777       /* Set Frame packetization */
04778       ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs);
04779       dialog->autoframing = peer->autoframing;
04780    }
04781    if (dialog->vrtp) { /* Video */
04782       ast_rtp_setdtmf(dialog->vrtp, 0);
04783       ast_rtp_setdtmfcompensate(dialog->vrtp, 0);
04784       ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout);
04785       ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout);
04786       ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive);
04787    }
04788    if (dialog->trtp) { /* Realtime text */
04789       ast_rtp_setdtmf(dialog->trtp, 0);
04790       ast_rtp_setdtmfcompensate(dialog->trtp, 0);
04791       ast_rtp_set_rtptimeout(dialog->trtp, peer->rtptimeout);
04792       ast_rtp_set_rtpholdtimeout(dialog->trtp, peer->rtpholdtimeout);
04793       ast_rtp_set_rtpkeepalive(dialog->trtp, peer->rtpkeepalive);
04794    }
04795 
04796    ast_string_field_set(dialog, peername, peer->name);
04797    ast_string_field_set(dialog, authname, peer->username);
04798    ast_string_field_set(dialog, username, peer->username);
04799    ast_string_field_set(dialog, peersecret, peer->secret);
04800    ast_string_field_set(dialog, peermd5secret, peer->md5secret);
04801    ast_string_field_set(dialog, mohsuggest, peer->mohsuggest);
04802    ast_string_field_set(dialog, mohinterpret, peer->mohinterpret);
04803    ast_string_field_set(dialog, tohost, peer->tohost);
04804    ast_string_field_set(dialog, fullcontact, peer->fullcontact);
04805    ast_string_field_set(dialog, context, peer->context);
04806    ast_string_field_set(dialog, parkinglot, peer->parkinglot);
04807    ref_proxy(dialog, obproxy_get(dialog, peer));
04808    dialog->callgroup = peer->callgroup;
04809    dialog->pickupgroup = peer->pickupgroup;
04810    dialog->allowtransfer = peer->allowtransfer;
04811    dialog->jointnoncodeccapability = dialog->noncodeccapability;
04812    dialog->rtptimeout = peer->rtptimeout;
04813    dialog->peerauth = peer->auth;
04814    dialog->maxcallbitrate = peer->maxcallbitrate;
04815    if (ast_strlen_zero(dialog->tohost))
04816       ast_string_field_set(dialog, tohost, ast_inet_ntoa(dialog->sa.sin_addr));
04817    if (!ast_strlen_zero(peer->fromdomain)) {
04818       ast_string_field_set(dialog, fromdomain, peer->fromdomain);
04819       if (!dialog->initreq.headers) {
04820          char *c;
04821          char *tmpcall = ast_strdupa(dialog->callid);
04822          /* this sure looks to me like we are going to change the callid on this dialog!! */
04823          c = strchr(tmpcall, '@');
04824          if (c) {
04825             *c = '\0';
04826             ao2_t_unlink(dialogs, dialog, "About to change the callid -- remove the old name");
04827             ast_string_field_build(dialog, callid, "%s@%s", tmpcall, peer->fromdomain);
04828             ao2_t_link(dialogs, dialog, "New dialog callid -- inserted back into table");
04829          }
04830       }
04831    }
04832    if (!ast_strlen_zero(peer->fromuser)) 
04833       ast_string_field_set(dialog, fromuser, peer->fromuser);
04834    if (!ast_strlen_zero(peer->language))
04835       ast_string_field_set(dialog, language, peer->language);
04836    /* Set timer T1 to RTT for this peer (if known by qualify=) */
04837    /* Minimum is settable or default to 100 ms */
04838    /* If there is a maxms and lastms from a qualify use that over a manual T1
04839       value. Otherwise, use the peer's T1 value. */
04840    if (peer->maxms && peer->lastms)
04841       dialog->timer_t1 = peer->lastms < global_t1min ? global_t1min : peer->lastms;
04842    else
04843       dialog->timer_t1 = peer->timer_t1;
04844 
04845    /* Set timer B to control transaction timeouts, the peer setting is the default and overrides
04846       the known timer */
04847    if (peer->timer_b)
04848       dialog->timer_b = peer->timer_b;
04849    else
04850       dialog->timer_b = 64 * dialog->timer_t1;
04851 
04852    if ((ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
04853        (ast_test_flag(&dialog->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
04854       dialog->noncodeccapability |= AST_RTP_DTMF;
04855    else
04856       dialog->noncodeccapability &= ~AST_RTP_DTMF;
04857    if (peer->call_limit)
04858       ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT);
04859    if (!dialog->portinuri)
04860       dialog->portinuri = peer->portinuri;
04861    
04862    return 0;
04863 }

static void destroy_association ( struct sip_peer peer  )  [static]

Remove registration data from realtime database or AST/DB when registration expires.

Definition at line 11200 of file chan_sip.c.

References ast_check_realtime(), ast_db_del(), ast_update_realtime(), sip_peer::deprecated_username, sip_settings::ignore_regexpire, sip_peer::name, sip_settings::peer_rtupdate, sip_peer::rt_fromcontact, SENTINEL, and sip_cfg.

Referenced by build_peer(), expire_register(), and parse_register_contact().

11201 {
11202    int realtimeregs = ast_check_realtime("sipregs");
11203    char *tablename = (realtimeregs) ? "sipregs" : "sippeers";
11204 
11205    if (!sip_cfg.ignore_regexpire) {
11206       if (peer->rt_fromcontact && sip_cfg.peer_rtupdate) {
11207          ast_update_realtime(tablename, "name", peer->name, "fullcontact", "", "ipaddr", "", "port", "", "regseconds", "0", peer->deprecated_username ? "username" : "defaultuser", "", "regserver", "", "useragent", "", "lastms", "", SENTINEL);
11208       } else {
11209          ast_db_del("SIP/Registry", peer->name);
11210       }
11211    }
11212 }

static void destroy_mailbox ( struct sip_mailbox mailbox  )  [static]

Destroy mailbox subscriptions

Definition at line 4238 of file chan_sip.c.

References ast_event_unsubscribe(), ast_free, and mailbox.

Referenced by clear_peer_mailboxes().

04239 {
04240    if (mailbox->mailbox)
04241       ast_free(mailbox->mailbox);
04242    if (mailbox->context)
04243       ast_free(mailbox->context);
04244    if (mailbox->event_sub)
04245       ast_event_unsubscribe(mailbox->event_sub);
04246    ast_free(mailbox);
04247 }

static int determine_firstline_parts ( struct sip_request req  )  [static]

Parse first line of incoming SIP request.

Definition at line 9810 of file chan_sip.c.

References ast_debug, ast_skip_blanks(), ast_skip_nonblanks(), ast_trim_blanks(), sip_request::data, sip_request::rlPart1, sip_request::rlPart2, and ast_str::str.

09811 {
09812    char *e = ast_skip_blanks(req->data->str);   /* there shouldn't be any */
09813    char *local_rlPart1;
09814 
09815    if (!*e)
09816       return -1;
09817    req->rlPart1 = e - req->data->str;  /* method or protocol */
09818    local_rlPart1 = e;
09819    e = ast_skip_nonblanks(e);
09820    if (*e)
09821       *e++ = '\0';
09822    /* Get URI or status code */
09823    e = ast_skip_blanks(e);
09824    if ( !*e )
09825       return -1;
09826    ast_trim_blanks(e);
09827 
09828    if (!strcasecmp(local_rlPart1, "SIP/2.0") ) { /* We have a response */
09829       if (strlen(e) < 3)   /* status code is 3 digits */
09830          return -1;
09831       req->rlPart2 = e - req->data->str;
09832    } else { /* We have a request */
09833       if ( *e == '<' ) { /* XXX the spec says it must not be in <> ! */
09834          ast_debug(3, "Oops. Bogus uri in <> %s\n", e);
09835          e++;
09836          if (!*e)
09837             return -1; 
09838       }
09839       req->rlPart2 = e - req->data->str;  /* URI */
09840       e = ast_skip_nonblanks(e);
09841       if (*e)
09842          *e++ = '\0';
09843       e = ast_skip_blanks(e);
09844       if (strcasecmp(e, "SIP/2.0") ) {
09845          ast_debug(3, "Skipping packet - Bad request protocol %s\n", e);
09846          return -1;
09847       }
09848    }
09849    return 1;
09850 }

static int dialog_cmp_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Note:
The only member of the dialog used here callid string

Definition at line 1793 of file chan_sip.c.

References sip_pvt::callid, CMP_MATCH, and CMP_STOP.

Referenced by load_module().

01794 {
01795    struct sip_pvt *pvt = obj, *pvt2 = arg;
01796    
01797    return !strcasecmp(pvt->callid, pvt2->callid) ? CMP_MATCH | CMP_STOP : 0;
01798 }

static int dialog_dump_func ( void *  userobj,
void *  arg,
int  flags 
) [static]

Definition at line 14072 of file chan_sip.c.

References ao2_t_ref, ast_cli(), and sip_pvt::callid.

Referenced by sip_show_objects().

14073 {
14074    struct sip_pvt *pvt = userobj;
14075    int refc = ao2_t_ref(userobj, 0, "");
14076    int *fd = arg;
14077    
14078    ast_cli(*fd, "name: %s\ntype: dialog\nobjflags: %d\nrefcount: %d\n\n", 
14079           pvt->callid, 0, refc);
14080    return 0;
14081 }

static int dialog_hash_cb ( const void *  obj,
const int  flags 
) [static]

Note:
The only member of the dialog used here callid string

Definition at line 1783 of file chan_sip.c.

References ast_str_case_hash(), and sip_pvt::callid.

Referenced by load_module().

01784 {
01785    const struct sip_pvt *pvt = obj;
01786 
01787    return ast_str_case_hash(pvt->callid);
01788 }

static int dialog_needdestroy ( void *  dialogobj,
void *  arg,
int  flags 
) [static]

Definition at line 14187 of file chan_sip.c.

References ao2_lock(), ao2_unlock(), ast_debug, ast_rtp_get_bridged(), sip_pvt::callid, check_rtp_timeout(), dialog_unlink_all(), dialogs, FALSE, sip_pvt::method, sip_pvt::needdestroy, sip_pvt::owner, sip_pvt::packets, sip_pvt::rtp, sip_methods, sip_pvt_trylock, sip_pvt_unlock, TRUE, and sip_pvt::vrtp.

Referenced by do_monitor().

14188 {
14189    struct sip_pvt *dialog = dialogobj;
14190    time_t *t = arg;
14191    
14192    /* log_show_lock(ao2_object_get_lockaddr(dialog)); this is an example of how to use log_show_lock() */
14193 
14194    if (sip_pvt_trylock(dialog)) {
14195       /* In very short-duration calls via sipp,
14196          this path gets executed fairly frequently (3% or so) even in low load
14197          situations; the routines we most commonly fight for a lock with:
14198          sip_answer (7 out of 9)
14199          sip_hangup (2 out of 9)
14200       */
14201       ao2_unlock(dialogs);
14202       usleep(1);
14203       ao2_lock(dialogs);
14204 
14205       /* I had previously returned CMP_STOP here; but changed it to return
14206          a zero instead, because there is no need to stop at the first sign
14207          of trouble. The old algorithm would restart in such circumstances,
14208          but there is no need for this now in astobj2-land. We'll
14209          just skip over this element this time, and catch it on the
14210          next traversal, which is about once a second or so. See the 
14211          ao2_callback call in do_monitor. We don't want the number of
14212          dialogs to back up too much between runs.
14213       */
14214       return 0;
14215    }
14216    
14217    /* Check RTP timeouts and kill calls if we have a timeout set and do not get RTP */
14218    check_rtp_timeout(dialog, *t);
14219 
14220    /* If we have sessions that needs to be destroyed, do it now */
14221    /* Check if we have outstanding requests not responsed to or an active call
14222       - if that's the case, wait with destruction */
14223    if (dialog->needdestroy && !dialog->packets && !dialog->owner) {
14224       /* We absolutely cannot destroy the rtp struct while a bridge is active or we WILL crash */
14225       if (dialog->rtp && ast_rtp_get_bridged(dialog->rtp)) {
14226          ast_debug(2, "Bridge still active.  Delaying destruction of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text);
14227          sip_pvt_unlock(dialog);
14228          return 0;
14229       }
14230       
14231       if (dialog->vrtp && ast_rtp_get_bridged(dialog->vrtp)) {
14232          ast_debug(2, "Bridge still active.  Delaying destroy of SIP dialog '%s' Method: %s\n", dialog->callid, sip_methods[dialog->method].text);
14233          sip_pvt_unlock(dialog);
14234          return 0;
14235       }
14236 
14237       sip_pvt_unlock(dialog);
14238       /* no, the unlink should handle this: dialog_unref(dialog, "needdestroy: one more refcount decrement to allow dialog to be destroyed"); */
14239       /* the CMP_MATCH will unlink this dialog from the dialog hash table */
14240       dialog_unlink_all(dialog, TRUE, FALSE);
14241       return 0; /* the unlink_all should unlink this from the table, so.... no need to return a match */
14242    }
14243 
14244    sip_pvt_unlock(dialog);
14245 
14246    return 0;
14247 }

static struct sip_pvt* dialog_ref ( struct sip_pvt p,
char *  tag 
) [static]

when we create or delete references, make sure to use these functions so we keep track of the refcounts. To simplify the code, we allow a NULL to be passed to dialog_unref().

Definition at line 1450 of file chan_sip.c.

References ao2_ref, ast_log(), and LOG_ERROR.

Referenced by __sip_reliable_xmit(), dialog_unlink_all(), handle_request_invite(), handle_request_subscribe(), handle_response_invite(), manager_sipnotify(), queue_request(), sip_call(), sip_cli_notify(), sip_new(), sip_poke_peer(), sip_scheddestroy(), sip_send_mwi_to_peer(), start_session_timer(), transmit_register(), and update_provisional_keepalive().

01451 {
01452    if (p)
01453       ao2_ref(p, 1);
01454    else
01455       ast_log(LOG_ERROR, "Attempt to Ref a null pointer\n");
01456    return p;
01457 }

static void * dialog_unlink_all ( struct sip_pvt dialog,
int  lockowner,
int  lockdialoglist 
) [static]

Unlink a dialog from the dialogs container, as well as any other places that it may be currently stored.

Note:
A reference to the dialog must be held before calling this function, and this function does not release that reference.

Definition at line 2793 of file chan_sip.c.

References ao2_t_unlink, ast_channel_lock, ast_channel_unlock, ast_debug, ast_extension_state_del(), ast_free, AST_SCHED_DEL, AST_SCHED_DEL_UNREF, sip_pvt::autokillid, sip_peer::call, sip_registry::call, sip_pkt::data, dialog_ref(), dialog_unref(), dialogs, sip_pvt::initid, sip_peer::mwipvt, ast_channel::name, sip_pkt::next, sip_pkt::owner, sip_pvt::owner, sip_pvt::packets, sip_pvt::provisional_keepalive_sched_id, sip_pvt::registry, registry_unref(), sip_pvt::relatedpeer, sip_pvt::request_queue_sched_id, sip_pkt::retransid, sched, sip_pvt::stateid, sip_pvt::t38id, ast_channel::tech_pvt, and sip_pvt::waitid.

Referenced by __sip_autodestruct(), dialog_needdestroy(), handle_request_subscribe(), manager_sipnotify(), reload_config(), sip_cli_notify(), sip_destroy_peer(), sip_poke_noanswer(), sip_poke_peer(), sip_registry_destroy(), sip_request_call(), sip_send_mwi_to_peer(), transmit_register(), and unload_module().

02794 {
02795    struct sip_pkt *cp;
02796 
02797    dialog_ref(dialog, "Let's bump the count in the unlink so it doesn't accidentally become dead before we are done");
02798 
02799    ao2_t_unlink(dialogs, dialog, "unlinking dialog via ao2_unlink");
02800 
02801    /* Unlink us from the owner (channel) if we have one */
02802    if (dialog->owner) {
02803       if (lockowner)
02804          ast_channel_lock(dialog->owner);
02805       ast_debug(1, "Detaching from channel %s\n", dialog->owner->name);
02806       dialog->owner->tech_pvt = dialog_unref(dialog->owner->tech_pvt, "resetting channel dialog ptr in unlink_all");
02807       if (lockowner)
02808          ast_channel_unlock(dialog->owner);
02809    }
02810    if (dialog->registry) {
02811       if (dialog->registry->call == dialog)
02812          dialog->registry->call = dialog_unref(dialog->registry->call, "nulling out the registry's call dialog field in unlink_all");
02813       dialog->registry = registry_unref(dialog->registry, "delete dialog->registry");
02814    }
02815    if (dialog->stateid > -1) {
02816       ast_extension_state_del(dialog->stateid, NULL);
02817       dialog_unref(dialog, "removing extension_state, should unref the associated dialog ptr that was stored there.");
02818       dialog->stateid = -1; /* shouldn't we 'zero' this out? */
02819    }
02820    /* Remove link from peer to subscription of MWI */
02821    if (dialog->relatedpeer && dialog->relatedpeer->mwipvt == dialog)
02822       dialog->relatedpeer->mwipvt = dialog_unref(dialog->relatedpeer->mwipvt, "delete ->relatedpeer->mwipvt");
02823    if (dialog->relatedpeer && dialog->relatedpeer->call == dialog)
02824       dialog->relatedpeer->call = dialog_unref(dialog->relatedpeer->call, "unset the relatedpeer->call field in tandem with relatedpeer field itself");
02825 
02826    /* remove all current packets in this dialog */
02827    while((cp = dialog->packets)) {
02828       dialog->packets = dialog->packets->next;
02829       AST_SCHED_DEL(sched, cp->retransid);
02830       dialog_unref(cp->owner, "remove all current packets in this dialog, and the pointer to the dialog too as part of __sip_destroy");
02831       if (cp->data) {
02832          ast_free(cp->data);
02833       }
02834       ast_free(cp);
02835    }
02836 
02837    AST_SCHED_DEL_UNREF(sched, dialog->waitid, dialog_unref(dialog, "when you delete the waitid sched, you should dec the refcount for the stored dialog ptr"));
02838 
02839    AST_SCHED_DEL_UNREF(sched, dialog->initid, dialog_unref(dialog, "when you delete the initid sched, you should dec the refcount for the stored dialog ptr"));
02840    
02841    if (dialog->autokillid > -1)
02842       AST_SCHED_DEL_UNREF(sched, dialog->autokillid, dialog_unref(dialog, "when you delete the autokillid sched, you should dec the refcount for the stored dialog ptr"));
02843 
02844    if (dialog->request_queue_sched_id > -1) {
02845       AST_SCHED_DEL_UNREF(sched, dialog->request_queue_sched_id, dialog_unref(dialog, "when you delete the request_queue_sched_id sched, you should dec the refcount for the stored dialog ptr"));
02846    }
02847 
02848    AST_SCHED_DEL_UNREF(sched, dialog->provisional_keepalive_sched_id, dialog_unref(dialog, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr"));
02849 
02850    if (dialog->t38id > -1) {
02851       AST_SCHED_DEL_UNREF(sched, dialog->t38id, dialog_unref(dialog, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr"));
02852    }
02853 
02854    dialog_unref(dialog, "Let's unbump the count in the unlink so the poor pvt can disappear if it is time");
02855    return NULL;
02856 }

static struct sip_pvt* dialog_unref ( struct sip_pvt p,
char *  tag 
) [static]

Definition at line 1459 of file chan_sip.c.

References ao2_ref.

Referenced by __sip_ack(), __sip_autodestruct(), __sip_destroy(), __sip_reliable_xmit(), auto_congest(), complete_sipch(), dialog_unlink_all(), get_also_info(), handle_invite_replaces(), handle_request_do(), handle_request_invite(), handle_request_subscribe(), handle_response_invite(), handle_response_peerpoke(), handle_response_register(), interpret_t38_parameters(), manager_sipnotify(), proc_session_timer(), queue_request(), reload_config(), restart_session_timer(), retrans_pkt(), send_response(), sip_call(), sip_cancel_destroy(), sip_cli_notify(), sip_destroy_peer(), sip_hangup(), sip_poke_noanswer(), sip_poke_peer(), sip_reg_timeout(), sip_registry_destroy(), sip_reinvite_retry(), sip_request_call(), sip_send_mwi_to_peer(), sip_t38_abort(), start_session_timer(), stop_session_timer(), transmit_register(), and update_provisional_keepalive().

01460 {
01461    if (p)
01462       ao2_ref(p, -1);
01463    return NULL;
01464 }

static void * do_monitor ( void *  data  )  [static]

The SIP monitoring thread.

Note:
This thread monitors all the SIP sessions and peers that needs notification of mwi (and thus do not have a separate thread) indefinitely

Definition at line 21499 of file chan_sip.c.

References ao2_t_callback, ast_debug, ast_io_add(), ast_io_change(), AST_IO_IN, ast_io_remove(), ast_io_wait(), ast_mutex_lock(), ast_mutex_unlock(), ast_sched_runq(), ast_sched_wait(), ast_verb, dialog_needdestroy(), dialogs, FALSE, io, monlock, OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, sched, sip_do_reload(), sip_reload_lock, and sipsock_read().

21500 {
21501    int res;
21502    time_t t;
21503    int reloading;
21504 
21505    /* Add an I/O event to our SIP UDP socket */
21506    if (sipsock > -1) 
21507       sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
21508 
21509    /* From here on out, we die whenever asked */
21510    for(;;) {
21511       /* Check for a reload request */
21512       ast_mutex_lock(&sip_reload_lock);
21513       reloading = sip_reloading;
21514       sip_reloading = FALSE;
21515       ast_mutex_unlock(&sip_reload_lock);
21516       if (reloading) {
21517          ast_verb(1, "Reloading SIP\n");
21518          sip_do_reload(sip_reloadreason);
21519 
21520          /* Change the I/O fd of our UDP socket */
21521          if (sipsock > -1) {
21522             if (sipsock_read_id)
21523                sipsock_read_id = ast_io_change(io, sipsock_read_id, sipsock, NULL, 0, NULL);
21524             else
21525                sipsock_read_id = ast_io_add(io, sipsock, sipsock_read, AST_IO_IN, NULL);
21526          } else if (sipsock_read_id) {
21527             ast_io_remove(io, sipsock_read_id);
21528             sipsock_read_id = NULL;
21529          }
21530       }
21531 
21532       /* Check for dialogs needing to be killed */
21533       t = time(NULL);
21534       /* don't scan the dialogs list if it hasn't been a reasonable period
21535          of time since the last time we did it (when MWI is being sent, we can
21536          get back to this point every millisecond or less)
21537       */
21538       ao2_t_callback(dialogs, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE, dialog_needdestroy, &t, 
21539             "callback to remove dialogs w/needdestroy");
21540 
21541       /* the old methodology would be to restart the search for dialogs to delete with every 
21542          dialog that was found and destroyed, probably because the list contents would change,
21543          so we'd need to restart. This isn't the best thing to do with callbacks. */
21544 
21545       /* XXX TODO The scheduler usage in this module does not have sufficient 
21546        * synchronization being done between running the scheduler and places 
21547        * scheduling tasks.  As it is written, any scheduled item may not run 
21548        * any sooner than about  1 second, regardless of whether a sooner time 
21549        * was asked for. */
21550 
21551       pthread_testcancel();
21552       /* Wait for sched or io */
21553       res = ast_sched_wait(sched);
21554       if ((res < 0) || (res > 1000))
21555          res = 1000;
21556       res = ast_io_wait(io, res);
21557       if (res > 20)
21558          ast_debug(1, "chan_sip: ast_io_wait ran %d all at once\n", res);
21559       ast_mutex_lock(&monlock);
21560       res = ast_sched_runq(sched);
21561       if (res >= 20)
21562          ast_debug(1, "chan_sip: ast_sched_runq ran %d all at once\n", res);
21563       ast_mutex_unlock(&monlock);
21564    }
21565 
21566    /* Never reached */
21567    return NULL;
21568 }

static int do_proxy_auth ( struct sip_pvt p,
struct sip_request req,
enum sip_auth_type  code,
int  sipmethod,
int  init 
) [static]

Add authentication on outbound SIP packet.

Definition at line 16235 of file chan_sip.c.

References ast_calloc, ast_debug, sip_invite_param::auth, auth_headers(), sip_invite_param::authheader, sip_pvt::authtries, sip_pvt::options, reply_digest(), SIP_INVITE, sip_methods, cfsip_methods::text, and transmit_invite().

Referenced by handle_response(), handle_response_invite(), handle_response_notify(), and handle_response_refer().

16236 {
16237    char *header, *respheader;
16238    char digest[1024];
16239 
16240    if (!p->options && !(p->options = ast_calloc(1, sizeof(*p->options))))
16241       return -2;
16242 
16243    p->authtries++;
16244    auth_headers(code, &header, &respheader);
16245    ast_debug(2, "Auth attempt %d on %s\n", p->authtries, sip_methods[sipmethod].text);
16246    memset(digest, 0, sizeof(digest));
16247    if (reply_digest(p, req, header, sipmethod, digest, sizeof(digest) )) {
16248       /* No way to authenticate */
16249       return -1;
16250    }
16251    /* Now we have a reply digest */
16252    p->options->auth = digest;
16253    p->options->authheader = respheader;
16254    return transmit_invite(p, sipmethod, sipmethod == SIP_INVITE, init); 
16255 }

static int do_register_auth ( struct sip_pvt p,
struct sip_request req,
enum sip_auth_type  code 
) [static]

Authenticate for outbound registration.

Definition at line 16211 of file chan_sip.c.

References append_history, ast_verbose, auth_headers(), sip_pvt::authtries, sip_pvt::do_history, sip_registry::hostname, sip_pvt::registry, reply_digest(), sip_debug_test_pvt(), SIP_REGISTER, and transmit_register().

Referenced by handle_response_register().

16212 {
16213    char *header, *respheader;
16214    char digest[1024];
16215 
16216    p->authtries++;
16217    auth_headers(code, &header, &respheader);
16218    memset(digest, 0, sizeof(digest));
16219    if (reply_digest(p, req, header, SIP_REGISTER, digest, sizeof(digest))) {
16220       /* There's nothing to use for authentication */
16221       /* No digest challenge in request */
16222       if (sip_debug_test_pvt(p) && p->registry)
16223          ast_verbose("No authentication challenge, sending blank registration to domain/host name %s\n", p->registry->hostname);
16224          /* No old challenge */
16225       return -1;
16226    }
16227    if (p->do_history)
16228       append_history(p, "RegistryAuth", "Try: %d", p->authtries);
16229    if (sip_debug_test_pvt(p) && p->registry)
16230       ast_verbose("Responding to challenge, registration to domain/host name %s\n", p->registry->hostname);
16231    return transmit_register(p->registry, SIP_REGISTER, digest, respheader); 
16232 }

static void do_setnat ( struct sip_pvt p,
int  natflags 
) [static]

Set nat mode on the various data sockets.

Definition at line 4621 of file chan_sip.c.

References ast_debug, ast_rtp_setnat(), ast_udptl_setnat(), sip_pvt::rtp, sip_pvt::trtp, sip_pvt::udptl, and sip_pvt::vrtp.

Referenced by check_peer_ok(), create_addr(), create_addr_from_peer(), sip_alloc(), and transmit_response_using_temp().

04622 {
04623    const char *mode = natflags ? "On" : "Off";
04624 
04625    if (p->rtp) {
04626       ast_debug(1, "Setting NAT on RTP to %s\n", mode);
04627       ast_rtp_setnat(p->rtp, natflags);
04628    }
04629    if (p->vrtp) {
04630       ast_debug(1, "Setting NAT on VRTP to %s\n", mode);
04631       ast_rtp_setnat(p->vrtp, natflags);
04632    }
04633    if (p->udptl) {
04634       ast_debug(1, "Setting NAT on UDPTL to %s\n", mode);
04635       ast_udptl_setnat(p->udptl, natflags);
04636    }
04637    if (p->trtp) {
04638       ast_debug(1, "Setting NAT on TRTP to %s\n", mode);
04639       ast_rtp_setnat(p->trtp, natflags);
04640    }
04641 }

static const char * domain_mode_to_text ( const enum domain_mode  mode  )  [static]

Print domain mode to cli.

Definition at line 14405 of file chan_sip.c.

References SIP_DOMAIN_AUTO, and SIP_DOMAIN_CONFIG.

Referenced by sip_show_domains().

14406 {
14407    switch (mode) {
14408    case SIP_DOMAIN_AUTO:
14409       return "[Automatic]";
14410    case SIP_DOMAIN_CONFIG:
14411       return "[Configured]";
14412    }
14413 
14414    return "";
14415 }

static const char * dtmfmode2str ( int  mode  )  const [static]

Convert DTMF mode to printable string.

Definition at line 14128 of file chan_sip.c.

References dtmfstr, and map_x_s().

Referenced by _sip_show_peer(), sip_show_channel(), and sip_show_settings().

14129 {
14130    return map_x_s(dtmfstr, mode, "<error>");
14131 }

static int expire_register ( const void *  data  )  [static]

Expire registration of SIP peer.

Definition at line 11228 of file chan_sip.c.

References sip_peer::addr, ao2_ref, ao2_t_unlink, ast_debug, AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_test_flag, sip_peer::default_outbound_transport, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, FALSE, sip_peer::flags, sip_peer::is_realtime, manager_event, sip_peer::name, peers, peers_by_ip, sip_peer::portinuri, register_peer_exten(), sip_peer::selfdestruct, set_socket_transport(), SIP_PAGE2_RTAUTOCLEAR, sip_peer::socket, sip_socket::tcptls_session, and unref_peer().

Referenced by parse_register_contact(), reg_source_db(), sip_show_sched(), and sip_unregister().

11229 {
11230    struct sip_peer *peer = (struct sip_peer *)data;
11231 
11232    if (!peer)     /* Hmmm. We have no peer. Weird. */
11233       return 0;
11234 
11235    peer->expire = -1;
11236    peer->portinuri = 0;
11237    memset(&peer->addr, 0, sizeof(peer->addr));
11238 
11239    destroy_association(peer); /* remove registration data from storage */
11240    set_socket_transport(&peer->socket, peer->default_outbound_transport);
11241 
11242    if (peer->socket.tcptls_session) {
11243       ao2_ref(peer->socket.tcptls_session, -1);
11244       peer->socket.tcptls_session = NULL;
11245    }
11246 
11247    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\nCause: Expired\r\n", peer->name);
11248    register_peer_exten(peer, FALSE);   /* Remove regexten */
11249    ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
11250 
11251    /* Do we need to release this peer from memory? 
11252       Only for realtime peers and autocreated peers
11253    */
11254    if (peer->is_realtime)
11255       ast_debug(3, "-REALTIME- peer expired registration. Name: %s. Realtime peer objects now %d\n", peer->name, rpeerobjs);
11256 
11257    if (peer->selfdestruct ||
11258        ast_test_flag(&peer->flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
11259       ao2_t_unlink(peers, peer, "ao2_unlink of peer from peers table");
11260       if (peer->addr.sin_addr.s_addr) {
11261          ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table");
11262       }
11263    }
11264 
11265    unref_peer(peer, "removing peer ref for expire_register");
11266 
11267    return 0;
11268 }

static void extract_uri ( struct sip_pvt p,
struct sip_request req 
) [static]

Check Contact: URI of SIP message.

Definition at line 9911 of file chan_sip.c.

References ast_copy_string(), ast_string_field_set, ast_strlen_zero(), get_header(), get_in_brackets(), remove_uri_parameters(), and SIPBUFSIZE.

Referenced by handle_incoming(), and handle_request_invite().

09912 {
09913    char stripped[SIPBUFSIZE];
09914    char *c;
09915 
09916    ast_copy_string(stripped, get_header(req, "Contact"), sizeof(stripped));
09917    c = get_in_brackets(stripped);
09918    /* Cut the URI at the at sign after the @, not in the username part */
09919    c = remove_uri_parameters(c);
09920    if (!ast_strlen_zero(c))
09921       ast_string_field_set(p, uri, c);
09922 
09923 }

static const char* faxec2str ( int  faxec  )  [static]

Definition at line 14575 of file chan_sip.c.

References faxecmodes, and map_x_s().

Referenced by _sip_show_peer(), and sip_show_settings().

14576 {
14577    return map_x_s(faxecmodes, faxec, "Unknown");
14578 }

static const char * find_alias ( const char *  name,
const char *  _default 
) [static]

Find compressed SIP alias.

Structure for conversion between compressed SIP and "normal" SIP

Definition at line 6457 of file chan_sip.c.

References aliases, and ARRAY_LEN.

06458 {
06459    /*! \brief Structure for conversion between compressed SIP and "normal" SIP */
06460    static const struct cfalias {
06461       char * const fullname;
06462       char * const shortname;
06463    } aliases[] = {
06464       { "Content-Type",  "c" },
06465       { "Content-Encoding",    "e" },
06466       { "From",       "f" },
06467       { "Call-ID",       "i" },
06468       { "Contact",       "m" },
06469       { "Content-Length",   "l" },
06470       { "Subject",       "s" },
06471       { "To",         "t" },
06472       { "Supported",     "k" },
06473       { "Refer-To",      "r" },
06474       { "Referred-By",   "b" },
06475       { "Allow-Events",  "u" },
06476       { "Event",      "o" },
06477       { "Via",     "v" },
06478       { "Accept-Contact",      "a" },
06479       { "Reject-Contact",      "j" },
06480       { "Request-Disposition", "d" },
06481       { "Session-Expires",     "x" },
06482       { "Identity",            "y" },
06483       { "Identity-Info",       "n" },
06484    };
06485    int x;
06486 
06487    for (x = 0; x < ARRAY_LEN(aliases); x++) {
06488       if (!strcasecmp(aliases[x].fullname, name))
06489          return aliases[x].shortname;
06490    }
06491 
06492    return _default;
06493 }

static int find_by_name ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 4547 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, FINDALLDEVICES, FINDPEERS, FINDUSERS, sip_peer::name, SIP_TYPE_PEER, SIP_TYPE_USER, peer_finding_info::tmp_peer, sip_peer::type, and peer_finding_info::which_objects.

Referenced by find_peer().

04548 {
04549    struct sip_peer *search = obj;
04550    struct peer_finding_info *pfi = arg;
04551 
04552    /* Usernames in SIP uri's are case sensitive. Domains are not */
04553    if (strcmp(search->name, pfi->tmp_peer.name)) {
04554       return 0;
04555    }
04556 
04557    switch (pfi->which_objects) {
04558    case FINDUSERS:
04559       if (!(search->type & SIP_TYPE_USER)) {
04560          return 0;
04561       }
04562       break;
04563    case FINDPEERS:
04564       if (!(search->type & SIP_TYPE_PEER)) {
04565          return 0;
04566       }
04567       break;
04568    case FINDALLDEVICES:
04569       break;
04570    }
04571 
04572    return CMP_MATCH | CMP_STOP;
04573 }

static struct sip_pvt * find_call ( struct sip_request req,
struct sockaddr_in *  sin,
const int  intended_method 
) [static]

find or create a dialog structure for an incoming SIP message. Connect incoming SIP message to current dialog or create new dialog structure Returns a reference to the sip_pvt object, remember to give it back once done. Called by handle_incoming(), sipsock_read

Definition at line 6934 of file chan_sip.c.

References ao2_lock(), ao2_t_callback, ao2_t_find, ao2_unlock(), ast_debug, ast_strlen_zero(), sip_pvt::callid, find_call_cb_arg::callid, CAN_CREATE_DIALOG, dialogs, find_call_cb(), find_call_cb_arg::fromtag, get_header(), gettag(), sip_request::method, find_call_cb_arg::method, OBJ_POINTER, SIP_ACK, sip_alloc(), SIP_BYE, SIP_INFO, sip_methods, SIP_NOTIFY, sip_pvt_lock, sip_pvt_trylock, SIP_REFER, SIP_RESPONSE, find_call_cb_arg::tag, cfsip_methods::text, find_call_cb_arg::totag, and transmit_response_using_temp().

Referenced by handle_request_do().

06935 {
06936    struct sip_pvt *p = NULL;
06937    char *tag = "";   /* note, tag is never NULL */
06938    char totag[128];
06939    char fromtag[128];
06940    struct find_call_cb_arg arg;
06941    const char *callid = get_header(req, "Call-ID");
06942    const char *from = get_header(req, "From");
06943    const char *to = get_header(req, "To");
06944    const char *cseq = get_header(req, "Cseq");
06945    struct sip_pvt *sip_pvt_ptr;
06946 
06947    /* Call-ID, to, from and Cseq are required by RFC 3261. (Max-forwards and via too - ignored now) */
06948    /* get_header always returns non-NULL so we must use ast_strlen_zero() */
06949    if (ast_strlen_zero(callid) || ast_strlen_zero(to) ||
06950          ast_strlen_zero(from) || ast_strlen_zero(cseq))
06951       return NULL;   /* Invalid packet */
06952 
06953    arg.method = req->method;
06954    arg.callid = callid;
06955    arg.fromtag = fromtag;
06956    arg.totag = totag;
06957    arg.tag = ""; /* make sure tag is never NULL */
06958 
06959    if (pedanticsipchecking) {
06960       /* In principle Call-ID's uniquely identify a call, but with a forking SIP proxy
06961          we need more to identify a branch - so we have to check branch, from
06962          and to tags to identify a call leg.
06963          For Asterisk to behave correctly, you need to turn on pedanticsipchecking
06964          in sip.conf
06965          */
06966       if (gettag(req, "To", totag, sizeof(totag)))
06967          req->has_to_tag = 1; /* Used in handle_request/response */
06968       gettag(req, "From", fromtag, sizeof(fromtag));
06969 
06970       tag = (req->method == SIP_RESPONSE) ? totag : fromtag;
06971 
06972       ast_debug(5, "= Looking for  Call ID: %s (Checking %s) --From tag %s --To-tag %s  \n", callid, req->method==SIP_RESPONSE ? "To" : "From", fromtag, totag);
06973 
06974       /* All messages must always have From: tag */
06975       if (ast_strlen_zero(fromtag)) {
06976          ast_debug(5, "%s request has no from tag, dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from );
06977          return NULL;
06978       }
06979       /* reject requests that must always have a To: tag */
06980       if (ast_strlen_zero(totag) && (req->method == SIP_ACK || req->method == SIP_BYE || req->method == SIP_INFO )) {
06981          ast_debug(5, "%s must have a to tag. dropping callid: %s from: %s\n", sip_methods[req->method].text , callid, from );
06982          return NULL;
06983       }
06984    }
06985 
06986 restartsearch:
06987    if (!pedanticsipchecking) {
06988       struct sip_pvt tmp_dialog = {
06989          .callid = callid,
06990       };       
06991       sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find in dialogs");
06992       if (sip_pvt_ptr) {  /* well, if we don't find it-- what IS in there? */
06993          /* Found the call */
06994          sip_pvt_lock(sip_pvt_ptr);
06995          return sip_pvt_ptr;
06996       }
06997    } else { /* in pedantic mode! -- do the fancy linear search */
06998       ao2_lock(dialogs);
06999       p = ao2_t_callback(dialogs, 0 /* single, data */, find_call_cb, &arg, "pedantic linear search for dialog");
07000       if (p) {
07001          if (sip_pvt_trylock(p)) {
07002             ao2_unlock(dialogs);
07003             usleep(1);
07004             goto restartsearch;
07005          }
07006          ao2_unlock(dialogs);
07007          return p;
07008       }
07009       ao2_unlock(dialogs);
07010    }
07011  
07012    /* See if the method is capable of creating a dialog */
07013    if (sip_methods[intended_method].can_create == CAN_CREATE_DIALOG) {
07014       if (intended_method == SIP_REFER) {
07015          /* We do support REFER, but not outside of a dialog yet */
07016          transmit_response_using_temp(callid, sin, 1, intended_method, req, "603 Declined (no dialog)");
07017       } else if (intended_method == SIP_NOTIFY) {
07018          /* We do not support out-of-dialog NOTIFY either,
07019             like voicemail notification, so cancel that early */
07020          transmit_response_using_temp(callid, sin, 1, intended_method, req, "489 Bad event");
07021       } else {
07022          /* Ok, time to create a new SIP dialog object, a pvt */
07023          if ((p = sip_alloc(callid, sin, 1, intended_method, req)))  {
07024             /* Ok, we've created a dialog, let's go and process it */
07025             sip_pvt_lock(p);
07026          } else {
07027             /* We have a memory or file/socket error (can't allocate RTP sockets or something) so we're not
07028                getting a dialog from sip_alloc. 
07029    
07030                Without a dialog we can't retransmit and handle ACKs and all that, but at least
07031                send an error message.
07032    
07033                Sorry, we apologize for the inconvienience
07034             */
07035             transmit_response_using_temp(callid, sin, 1, intended_method, req, "500 Server internal error");
07036             ast_debug(4, "Failed allocating SIP dialog, sending 500 Server internal error and giving up\n");
07037          }
07038       }
07039       return p; /* can be NULL */
07040    } else if( sip_methods[intended_method].can_create == CAN_CREATE_DIALOG_UNSUPPORTED_METHOD) {
07041       /* A method we do not support, let's take it on the volley */
07042       transmit_response_using_temp(callid, sin, 1, intended_method, req, "501 Method Not Implemented");
07043       ast_debug(2, "Got a request with unsupported SIP method.\n");
07044    } else if (intended_method != SIP_RESPONSE && intended_method != SIP_ACK) {
07045       /* This is a request outside of a dialog that we don't know about */
07046       transmit_response_using_temp(callid, sin, 1, intended_method, req, "481 Call leg/transaction does not exist");
07047       ast_debug(2, "That's odd...  Got a request in unknown dialog. Callid %s\n", callid ? callid : "<unknown>");
07048    }
07049    /* We do not respond to responses for dialogs that we don't know about, we just drop
07050       the session quickly */
07051    if (intended_method == SIP_RESPONSE)
07052       ast_debug(2, "That's odd...  Got a response on a call we dont know about. Callid %s\n", callid ? callid : "<unknown>");
07053 
07054    return NULL;
07055 }

static int find_call_cb ( void *  __pvt,
void *  __arg,
int  flags 
) [static]

code to determine whether this is the pvt that we are looking for. Return FALSE if not found, true otherwise. p is unlocked.

Definition at line 6893 of file chan_sip.c.

References ast_debug, ast_strlen_zero(), ast_test_flag, find_call_cb_arg::callid, sip_pvt::callid, FALSE, sip_pvt::flags, find_call_cb_arg::method, sip_methods, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_REGISTER, SIP_RESPONSE, sip_pvt::tag, find_call_cb_arg::tag, sip_pvt::theirtag, and find_call_cb_arg::totag.

Referenced by find_call().

06894 {
06895    struct sip_pvt *p = __pvt;
06896    struct find_call_cb_arg *arg = __arg;
06897    /* In pedantic, we do not want packets with bad syntax to be connected to a PVT */
06898    int found = FALSE;
06899    
06900    if (!ast_strlen_zero(p->callid)) { /* XXX double check, do we allow match on empty p->callid ? */
06901       if (arg->method == SIP_REGISTER)
06902          found = (!strcmp(p->callid, arg->callid));
06903       else {
06904          found = !strcmp(p->callid, arg->callid);
06905          if (pedanticsipchecking && found) {
06906             found = ast_strlen_zero(arg->tag) || ast_strlen_zero(p->theirtag) || !ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED) || !strcmp(p->theirtag, arg->tag);
06907          } 
06908       }
06909       
06910       ast_debug(5, "= %s Their Call ID: %s Their Tag %s Our tag: %s\n", found ? "Found" : "No match", p->callid, p->theirtag, p->tag);
06911       
06912       /* If we get a new request within an existing to-tag - check the to tag as well */
06913       if (pedanticsipchecking && found && arg->method != SIP_RESPONSE) { /* SIP Request */
06914          if (p->tag[0] == '\0' && arg->totag[0]) {
06915             /* We have no to tag, but they have. Wrong dialog */
06916             found = FALSE;
06917          } else if (arg->totag[0]) { /* Both have tags, compare them */
06918             if (strcmp(arg->totag, p->tag)) {
06919                found = FALSE; /* This is not our packet */
06920             }
06921          }
06922          if (!found)
06923             ast_debug(5, "= Being pedantic: This is not our match on request: Call ID: %s Ourtag <null> Totag %s Method %s\n", p->callid, arg->totag, sip_methods[arg->method].text);
06924       }
06925    }
06926    return found;
06927 }

static const char* find_closing_quote ( const char *  start,
const char *  lim 
) [static]

Locate closing quote in a string, skipping escaped quotes. optionally with a limit on the search. start must be past the first quote.

Definition at line 3933 of file chan_sip.c.

References s.

Referenced by get_in_brackets().

03934 {
03935    char last_char = '\0';
03936    const char *s;
03937    for (s = start; *s && s != lim; last_char = *s++) {
03938       if (*s == '"' && last_char != '\\')
03939          break;
03940    }
03941    return s;
03942 }

static struct sip_peer * find_peer ( const char *  peer,
struct sockaddr_in *  sin,
int  realtime,
int  which_objects,
int  devstate_only,
int  transport 
) [static]

Locate device by name or ip address.

Parameters:
which_objects Define which objects should be matched when doing a lookup by name. Valid options are FINDUSERS, FINDPEERS, or FINDALLDEVICES. Note that this option is not used at all when doing a lookup by IP.
This is used on find matching device on name or ip/port. If the device was declared as type=peer, we don't match on peer name on incoming INVITEs.

Note:
Avoid using this function in new functions if there is a way to avoid it, since it might cause a database lookup.

Definition at line 4588 of file chan_sip.c.

References sip_peer::addr, ao2_t_callback, ao2_t_find, ast_copy_string(), ast_set_flag, find_by_name(), ast_flags::flags, sip_peer::flags, sip_peer::name, OBJ_POINTER, peers, peers_by_ip, realtime_peer(), SIP_INSECURE_PORT, peer_finding_info::tmp_peer, sip_peer::transports, and peer_finding_info::which_objects.

04589 {
04590    struct sip_peer *p = NULL;
04591 
04592    if (peer) {
04593       struct peer_finding_info pfi = {
04594          .which_objects = which_objects,
04595       };
04596       ast_copy_string(pfi.tmp_peer.name, peer, sizeof(pfi.tmp_peer.name));
04597       p = ao2_t_callback(peers, OBJ_POINTER, find_by_name, &pfi, "ao2_callback in peers table");
04598    } else if (sin) { /* search by addr? */
04599       struct sip_peer tmp_peer;
04600       tmp_peer.addr.sin_addr.s_addr = sin->sin_addr.s_addr;
04601       tmp_peer.addr.sin_port = sin->sin_port;
04602       tmp_peer.flags[0].flags = 0;
04603       tmp_peer.transports = transport;
04604       p = ao2_t_find(peers_by_ip, &tmp_peer, OBJ_POINTER, "ao2_find in peers_by_ip table"); /* WAS:  p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); */
04605       if (!p) {
04606          ast_set_flag(&tmp_peer.flags[0], SIP_INSECURE_PORT);
04607          p = ao2_t_find(peers_by_ip, &tmp_peer, OBJ_POINTER, "ao2_find in peers_by_ip table 2"); /* WAS:  p = ASTOBJ_CONTAINER_FIND_FULL(&peerl, sin, name, sip_addr_hashfunc, 1, sip_addrcmp); */
04608          if (p) {
04609             return p;
04610          }
04611       }
04612    }
04613 
04614    if (!p && (realtime || devstate_only))
04615       p = realtime_peer(peer, sin, devstate_only);
04616 
04617    return p;
04618 }

static struct sip_auth * find_realm_authentication ( struct sip_auth authlist,
const char *  realm 
) [static]

Find authentication for a specific realm.

Definition at line 22634 of file chan_sip.c.

References sip_auth::next, and sip_auth::realm.

Referenced by build_reply_digest().

22635 {
22636    struct sip_auth *a;
22637 
22638    for (a = authlist; a; a = a->next) {
22639       if (!strcasecmp(a->realm, realm))
22640          break;
22641    }
22642 
22643    return a;
22644 }

static int find_sdp ( struct sip_request req  )  [static]

Determine whether a SIP message contains an SDP in its body.

Parameters:
req the SIP request to process
Returns:
1 if SDP found, 0 if not found
Also updates req->sdp_start and req->sdp_count to indicate where the SDP lives in the message body.

Definition at line 7298 of file chan_sip.c.

References ast_log(), ast_strdupa, ast_strlen_zero(), FALSE, get_header(), sip_request::lines, LOG_WARNING, REQ_OFFSET_TO_STR, sip_request::sdp_count, sip_request::sdp_start, strcasestr(), and TRUE.

Referenced by handle_incoming(), handle_request_invite(), handle_response(), and handle_response_invite().

07299 {
07300    const char *content_type;
07301    const char *content_length;
07302    const char *search;
07303    char *boundary;
07304    unsigned int x;
07305    int boundaryisquoted = FALSE;
07306    int found_application_sdp = FALSE;
07307    int found_end_of_headers = FALSE;
07308 
07309    content_length = get_header(req, "Content-Length");
07310 
07311    if (!ast_strlen_zero(content_length)) {
07312       if (sscanf(content_length, "%30u", &x) != 1) {
07313          ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length);
07314          return 0;
07315       }
07316 
07317       /* Content-Length of zero means there can't possibly be an
07318          SDP here, even if the Content-Type says there is */
07319       if (x == 0)
07320          return 0;
07321    }
07322 
07323    content_type = get_header(req, "Content-Type");
07324 
07325    /* if the body contains only SDP, this is easy */
07326    if (!strncasecmp(content_type, "application/sdp", 15)) {
07327       req->sdp_start = 0;
07328       req->sdp_count = req->lines;
07329       return req->lines ? 1 : 0;
07330    }
07331 
07332    /* if it's not multipart/mixed, there cannot be an SDP */
07333    if (strncasecmp(content_type, "multipart/mixed", 15))
07334       return 0;
07335 
07336    /* if there is no boundary marker, it's invalid */
07337    if ((search = strcasestr(content_type, ";boundary=")))
07338       search += 10;
07339    else if ((search = strcasestr(content_type, "; boundary=")))
07340       search += 11;
07341    else
07342       return 0;
07343 
07344    if (ast_strlen_zero(search))
07345       return 0;
07346 
07347    /* If the boundary is quoted with ", remove quote */
07348    if (*search == '\"')  {
07349       search++;
07350       boundaryisquoted = TRUE;
07351    }
07352 
07353    /* make a duplicate of the string, with two extra characters
07354       at the beginning */
07355    boundary = ast_strdupa(search - 2);
07356    boundary[0] = boundary[1] = '-';
07357    /* Remove final quote */
07358    if (boundaryisquoted)
07359       boundary[strlen(boundary) - 1] = '\0';
07360 
07361    /* search for the boundary marker, the empty line delimiting headers from
07362       sdp part and the end boundry if it exists */
07363 
07364    for (x = 0; x < (req->lines); x++) {
07365       char *line = REQ_OFFSET_TO_STR(req, line[x]);
07366       if (!strncasecmp(line, boundary, strlen(boundary))){
07367          if (found_application_sdp && found_end_of_headers) {
07368             req->sdp_count = (x - 1) - req->sdp_start;
07369             return 1;
07370          }
07371          found_application_sdp = FALSE;
07372       }
07373       if (!strcasecmp(line, "Content-Type: application/sdp"))
07374          found_application_sdp = TRUE;
07375       
07376       if (ast_strlen_zero(line)) {
07377          if (found_application_sdp && !found_end_of_headers){
07378             req->sdp_start = x;
07379             found_end_of_headers = TRUE;
07380          }
07381       }
07382    }
07383    if (found_application_sdp && found_end_of_headers) {
07384       req->sdp_count = x - req->sdp_start;
07385       return TRUE;
07386    }
07387    return FALSE;
07388 }

static int find_sip_method ( const char *  msg  )  [static]

find_sip_method: Find SIP method from header

Definition at line 2998 of file chan_sip.c.

References ARRAY_LEN, ast_strlen_zero(), cfsip_methods::id, method_match(), and sip_methods.

Referenced by __sip_pretend_ack(), handle_request_do(), handle_response(), and sip_hangup().

02999 {
03000    int i, res = 0;
03001    
03002    if (ast_strlen_zero(msg))
03003       return 0;
03004    for (i = 1; i < ARRAY_LEN(sip_methods) && !res; i++) {
03005       if (method_match(i, msg))
03006          res = sip_methods[i].id;
03007    }
03008    return res;
03009 }

static struct cfsubscription_types * find_subscription_type ( enum subscriptiontype  subtype  )  [static]

Find subscription type in array.

Definition at line 15356 of file chan_sip.c.

References ARRAY_LEN, and subscription_types.

Referenced by transmit_state_notify().

15357 {
15358    int i;
15359 
15360    for (i = 1; i < ARRAY_LEN(subscription_types); i++) {
15361       if (subscription_types[i].type == subtype) {
15362          return &subscription_types[i];
15363       }
15364    }
15365    return &subscription_types[0];
15366 }

static void free_old_route ( struct sip_route route  )  [static]

Remove route from route list.

Definition at line 11627 of file chan_sip.c.

References ast_free, sip_route::next, and sip_request::next.

Referenced by __sip_destroy(), and build_route().

11628 {
11629    struct sip_route *next;
11630 
11631    while (route) {
11632       next = route->next;
11633       ast_free(route);
11634       route = next;
11635    }
11636 }

static int func_check_sipdomain ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

Dial plan function to check if domain is local.

Definition at line 16477 of file chan_sip.c.

References ast_copy_string(), ast_log(), ast_strlen_zero(), check_sip_domain(), and LOG_WARNING.

16478 {
16479    if (ast_strlen_zero(data)) {
16480       ast_log(LOG_WARNING, "CHECKSIPDOMAIN requires an argument - A domain name\n");
16481       return -1;
16482    }
16483    if (check_sip_domain(data, NULL, 0))
16484       ast_copy_string(buf, data, len);
16485    else
16486       buf[0] = '\0';
16487    return 0;
16488 }

static int func_header_read ( struct ast_channel chan,
const char *  function,
char *  data,
char *  buf,
size_t  len 
) [static]

Read SIP header (dialplan function).

Definition at line 16413 of file chan_sip.c.

References __get_header(), AST_APP_ARG, ast_channel_lock, ast_channel_unlock, ast_copy_string(), AST_DECLARE_APP_ARGS, ast_log(), AST_STANDARD_APP_ARGS, ast_strlen_zero(), chan, sip_request::header, sip_pvt::initreq, IS_SIP_TECH, LOG_WARNING, ast_channel::tech, and ast_channel::tech_pvt.

16414 {
16415    struct sip_pvt *p;
16416    const char *content = NULL;
16417    AST_DECLARE_APP_ARGS(args,
16418       AST_APP_ARG(header);
16419       AST_APP_ARG(number);
16420    );
16421    int i, number, start = 0;
16422 
16423    if (ast_strlen_zero(data)) {
16424       ast_log(LOG_WARNING, "This function requires a header name.\n");
16425       return -1;
16426    }
16427 
16428    ast_channel_lock(chan);
16429    if (!IS_SIP_TECH(chan->tech)) {
16430       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
16431       ast_channel_unlock(chan);
16432       return -1;
16433    }
16434 
16435    AST_STANDARD_APP_ARGS(args, data);
16436    if (!args.number) {
16437       number = 1;
16438    } else {
16439       sscanf(args.number, "%30d", &number);
16440       if (number < 1)
16441          number = 1;
16442    }
16443 
16444    p = chan->tech_pvt;
16445 
16446    /* If there is no private structure, this channel is no longer alive */
16447    if (!p) {
16448       ast_channel_unlock(chan);
16449       return -1;
16450    }
16451 
16452    for (i = 0; i < number; i++)
16453       content = __get_header(&p->initreq, args.header, &start);
16454 
16455    if (ast_strlen_zero(content)) {
16456       ast_channel_unlock(chan);
16457       return -1;
16458    }
16459 
16460    ast_copy_string(buf, content, len);
16461    ast_channel_unlock(chan);
16462 
16463    return 0;
16464 }

static int function_sipchaninfo_read ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

${SIPCHANINFO()} Dialplan function - reads sip channel data

Definition at line 16621 of file chan_sip.c.

References ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_inet_ntoa(), ast_log(), chan, sip_pvt::from, IS_SIP_TECH, LOG_WARNING, sip_pvt::peername, sip_pvt::recv, sip_pvt::sa, t38properties::state, sip_pvt::t38, T38_DISABLED, ast_channel::tech, ast_channel::tech_pvt, sip_pvt::uri, and sip_pvt::useragent.

16622 {
16623    struct sip_pvt *p;
16624    static int deprecated = 0;
16625 
16626    *buf = 0;
16627    
16628    if (!data) {
16629       ast_log(LOG_WARNING, "This function requires a parameter name.\n");
16630       return -1;
16631    }
16632 
16633    ast_channel_lock(chan);
16634    if (!IS_SIP_TECH(chan->tech)) {
16635       ast_log(LOG_WARNING, "This function can only be used on SIP channels.\n");
16636       ast_channel_unlock(chan);
16637       return -1;
16638    }
16639 
16640    if (deprecated++ % 20 == 0) {
16641       /* Deprecated in 1.6.1 */
16642       ast_log(LOG_WARNING, "SIPCHANINFO() is deprecated.  Please transition to using CHANNEL().\n");
16643    }
16644 
16645    p = chan->tech_pvt;
16646 
16647    /* If there is no private structure, this channel is no longer alive */
16648    if (!p) {
16649       ast_channel_unlock(chan);
16650       return -1;
16651    }
16652 
16653    if (!strcasecmp(data, "peerip")) {
16654       ast_copy_string(buf, p->sa.sin_addr.s_addr ? ast_inet_ntoa(p->sa.sin_addr) : "", len);
16655    } else  if (!strcasecmp(data, "recvip")) {
16656       ast_copy_string(buf, p->recv.sin_addr.s_addr ? ast_inet_ntoa(p->recv.sin_addr) : "", len);
16657    } else  if (!strcasecmp(data, "from")) {
16658       ast_copy_string(buf, p->from, len);
16659    } else  if (!strcasecmp(data, "uri")) {
16660       ast_copy_string(buf, p->uri, len);
16661    } else  if (!strcasecmp(data, "useragent")) {
16662       ast_copy_string(buf, p->useragent, len);
16663    } else  if (!strcasecmp(data, "peername")) {
16664       ast_copy_string(buf, p->peername, len);
16665    } else if (!strcasecmp(data, "t38passthrough")) {
16666       if (p->t38.state == T38_DISABLED) {
16667          ast_copy_string(buf, "0", len);
16668       } else { /* T38 is offered or enabled in this call */
16669          ast_copy_string(buf, "1", len);
16670       }
16671    } else {
16672       ast_channel_unlock(chan);
16673       return -1;
16674    }
16675    ast_channel_unlock(chan);
16676 
16677    return 0;
16678 }

static int function_sippeer ( struct ast_channel chan,
const char *  cmd,
char *  data,
char *  buf,
size_t  len 
) [static]

${SIPPEER()} Dialplan function - reads peer data

Todo:
Will be deprecated after 1.4

Definition at line 16502 of file chan_sip.c.

References sip_peer::accountcode, sip_peer::addr, ast_codec_pref_index(), ast_copy_string(), ast_getformatname(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_log(), ast_print_group(), ast_str_alloca, sip_peer::busy_level, sip_peer::call_limit, sip_peer::callgroup, sip_peer::capability, chanvar, sip_peer::chanvars, sip_peer::cid_name, sip_peer::cid_num, sip_peer::context, sip_peer::expire, FALSE, find_peer(), FINDPEERS, sip_peer::host_dynamic, sip_peer::inUse, sip_peer::language, LOG_WARNING, ast_variable::name, ast_variable::next, peer_mailboxes_to_str(), peer_status(), sip_peer::pickupgroup, sip_peer::prefs, sip_peer::regexten, ast_str::str, strsep(), TRUE, unref_peer(), sip_peer::useragent, and ast_variable::value.

16503 {
16504    struct sip_peer *peer;
16505    char *colname;
16506 
16507    if ((colname = strchr(data, ':'))) {   /*! \todo Will be deprecated after 1.4 */
16508       static int deprecation_warning = 0;
16509       *colname++ = '\0';
16510       if (deprecation_warning++ % 10 == 0)
16511          ast_log(LOG_WARNING, "SIPPEER(): usage of ':' to separate arguments is deprecated.  Please use ',' instead.\n");
16512    } else if ((colname = strchr(data, ',')))
16513       *colname++ = '\0';
16514    else
16515       colname = "ip";
16516 
16517    if (!(peer = find_peer(data, NULL, TRUE, FINDPEERS, FALSE, 0)))
16518       return -1;
16519 
16520    if (!strcasecmp(colname, "ip")) {
16521       ast_copy_string(buf, peer->addr.sin_addr.s_addr ? ast_inet_ntoa(peer->addr.sin_addr) : "", len);
16522    } else  if (!strcasecmp(colname, "port")) {
16523       snprintf(buf, len, "%d", ntohs(peer->addr.sin_port));
16524    } else  if (!strcasecmp(colname, "status")) {
16525       peer_status(peer, buf, len);
16526    } else  if (!strcasecmp(colname, "language")) {
16527       ast_copy_string(buf, peer->language, len);
16528    } else  if (!strcasecmp(colname, "regexten")) {
16529       ast_copy_string(buf, peer->regexten, len);
16530    } else  if (!strcasecmp(colname, "limit")) {
16531       snprintf(buf, len, "%d", peer->call_limit);
16532    } else  if (!strcasecmp(colname, "busylevel")) {
16533       snprintf(buf, len, "%d", peer->busy_level);
16534    } else  if (!strcasecmp(colname, "curcalls")) {
16535       snprintf(buf, len, "%d", peer->inUse);
16536    } else  if (!strcasecmp(colname, "accountcode")) {
16537       ast_copy_string(buf, peer->accountcode, len);
16538    } else  if (!strcasecmp(colname, "callgroup")) {
16539       ast_print_group(buf, len, peer->callgroup);
16540    } else  if (!strcasecmp(colname, "pickupgroup")) {
16541       ast_print_group(buf, len, peer->pickupgroup);
16542    } else  if (!strcasecmp(colname, "useragent")) {
16543       ast_copy_string(buf, peer->useragent, len);
16544    } else  if (!strcasecmp(colname, "mailbox")) {
16545       struct ast_str *mailbox_str = ast_str_alloca(512);
16546       peer_mailboxes_to_str(&mailbox_str, peer);
16547       ast_copy_string(buf, mailbox_str->str, len);
16548    } else  if (!strcasecmp(colname, "context")) {
16549       ast_copy_string(buf, peer->context, len);
16550    } else  if (!strcasecmp(colname, "expire")) {
16551       snprintf(buf, len, "%d", peer->expire);
16552    } else  if (!strcasecmp(colname, "dynamic")) {
16553       ast_copy_string(buf, peer->host_dynamic ? "yes" : "no", len);
16554    } else  if (!strcasecmp(colname, "callerid_name")) {
16555       ast_copy_string(buf, peer->cid_name, len);
16556    } else  if (!strcasecmp(colname, "callerid_num")) {
16557       ast_copy_string(buf, peer->cid_num, len);
16558    } else  if (!strcasecmp(colname, "codecs")) {
16559       ast_getformatname_multiple(buf, len -1, peer->capability);
16560    } else  if (!strncasecmp(colname, "chanvar[", 8)) {
16561       char *chanvar=colname + 8;
16562       struct ast_variable *v;
16563    
16564       chanvar = strsep(&chanvar, "]");
16565       for (v = peer->chanvars ; v ; v = v->next)
16566          if (!strcasecmp(v->name, chanvar))
16567             ast_copy_string(buf, v->value, len);
16568    } else  if (!strncasecmp(colname, "codec[", 6)) {
16569       char *codecnum;
16570       int codec = 0;
16571       
16572       codecnum = colname + 6; /* move past the '[' */
16573       codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */
16574       if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
16575          ast_copy_string(buf, ast_getformatname(codec), len);
16576       } else {
16577          buf[0] = '\0';
16578       }
16579    } else {
16580       buf[0] = '\0';
16581    }
16582 
16583    unref_peer(peer, "unref_peer from function_sippeer, just before return");
16584 
16585    return 0;
16586 }

static char * generate_random_string ( char *  buf,
size_t  size 
) [static]

Generate 32 byte random string for callid's etc.

Definition at line 6674 of file chan_sip.c.

References ast_random().

Referenced by build_callid_pvt(), and build_callid_registry().

06675 {
06676    long val[4];
06677    int x;
06678 
06679    for (x=0; x<4; x++)
06680       val[x] = ast_random();
06681    snprintf(buf, size, "%08lx%08lx%08lx%08lx", val[0], val[1], val[2], val[3]);
06682 
06683    return buf;
06684 }

static int get_also_info ( struct sip_pvt p,
struct sip_request oreq 
) [static]

Call transfer support (old way, deprecated by the IETF)--.

Definition at line 12874 of file chan_sip.c.

References ast_canmatch_extension(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), ast_string_field_set, ast_strlen_zero(), ast_uri_decode(), ast_verbose, context, sip_pvt::context, dialog_unref(), get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, ast_channel::macrocontext, sip_pvt::owner, pbx_builtin_getvar_helper(), sip_pvt::refer, sip_refer::refer_call, sip_refer::refer_contact, sip_refer::refer_to, sip_refer::refer_to_domain, sip_refer::referred_by, S_OR, sip_debug_test_pvt(), and sip_refer_allocate().

Referenced by handle_request_bye().

12875 {
12876    char tmp[256] = "", *c, *a;
12877    struct sip_request *req = oreq ? oreq : &p->initreq;
12878    struct sip_refer *referdata = NULL;
12879    const char *transfer_context = NULL;
12880    
12881    if (!p->refer && !sip_refer_allocate(p))
12882       return -1;
12883 
12884    referdata = p->refer;
12885 
12886    ast_copy_string(tmp, get_header(req, "Also"), sizeof(tmp));
12887    c = get_in_brackets(tmp);
12888 
12889    if (pedanticsipchecking)
12890       ast_uri_decode(c);
12891 
12892    if (!strncasecmp(c, "sip:", 4)) {
12893       c += 4;
12894    } else if (!strncasecmp(c, "sips:", 5)) {
12895       c += 5;
12896    } else {
12897       ast_log(LOG_WARNING, "Huh?  Not a SIP header in Also: transfer (%s)?\n", c);
12898       return -1;
12899    }
12900 
12901    if ((a = strchr(c, ';')))  /* Remove arguments */
12902       *a = '\0';
12903    
12904    if ((a = strchr(c, '@'))) {   /* Separate Domain */
12905       *a++ = '\0';
12906       ast_copy_string(referdata->refer_to_domain, a, sizeof(referdata->refer_to_domain));
12907    }
12908    
12909    if (sip_debug_test_pvt(p))
12910       ast_verbose("Looking for %s in %s\n", c, p->context);
12911 
12912    if (p->owner)  /* Mimic behaviour in res_features.c */
12913       transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT");
12914 
12915    /* By default, use the context in the channel sending the REFER */
12916    if (ast_strlen_zero(transfer_context)) {
12917       transfer_context = S_OR(p->owner->macrocontext,
12918                S_OR(p->context, default_context));
12919    }
12920    if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) {
12921       /* This is a blind transfer */
12922       ast_debug(1, "SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context);
12923       ast_copy_string(referdata->refer_to, c, sizeof(referdata->refer_to));
12924       ast_copy_string(referdata->referred_by, "", sizeof(referdata->referred_by));
12925       ast_copy_string(referdata->refer_contact, "", sizeof(referdata->refer_contact));
12926       referdata->refer_call = dialog_unref(referdata->refer_call, "unreffing referdata->refer_call");
12927       /* Set new context */
12928       ast_string_field_set(p, context, transfer_context);
12929       return 0;
12930    } else if (ast_canmatch_extension(NULL, p->context, c, 1, NULL)) {
12931       return 1;
12932    }
12933 
12934    return -1;
12935 }

static char* get_body ( struct sip_request req,
char *  name 
) [static]

Get a specific line from the message body.

Definition at line 6441 of file chan_sip.c.

References get_body_by_line(), sip_request::lines, and REQ_OFFSET_TO_STR.

Referenced by handle_request_info().

06442 {
06443    int x;
06444    int len = strlen(name);
06445    char *r;
06446 
06447    for (x = 0; x < req->lines; x++) {
06448       r = get_body_by_line(REQ_OFFSET_TO_STR(req, line[x]), name, len);
06449       if (r[0] != '\0')
06450          return r;
06451    }
06452 
06453    return "";
06454 }

static char* get_body_by_line ( const char *  line,
const char *  name,
int  nameLen 
) [static]

Reads one line of SIP message body.

Definition at line 6386 of file chan_sip.c.

References ast_skip_blanks().

Referenced by get_body(), and get_sdp_iterate().

06387 {
06388    if (!strncasecmp(line, name, nameLen) && line[nameLen] == '=')
06389       return ast_skip_blanks(line + nameLen + 1);
06390 
06391    return "";
06392 }

static int get_cached_mwi ( struct sip_peer peer,
int *  new,
int *  old 
) [static]

Get cached MWI info.

Return values:
0 At least one message is waiting
1 no messages waiting

Definition at line 21342 of file chan_sip.c.

References ast_event_destroy(), ast_event_get_cached(), ast_event_get_ie_uint(), AST_EVENT_IE_CONTEXT, AST_EVENT_IE_END, AST_EVENT_IE_MAILBOX, AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_STR, AST_EVENT_MWI, AST_LIST_TRAVERSE, sip_mailbox::entry, mailbox, sip_peer::mailboxes, and S_OR.

Referenced by sip_send_mwi_to_peer().

21343 {
21344    struct sip_mailbox *mailbox;
21345 
21346    AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
21347       struct ast_event *event;
21348       event = ast_event_get_cached(AST_EVENT_MWI,
21349          AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox->mailbox,
21350          AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, S_OR(mailbox->context, "default"),
21351          AST_EVENT_IE_END);
21352       if (!event)
21353          continue;
21354       *new += ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
21355       *old += ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
21356       ast_event_destroy(event);
21357    }
21358 
21359    return (*new || *old) ? 0 : 1;
21360 }

static char * get_calleridname ( const char *  input,
char *  output,
size_t  outputsize 
) [static]

Get caller id name from SIP headers.

Definition at line 13040 of file chan_sip.c.

References ast_copy_string(), and ast_skip_blanks().

Referenced by check_user_full().

13041 {
13042    const char *end = strchr(input, '<');  /* first_bracket */
13043    const char *tmp = strchr(input, '"');  /* first quote */
13044    int bytes = 0;
13045    int maxbytes = outputsize - 1;
13046 
13047    if (!end || end == input)  /* we require a part in brackets */
13048       return NULL;
13049 
13050    end--; /* move just before "<" */
13051 
13052    if (tmp && tmp <= end) {
13053       /* The quote (tmp) precedes the bracket (end+1).
13054        * Find the matching quote and return the content.
13055        */
13056       end = strchr(tmp+1, '"');
13057       if (!end)
13058          return NULL;
13059       bytes = (int) (end - tmp);
13060       /* protect the output buffer */
13061       if (bytes > maxbytes)
13062          bytes = maxbytes;
13063       ast_copy_string(output, tmp + 1, bytes);
13064    } else {
13065       /* No quoted string, or it is inside brackets. */
13066       /* clear the empty characters in the begining*/
13067       input = ast_skip_blanks(input);
13068       /* clear the empty characters in the end */
13069       while(*end && *end < 33 && end > input)
13070          end--;
13071       if (end >= input) {
13072          bytes = (int) (end - input) + 2;
13073          /* protect the output buffer */
13074          if (bytes > maxbytes)
13075             bytes = maxbytes;
13076          ast_copy_string(output, input, bytes);
13077       } else
13078          return NULL;
13079    }
13080    return output;
13081 }

static int get_destination ( struct sip_pvt p,
struct sip_request oreq 
) [static]

Find out who the call is for. We use the request uri as a destination. This code assumes authentication has been done, so that the device (peer/user) context is already set.

Returns:
0 on success (found a matching extension), 1 for pickup extension or overlap dialling support (if we support it), -1 on error.

Definition at line 12483 of file chan_sip.c.

References ast_canmatch_extension(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_get_hint(), AST_LIST_EMPTY, ast_log(), AST_MAX_EXTENSION, ast_pickup_ext(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), ast_verbose, check_sip_domain(), sip_pvt::cid_num, sip_pvt::context, context, sip_pvt::domain, exten, sip_pvt::exten, sip_pvt::flags, get_header(), get_in_brackets(), global_flags, sip_pvt::initreq, LOG_WARNING, sip_request::method, REQ_OFFSET_TO_STR, sip_request::rlPart2, S_OR, sip_debug_test_pvt(), SIP_INVITE, sip_methods, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_HAVEPEERCONTEXT, SIP_REFER, SIP_SUBSCRIBE, strsep(), and sip_pvt::subscribecontext.

Referenced by handle_request_invite(), handle_request_options(), and handle_request_subscribe().

12484 {
12485    char tmp[256] = "", *uri, *a;
12486    char tmpf[256] = "", *from = NULL;
12487    struct sip_request *req;
12488    char *colon;
12489    char *decoded_uri;
12490    
12491    req = oreq;
12492    if (!req)
12493       req = &p->initreq;
12494 
12495    /* Find the request URI */
12496    if (req->rlPart2)
12497       ast_copy_string(tmp, REQ_OFFSET_TO_STR(req, rlPart2), sizeof(tmp));
12498    
12499    if (pedanticsipchecking)
12500       ast_uri_decode(tmp);
12501 
12502    uri = get_in_brackets(tmp);
12503    
12504    if (!strncasecmp(uri, "sip:", 4)) {
12505       uri += 4;
12506    } else if (!strncasecmp(uri, "sips:", 5)) {
12507       uri += 5;
12508    } else {
12509       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", uri);
12510       return -1;
12511    }
12512 
12513    /* Now find the From: caller ID and name */
12514    /* XXX Why is this done in get_destination? Isn't it already done?
12515       Needs to be checked 
12516         */
12517    ast_copy_string(tmpf, get_header(req, "From"), sizeof(tmpf));
12518    if (!ast_strlen_zero(tmpf)) {
12519       if (pedanticsipchecking)
12520          ast_uri_decode(tmpf);
12521       from = get_in_brackets(tmpf);
12522    } 
12523    
12524    if (!ast_strlen_zero(from)) {
12525       if (!strncasecmp(from, "sip:", 4)) {
12526          from += 4;
12527       } else if (!strncasecmp(from, "sips:", 5)) {
12528          from += 5;
12529       } else {
12530          ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", from);
12531          return -1;
12532       }
12533       if ((a = strchr(from, '@')))
12534          *a++ = '\0';
12535       else
12536          a = from;   /* just a domain */
12537       from = strsep(&from, ";"); /* Remove userinfo options */
12538       a = strsep(&a, ";");    /* Remove URI options */
12539       ast_string_field_set(p, fromdomain, a);
12540    }
12541 
12542    /* Skip any options and find the domain */
12543 
12544    /* Get the target domain */
12545    if ((a = strchr(uri, '@'))) {
12546       *a++ = '\0';
12547    } else { /* No username part */
12548       a = uri;
12549       uri = "s";  /* Set extension to "s" */
12550    }
12551    colon = strchr(a, ':'); /* Remove :port */
12552    if (colon)
12553       *colon = '\0';
12554 
12555    uri = strsep(&uri, ";");   /* Remove userinfo options */
12556    a = strsep(&a, ";");    /* Remove URI options */
12557 
12558    ast_string_field_set(p, domain, a);
12559 
12560    if (!AST_LIST_EMPTY(&domain_list)) {
12561       char domain_context[AST_MAX_EXTENSION];
12562 
12563       domain_context[0] = '\0';
12564       if (!check_sip_domain(p->domain, domain_context, sizeof(domain_context))) {
12565          if (!allow_external_domains && (req->method == SIP_INVITE || req->method == SIP_REFER)) {
12566             ast_debug(1, "Got SIP %s to non-local domain '%s'; refusing request.\n", sip_methods[req->method].text, p->domain);
12567             return -2;
12568          }
12569       }
12570       /* If we don't have a peer (i.e. we're a guest call),
12571        * overwrite the original context */
12572       if (!ast_test_flag(&p->flags[1], SIP_PAGE2_HAVEPEERCONTEXT) && !ast_strlen_zero(domain_context))
12573          ast_string_field_set(p, context, domain_context);
12574    }
12575 
12576    /* If the request coming in is a subscription and subscribecontext has been specified use it */
12577    if (req->method == SIP_SUBSCRIBE && !ast_strlen_zero(p->subscribecontext))
12578       ast_string_field_set(p, context, p->subscribecontext);
12579 
12580    if (sip_debug_test_pvt(p))
12581       ast_verbose("Looking for %s in %s (domain %s)\n", uri, p->context, p->domain);
12582 
12583    /* If this is a subscription we actually just need to see if a hint exists for the extension */
12584    if (req->method == SIP_SUBSCRIBE) {
12585       char hint[AST_MAX_EXTENSION];
12586       return (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten) ? 0 : -1);
12587    } else {
12588       decoded_uri = ast_strdupa(uri);
12589       ast_uri_decode(decoded_uri);
12590       /* Check the dialplan for the username part of the request URI,
12591          the domain will be stored in the SIPDOMAIN variable
12592          Since extensions.conf can have unescaped characters, try matching a decoded
12593          uri in addition to the non-decoded uri
12594          Return 0 if we have a matching extension */
12595       if (ast_exists_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from)) || ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from)) ||
12596           !strcmp(decoded_uri, ast_pickup_ext())) {
12597          if (!oreq)
12598             ast_string_field_set(p, exten, decoded_uri);
12599          return 0;
12600       } 
12601    }
12602 
12603    /* Return 1 for pickup extension or overlap dialling support (if we support it) */
12604    if((ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP) && 
12605        ast_canmatch_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))) ||
12606        !strncmp(decoded_uri, ast_pickup_ext(), strlen(decoded_uri))) {
12607       return 1;
12608    }
12609    
12610    return -1;
12611 }

static const char * get_header ( const struct sip_request req,
const char *  name 
) [static]

Get header from SIP request.

Returns:
Always return something, so don't check for NULL because it won't happen :-)

Definition at line 6534 of file chan_sip.c.

References __get_header().

06535 {
06536    int start = 0;
06537    return __get_header(req, name, &start);
06538 }

static char * get_in_brackets ( char *  tmp  )  [static]

Pick out text in brackets from character string.

Returns:
pointer to terminated stripped string
Parameters:
tmp input string that will be modified Examples:
	"foo" <bar>	valid input, returns bar
	foo		returns the whole string
	< "foo ... >	returns the string between brackets
	< "foo...	bogus (missing closing bracket), returns the whole string
			XXX maybe should still skip the opening bracket

Definition at line 3956 of file chan_sip.c.

References ast_log(), find_closing_quote(), LOG_WARNING, and parse().

Referenced by check_user_full(), extract_uri(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), parse_moved_contact(), parse_ok_contact(), parse_register_contact(), register_verify(), reqprep(), transmit_refer(), and transmit_state_notify().

03957 {
03958    const char *parse = tmp;
03959    char *first_bracket;
03960 
03961    /*
03962     * Skip any quoted text until we find the part in brackets.
03963    * On any error give up and return the full string.
03964    */
03965    while ( (first_bracket = strchr(parse, '<')) ) {
03966       char *first_quote = strchr(parse, '"');
03967 
03968       if (!first_quote || first_quote > first_bracket)
03969          break; /* no need to look at quoted part */
03970       /* the bracket is within quotes, so ignore it */
03971       parse = find_closing_quote(first_quote + 1, NULL);
03972       if (!*parse) { /* not found, return full string ? */
03973          /* XXX or be robust and return in-bracket part ? */
03974          ast_log(LOG_WARNING, "No closing quote found in '%s'\n", tmp);
03975          break;
03976       }
03977       parse++;
03978    }
03979    if (first_bracket) {
03980       char *second_bracket = strchr(first_bracket + 1, '>');
03981       if (second_bracket) {
03982          *second_bracket = '\0';
03983          tmp = first_bracket + 1;
03984       } else {
03985          ast_log(LOG_WARNING, "No closing bracket found in '%s'\n", tmp);
03986       }
03987    }
03988    
03989    return tmp;
03990 }

static struct ast_variable * get_insecure_variable_from_config ( struct ast_config config  )  [static]

Definition at line 4319 of file chan_sip.c.

References ast_category_browse(), ast_category_root(), ast_test_flag, ast_variable_retrieve(), ast_flags::flags, set_insecure_flags(), SIP_INSECURE_PORT, and var.

04320 {
04321    struct ast_variable *var = NULL;
04322    struct ast_flags flags = {0};
04323    char *cat = NULL;
04324    const char *insecure;
04325    while ((cat = ast_category_browse(cfg, cat))) {
04326       insecure = ast_variable_retrieve(cfg, cat, "insecure");
04327       set_insecure_flags(&flags, insecure, -1);
04328       if (ast_test_flag(&flags, SIP_INSECURE_PORT)) {
04329          var = ast_category_root(cfg, cat);
04330          break;
04331       }
04332    }
04333    return var;
04334 }

static int get_ip_and_port_from_sdp ( struct sip_request req,
const enum media_type  media,
struct sockaddr_in *  sin 
) [static]

Definition at line 7397 of file chan_sip.c.

References ast_gethostbyname(), ast_log(), ast_strlen_zero(), get_sdp_iterate(), hp, LOG_WARNING, SDP_AUDIO, sip_request::sdp_start, and SDP_VIDEO.

Referenced by handle_request_invite().

07398 {
07399    const char *m;
07400    const char *c;
07401    int miterator = req->sdp_start;
07402    int citerator = req->sdp_start;
07403    int x = 0;
07404    int numberofports;
07405    int len;
07406    char host[258] = ""; /*Initialize to empty so we will know if we have any input */
07407    struct ast_hostent audiohp;
07408    struct hostent *hp;
07409 
07410    c = get_sdp_iterate(&citerator, req, "c");
07411    if (sscanf(c, "IN IP4 %256s", host) != 1) {
07412       ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
07413       /* Continue since there may be a valid host in a c= line specific to the audio stream */
07414    }
07415    /* We only want the m and c lines for audio */
07416    for (m = get_sdp_iterate(&miterator, req, "m"); !ast_strlen_zero(m); m = get_sdp_iterate(&miterator, req, "m")) {
07417       if ((media == SDP_AUDIO && ((sscanf(m, "audio %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
07418           (sscanf(m, "audio %30u RTP/AVP %n", &x, &len) == 1 && len > 0))) ||
07419          (media == SDP_VIDEO && ((sscanf(m, "video %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
07420           (sscanf(m, "video %30u RTP/AVP %n", &x, &len) == 1 && len > 0)))) {
07421          /* See if there's a c= line for this media stream.
07422           * XXX There is no guarantee that we'll be grabbing the c= line for this
07423           * particular media stream here. However, this is the same logic used in process_sdp.
07424           */
07425          c = get_sdp_iterate(&citerator, req, "c");
07426          if (!ast_strlen_zero(c)) {
07427             sscanf(c, "IN IP4 %256s", host);
07428          }
07429          break;
07430       }
07431    }
07432 
07433    if (ast_strlen_zero(host) || x == 0) {
07434       ast_log(LOG_WARNING, "Failed to read an alternate host or port in SDP. Expect %s problems\n", media == SDP_AUDIO ? "audio" : "video");
07435       return -1;
07436    }
07437 
07438    hp = ast_gethostbyname(host, &audiohp);
07439    if (!hp) {
07440       ast_log(LOG_WARNING, "Could not look up IP address of alternate hostname. Expect %s problems\n", media == SDP_AUDIO? "audio" : "video");
07441       return -1;
07442    }
07443 
07444    memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
07445    sin->sin_port = htons(x);
07446    return 0;
07447 }

static int get_msg_text ( char *  buf,
int  len,
struct sip_request req,
int  addnewline 
) [static]

Get text out of a SIP MESSAGE packet.

Definition at line 13433 of file chan_sip.c.

References sip_request::lines, and REQ_OFFSET_TO_STR.

Referenced by handle_request_info(), handle_request_notify(), and receive_message().

13434 {
13435    int x;
13436    int y;
13437 
13438    buf[0] = '\0';
13439    /*XXX isn't strlen(buf) going to always be 0? */
13440    y = len - strlen(buf) - 5;
13441    if (y < 0)
13442       y = 0;
13443    for (x = 0; x < req->lines; x++) {
13444       char *line = REQ_OFFSET_TO_STR(req, line[x]);
13445       strncat(buf, line, y); /* safe */
13446       y -= strlen(line) + 1;
13447       if (y < 0)
13448          y = 0;
13449       if (y != 0 && addnewline)
13450          strcat(buf, "\n"); /* safe */
13451    }
13452    return 0;
13453 }

static const char * get_name_from_variable ( struct ast_variable var,
const char *  newpeername 
) [static]

Definition at line 4336 of file chan_sip.c.

References ast_variable::name, ast_variable::next, ast_variable::value, and var.

04337 {
04338    struct ast_variable *tmp;
04339    for (tmp = var; tmp; tmp = tmp->next) {
04340       if (!newpeername && !strcasecmp(tmp->name, "name"))
04341          newpeername = tmp->value;
04342    }
04343    return newpeername;
04344 }

static void get_our_media_address ( struct sip_pvt p,
int  needvideo,
struct sockaddr_in *  sin,
struct sockaddr_in *  vsin,
struct sockaddr_in *  tsin,
struct sockaddr_in *  dest,
struct sockaddr_in *  vdest 
) [static]

Set all IP media addresses for this call.

Note:
called from add_sdp()

Definition at line 9330 of file chan_sip.c.

References ast_rtp_get_us(), sip_pvt::ourip, sip_pvt::redirip, sip_pvt::rtp, sip_pvt::trtp, sip_pvt::vredirip, and sip_pvt::vrtp.

Referenced by add_sdp().

09333 {
09334    /* First, get our address */
09335    ast_rtp_get_us(p->rtp, sin);
09336    if (p->vrtp)
09337       ast_rtp_get_us(p->vrtp, vsin);
09338    if (p->trtp)
09339       ast_rtp_get_us(p->trtp, tsin);
09340 
09341    /* Now, try to figure out where we want them to send data */
09342    /* Is this a re-invite to move the media out, then use the original offer from caller  */
09343    if (p->redirip.sin_addr.s_addr) {   /* If we have a redirection IP, use it */
09344       dest->sin_port = p->redirip.sin_port;
09345       dest->sin_addr = p->redirip.sin_addr;
09346    } else {
09347       dest->sin_addr = p->ourip.sin_addr;
09348       dest->sin_port = sin->sin_port;
09349    }
09350    if (needvideo) {
09351       /* Determine video destination */
09352       if (p->vredirip.sin_addr.s_addr) {
09353          vdest->sin_addr = p->vredirip.sin_addr;
09354          vdest->sin_port = p->vredirip.sin_port;
09355       } else {
09356          vdest->sin_addr = p->ourip.sin_addr;
09357          vdest->sin_port = vsin->sin_port;
09358       }
09359    }
09360 
09361 }

static int get_rdnis ( struct sip_pvt p,
struct sip_request oreq 
) [static]

Get referring dnis.

Definition at line 12416 of file chan_sip.c.

References ast_copy_string(), ast_log(), ast_string_field_set, ast_strip_quoted(), ast_strlen_zero(), ast_verbose, exten, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_debug_test_pvt(), sip_set_redirstr(), strcasestr(), and strsep().

Referenced by handle_request_invite().

12417 {
12418    char tmp[256], *exten, *rexten, *rdomain;
12419    char *params, *reason = NULL;
12420    struct sip_request *req;
12421    
12422    req = oreq ? oreq : &p->initreq;
12423 
12424    ast_copy_string(tmp, get_header(req, "Diversion"), sizeof(tmp));
12425    if (ast_strlen_zero(tmp))
12426       return 0;
12427 
12428    params = strchr(tmp, ';');
12429 
12430    exten = get_in_brackets(tmp);
12431    if (!strncasecmp(exten, "sip:", 4)) {
12432       exten += 4;
12433    } else if (!strncasecmp(exten, "sips:", 5)) {
12434       exten += 5;
12435    } else {
12436       ast_log(LOG_WARNING, "Huh?  Not an RDNIS SIP header (%s)?\n", exten);
12437       return -1;
12438    }
12439 
12440    /* Get diversion-reason param if present */
12441    if (params) {
12442       *params = '\0';   /* Cut off parameters  */
12443       params++;
12444       while (*params == ';' || *params == ' ')
12445          params++;
12446       /* Check if we have a reason parameter */
12447       if ((reason = strcasestr(params, "reason="))) {
12448          reason+=7;
12449          /* Remove enclosing double-quotes */
12450          if (*reason == '"') 
12451             ast_strip_quoted(reason, "\"", "\"");
12452          if (!ast_strlen_zero(reason)) {
12453             sip_set_redirstr(p, reason);
12454             if (p->owner) {
12455                pbx_builtin_setvar_helper(p->owner, "__PRIREDIRECTREASON", p->redircause);
12456                pbx_builtin_setvar_helper(p->owner, "__SIPREDIRECTREASON", reason);
12457             }
12458          }
12459       }
12460    }
12461 
12462    rdomain = exten;
12463    rexten = strsep(&rdomain, "@");  /* trim anything after @ */
12464    if (p->owner) 
12465       pbx_builtin_setvar_helper(p->owner, "__SIPRDNISDOMAIN", rdomain);
12466 
12467    if (sip_debug_test_pvt(p))
12468       ast_verbose("RDNIS for this call is is %s (reason %s)\n", exten, reason ? reason : "");
12469 
12470    ast_string_field_set(p, rdnis, rexten);
12471 
12472    return 0;
12473 }

static int get_refer_info ( struct sip_pvt transferer,
struct sip_request outgoing_req 
) [static]

Call transfer support (the REFER method) Extracts Refer headers into pvt dialog structure.

Definition at line 12698 of file chan_sip.c.

References ast_bridged_channel(), ast_copy_string(), ast_debug, ast_exists_extension(), ast_log(), ast_strdupa, ast_strlen_zero(), ast_uri_decode(), ast_verbose, sip_refer::attendedtransfer, sip_pvt::context, get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, ast_channel::macrocontext, sip_pvt::owner, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), sip_pvt::refer, sip_refer::refer_to, sip_refer::refer_to_context, sip_refer::refer_to_domain, sip_refer::refer_to_urioption, sip_refer::referred_by, sip_refer::referred_by_name, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, S_OR, sip_debug_test_pvt(), and strcasestr().

Referenced by handle_request_refer().

12699 {
12700 
12701    const char *p_referred_by = NULL;
12702    char *h_refer_to = NULL; 
12703    char *h_referred_by = NULL;
12704    char *refer_to;
12705    const char *p_refer_to;
12706    char *referred_by_uri = NULL;
12707    char *ptr;
12708    struct sip_request *req = NULL;
12709    const char *transfer_context = NULL;
12710    struct sip_refer *referdata;
12711 
12712 
12713    req = outgoing_req;
12714    referdata = transferer->refer;
12715 
12716    if (!req)
12717       req = &transferer->initreq;
12718 
12719    p_refer_to = get_header(req, "Refer-To");
12720    if (ast_strlen_zero(p_refer_to)) {
12721       ast_log(LOG_WARNING, "Refer-To Header missing. Skipping transfer.\n");
12722       return -2;  /* Syntax error */
12723    }
12724    h_refer_to = ast_strdupa(p_refer_to);
12725    refer_to = get_in_brackets(h_refer_to);
12726    if (pedanticsipchecking)
12727       ast_uri_decode(refer_to);
12728 
12729    if (!strncasecmp(refer_to, "sip:", 4)) {
12730       refer_to += 4;       /* Skip sip: */
12731    } else if (!strncasecmp(refer_to, "sips:", 5)) {
12732       refer_to += 5;
12733    } else {
12734       ast_log(LOG_WARNING, "Can't transfer to non-sip: URI.  (Refer-to: %s)?\n", refer_to);
12735       return -3;
12736    }
12737 
12738    /* Get referred by header if it exists */
12739    p_referred_by = get_header(req, "Referred-By");
12740 
12741    /* Give useful transfer information to the dialplan */
12742    if (transferer->owner) {
12743       struct ast_channel *peer = ast_bridged_channel(transferer->owner);
12744       if (peer) {
12745          pbx_builtin_setvar_helper(peer, "SIPREFERRINGCONTEXT", transferer->context);
12746          pbx_builtin_setvar_helper(peer, "SIPREFERREDBYHDR", p_referred_by);
12747       }
12748    }
12749 
12750    if (!ast_strlen_zero(p_referred_by)) {
12751       char *lessthan;
12752       h_referred_by = ast_strdupa(p_referred_by);
12753       if (pedanticsipchecking)
12754          ast_uri_decode(h_referred_by);
12755 
12756       /* Store referrer's caller ID name */
12757       ast_copy_string(referdata->referred_by_name, h_referred_by, sizeof(referdata->referred_by_name));
12758       if ((lessthan = strchr(referdata->referred_by_name, '<'))) {
12759          *(lessthan - 1) = '\0'; /* Space */
12760       }
12761 
12762       referred_by_uri = get_in_brackets(h_referred_by);
12763       if (!strncasecmp(referred_by_uri, "sip:", 4)) {
12764          referred_by_uri += 4;      /* Skip sip: */
12765       } else if (!strncasecmp(referred_by_uri, "sips:", 5)) {
12766          referred_by_uri += 5;      /* Skip sips: */
12767       } else {
12768          ast_log(LOG_WARNING, "Huh?  Not a sip: header (Referred-by: %s). Skipping.\n", referred_by_uri);
12769          referred_by_uri = NULL;
12770       }
12771    }
12772 
12773    /* Check for arguments in the refer_to header */
12774    if ((ptr = strcasestr(refer_to, "replaces="))) {
12775       char *to = NULL, *from = NULL;
12776       
12777       /* This is an attended transfer */
12778       referdata->attendedtransfer = 1;
12779       ast_copy_string(referdata->replaces_callid, ptr+9, sizeof(referdata->replaces_callid));
12780       ast_uri_decode(referdata->replaces_callid);
12781       if ((ptr = strchr(referdata->replaces_callid, ';')))  /* Find options */ {
12782          *ptr++ = '\0';
12783       }
12784       
12785       if (ptr) {
12786          /* Find the different tags before we destroy the string */
12787          to = strcasestr(ptr, "to-tag=");
12788          from = strcasestr(ptr, "from-tag=");
12789       }
12790       
12791       /* Grab the to header */
12792       if (to) {
12793          ptr = to + 7;
12794          if ((to = strchr(ptr, '&')))
12795             *to = '\0';
12796          if ((to = strchr(ptr, ';')))
12797             *to = '\0';
12798          ast_copy_string(referdata->replaces_callid_totag, ptr, sizeof(referdata->replaces_callid_totag));
12799       }
12800       
12801       if (from) {
12802          ptr = from + 9;
12803          if ((to = strchr(ptr, '&')))
12804             *to = '\0';
12805          if ((to = strchr(ptr, ';')))
12806             *to = '\0';
12807          ast_copy_string(referdata->replaces_callid_fromtag, ptr, sizeof(referdata->replaces_callid_fromtag));
12808       }
12809       
12810       if (!pedanticsipchecking)
12811          ast_debug(2, "Attended transfer: Will use Replace-Call-ID : %s (No check of from/to tags)\n", referdata->replaces_callid );
12812       else
12813          ast_debug(2, "Attended transfer: Will use Replace-Call-ID : %s F-tag: %s T-tag: %s\n", referdata->replaces_callid, referdata->replaces_callid_fromtag ? referdata->replaces_callid_fromtag : "<none>", referdata->replaces_callid_totag ? referdata->replaces_callid_totag : "<none>" );
12814    }
12815    
12816    if ((ptr = strchr(refer_to, '@'))) {   /* Separate domain */
12817       char *urioption = NULL, *domain;
12818       *ptr++ = '\0';
12819 
12820       if ((urioption = strchr(ptr, ';'))) /* Separate urioptions */
12821          *urioption++ = '\0';
12822       
12823       domain = ptr;
12824       if ((ptr = strchr(domain, ':'))) /* Remove :port */
12825          *ptr = '\0';
12826       
12827       /* Save the domain for the dial plan */
12828       ast_copy_string(referdata->refer_to_domain, domain, sizeof(referdata->refer_to_domain));
12829       if (urioption)
12830          ast_copy_string(referdata->refer_to_urioption, urioption, sizeof(referdata->refer_to_urioption));
12831    }
12832 
12833    if ((ptr = strchr(refer_to, ';')))  /* Remove options */
12834       *ptr = '\0';
12835    ast_copy_string(referdata->refer_to, refer_to, sizeof(referdata->refer_to));
12836    
12837    if (referred_by_uri) {
12838       if ((ptr = strchr(referred_by_uri, ';')))    /* Remove options */
12839          *ptr = '\0';
12840       ast_copy_string(referdata->referred_by, referred_by_uri, sizeof(referdata->referred_by));
12841    } else {
12842       referdata->referred_by[0] = '\0';
12843    }
12844 
12845    /* Determine transfer context */
12846    if (transferer->owner)  /* Mimic behaviour in res_features.c */
12847       transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT");
12848 
12849    /* By default, use the context in the channel sending the REFER */
12850    if (ast_strlen_zero(transfer_context)) {
12851       transfer_context = S_OR(transferer->owner->macrocontext,
12852                S_OR(transferer->context, default_context));
12853    }
12854 
12855    ast_copy_string(referdata->refer_to_context, transfer_context, sizeof(referdata->refer_to_context));
12856    
12857    /* Either an existing extension or the parking extension */
12858    if (referdata->attendedtransfer || ast_exists_extension(NULL, transfer_context, refer_to, 1, NULL) ) {
12859       if (sip_debug_test_pvt(transferer)) {
12860          ast_verbose("SIP transfer to extension %s@%s by %s\n", refer_to, transfer_context, referred_by_uri);
12861       }
12862       /* We are ready to transfer to the extension */
12863       return 0;
12864    } 
12865    if (sip_debug_test_pvt(transferer))
12866       ast_verbose("Failed SIP Transfer to non-existing extension %s in context %s\n n", refer_to, transfer_context);
12867 
12868    /* Failure, we can't find this extension */
12869    return -1;
12870 }

static int get_rpid_num ( const char *  input,
char *  output,
int  maxlen 
) [static]

Get caller id number from Remote-Party-ID header field Returns true if number should be restricted (privacy setting found) output is set to NULL if no number found.

Definition at line 13087 of file chan_sip.c.

References ast_copy_string(), and AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED.

Referenced by check_user_full().

13088 {
13089    char *start;
13090    char *end;
13091 
13092    start = strchr(input, ':');
13093    if (!start) {
13094       output[0] = '\0';
13095       return 0;
13096    }
13097    start++;
13098 
13099    /* we found "number" */
13100    ast_copy_string(output, start, maxlen);
13101    output[maxlen-1] = '\0';
13102 
13103    end = strchr(output, '@');
13104    if (end)
13105       *end = '\0';
13106    else
13107       output[0] = '\0';
13108    if (strstr(input, "privacy=full") || strstr(input, "privacy=uri"))
13109       return AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED;
13110 
13111    return 0;
13112 }

static const char * get_sdp_iterate ( int *  start,
struct sip_request req,
const char *  name 
) [static]

Lookup 'name' in the SDP starting at the 'start' line. Returns the matching line, and 'start' is updated with the next line number.

Definition at line 6398 of file chan_sip.c.

References get_body_by_line(), REQ_OFFSET_TO_STR, sip_request::sdp_count, and sip_request::sdp_start.

06399 {
06400    int len = strlen(name);
06401 
06402    while (*start < (req->sdp_start + req->sdp_count)) {
06403       const char *r = get_body_by_line(REQ_OFFSET_TO_STR(req, line[(*start)++]), name, len);
06404       if (r[0] != '\0')
06405          return r;
06406    }
06407 
06408    /* if the line was not found, ensure that *start points past the SDP */
06409    (*start)++;
06410 
06411    return "";
06412 }

static char get_sdp_line ( int *  start,
int  stop,
struct sip_request req,
const char **  value 
) [static]

Fetches the next valid SDP line between the 'start' line (inclusive) and the 'stop' line (exclusive). Returns the type ('a', 'c', ...) and matching line in reference 'start' is updated with the next line number.

Definition at line 6419 of file chan_sip.c.

References ast_skip_blanks(), REQ_OFFSET_TO_STR, sip_request::sdp_count, and sip_request::sdp_start.

Referenced by process_sdp().

06420 {
06421    char type = '\0';
06422    const char *line = NULL;
06423 
06424    if (stop > (req->sdp_start + req->sdp_count)) {
06425       stop = req->sdp_start + req->sdp_count;
06426    }
06427 
06428    while (*start < stop) {
06429       line = REQ_OFFSET_TO_STR(req, line[(*start)++]);
06430       if (line[1] == '=') {
06431          type = line[0];
06432          *value = ast_skip_blanks(line + 2);
06433          break;
06434       }
06435    }
06436 
06437    return type;
06438 }

static struct sip_pvt * get_sip_pvt_byid_locked ( const char *  callid,
const char *  totag,
const char *  fromtag 
) [static]

Lock dialog lock and find matching pvt lock.

Returns:
a reference, remember to release it when done

Definition at line 12616 of file chan_sip.c.

References ao2_t_find, ast_channel_trylock, ast_debug, ast_strlen_zero(), sip_pvt::callid, dialogs, OBJ_POINTER, sip_pvt_lock, sip_pvt_unlock, and TRUE.

Referenced by handle_request_invite(), and local_attended_transfer().

12617 {
12618    struct sip_pvt *sip_pvt_ptr;
12619    struct sip_pvt tmp_dialog = {
12620       .callid = callid,
12621    };
12622 
12623    if (totag)
12624       ast_debug(4, "Looking for callid %s (fromtag %s totag %s)\n", callid, fromtag ? fromtag : "<no fromtag>", totag ? totag : "<no totag>");
12625 
12626    /* Search dialogs and find the match */
12627    
12628    sip_pvt_ptr = ao2_t_find(dialogs, &tmp_dialog, OBJ_POINTER, "ao2_find of dialog in dialogs table");
12629    if (sip_pvt_ptr) {
12630       /* Go ahead and lock it (and its owner) before returning */
12631       sip_pvt_lock(sip_pvt_ptr);
12632       if (pedanticsipchecking) {
12633          unsigned char frommismatch = 0, tomismatch = 0;
12634 
12635          if (ast_strlen_zero(fromtag)) {
12636             sip_pvt_unlock(sip_pvt_ptr);
12637             ast_debug(4, "Matched %s call for callid=%s - no from tag specified, pedantic check fails\n",
12638                  sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid);
12639             return NULL;
12640          }
12641 
12642          if (ast_strlen_zero(totag)) {
12643             sip_pvt_unlock(sip_pvt_ptr);
12644             ast_debug(4, "Matched %s call for callid=%s - no to tag specified, pedantic check fails\n",
12645                  sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid);
12646             return NULL;
12647          }
12648          /* RFC 3891
12649           * > 3.  User Agent Server Behavior: Receiving a Replaces Header
12650           * > The Replaces header contains information used to match an existing
12651           * > SIP dialog (call-id, to-tag, and from-tag).  Upon receiving an INVITE
12652           * > with a Replaces header, the User Agent (UA) attempts to match this
12653           * > information with a confirmed or early dialog.  The User Agent Server
12654           * > (UAS) matches the to-tag and from-tag parameters as if they were tags
12655           * > present in an incoming request.  In other words, the to-tag parameter
12656           * > is compared to the local tag, and the from-tag parameter is compared
12657           * > to the remote tag.
12658           *
12659           * Thus, the totag is always compared to the local tag, regardless if
12660           * this our call is an incoming or outgoing call.
12661           */
12662          frommismatch = !!strcmp(fromtag, sip_pvt_ptr->theirtag);
12663          tomismatch = !!strcmp(totag, sip_pvt_ptr->tag);
12664          if (frommismatch || tomismatch) {
12665             sip_pvt_unlock(sip_pvt_ptr);
12666             if (frommismatch) {
12667                ast_debug(4, "Matched %s call for callid=%s - But the pedantic check rejected the match; their tag is %s Our tag is %s\n",
12668                        sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid, 
12669                        fromtag, sip_pvt_ptr->theirtag);
12670             }
12671             if (tomismatch) {
12672                ast_debug(4, "Matched %s call for callid=%s - pedantic to tag check fails; their tag is %s our tag is %s\n",
12673                     sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING", sip_pvt_ptr->callid, 
12674                     totag, sip_pvt_ptr->tag);
12675             }
12676             return NULL;
12677          }
12678       }
12679       
12680       if (totag)
12681          ast_debug(4, "Matched %s call - their tag is %s Our tag is %s\n",
12682                  sip_pvt_ptr->outgoing_call == TRUE ? "OUTGOING": "INCOMING",
12683                  sip_pvt_ptr->theirtag, sip_pvt_ptr->tag);
12684 
12685       /* deadlock avoidance... */
12686       while (sip_pvt_ptr->owner && ast_channel_trylock(sip_pvt_ptr->owner)) {
12687          sip_pvt_unlock(sip_pvt_ptr);
12688          usleep(1);
12689          sip_pvt_lock(sip_pvt_ptr);
12690       }
12691    }
12692    
12693    return sip_pvt_ptr;
12694 }

static const char* get_transport ( enum sip_transport  t  )  [inline, static]

Definition at line 3141 of file chan_sip.c.

References SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, and SIP_TRANSPORT_UDP.

Referenced by _sip_show_peer(), ast_sip_ouraddrfor(), build_contact(), build_peer(), create_addr(), get_transport_pvt(), handle_request_do(), parse_moved_contact(), sip_show_tcp(), transmit_notify_with_mwi(), and transmit_register().

03142 {
03143    switch (t) {
03144    case SIP_TRANSPORT_UDP:
03145       return "UDP";
03146    case SIP_TRANSPORT_TCP:
03147       return "TCP";
03148    case SIP_TRANSPORT_TLS:
03149       return "TLS";
03150    }
03151 
03152    return "UNKNOWN";
03153 }

static const char* get_transport_list ( struct sip_peer peer  )  [inline, static]

Definition at line 3121 of file chan_sip.c.

References SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, SIP_TRANSPORT_UDP, and sip_peer::transports.

03121                                                                     {
03122    switch (peer->transports) {
03123       case SIP_TRANSPORT_UDP:
03124          return "UDP";
03125       case SIP_TRANSPORT_TCP:
03126          return "TCP";
03127       case SIP_TRANSPORT_TLS:
03128          return "TLS";
03129       case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TCP:
03130          return "TCP,UDP";
03131       case SIP_TRANSPORT_UDP | SIP_TRANSPORT_TLS:
03132          return "TLS,UDP";
03133       case SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS:
03134          return "TLS,TCP";
03135       default:
03136          return peer->transports ? 
03137             "TLS,TCP,UDP" : "UNKNOWN"; 
03138    }
03139 }

static const char* get_transport_pvt ( struct sip_pvt p  )  [inline, static]

Definition at line 3155 of file chan_sip.c.

References get_transport(), sip_pvt::outboundproxy, set_socket_transport(), sip_pvt::socket, sip_proxy::transport, and sip_socket::type.

Referenced by __sip_xmit(), and build_via().

03156 {
03157    if (p->outboundproxy && p->outboundproxy->transport) {
03158       set_socket_transport(&p->socket, p->outboundproxy->transport);
03159    }
03160 
03161    return get_transport(p->socket.type);
03162 }

static int get_transport_str2enum ( const char *  transport  )  [static]

Return int representing a bit field of transport types found in const char *transport.

Definition at line 3100 of file chan_sip.c.

References ast_strlen_zero(), SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, and SIP_TRANSPORT_UDP.

Referenced by __set_address_from_contact(), and parse_register_contact().

03101    {
03102    int res = 0;
03103 
03104    if (ast_strlen_zero(transport)) {
03105       return res;
03106    }
03107 
03108    if (!strcasecmp(transport, "udp")) {
03109       res |= SIP_TRANSPORT_UDP;
03110    }
03111    if (!strcasecmp(transport, "tcp")) {
03112       res |= SIP_TRANSPORT_TCP;
03113    }
03114    if (!strcasecmp(transport, "tls")) {
03115       res |= SIP_TRANSPORT_TLS;
03116    }
03117 
03118    return res;
03119 }

static const char * gettag ( const struct sip_request req,
const char *  header,
char *  tagbuf,
int  tagbufsize 
) [static]

Get tag from packet.

Returns:
Returns the pointer to the provided tag buffer, or NULL if the tag was not found.

Definition at line 18151 of file chan_sip.c.

References ast_copy_string(), get_header(), strcasestr(), and strsep().

Referenced by find_call(), handle_incoming(), handle_request_subscribe(), and handle_response().

18152 {
18153    const char *thetag;
18154 
18155    if (!tagbuf)
18156       return NULL;
18157    tagbuf[0] = '\0';    /* reset the buffer */
18158    thetag = get_header(req, header);
18159    thetag = strcasestr(thetag, ";tag=");
18160    if (thetag) {
18161       thetag += 5;
18162       ast_copy_string(tagbuf, thetag, tagbufsize);
18163       return strsep(&tagbuf, ";");
18164    }
18165    return NULL;
18166 }

static int handle_common_options ( struct ast_flags flags,
struct ast_flags mask,
struct ast_variable v 
) [static]

Handle flag-type options common to configuration of devices - peers.

Parameters:
flags array of two struct ast_flags
mask array of two struct ast_flags
v linked list of config variables to process
Returns:
non-zero if any config options were handled, zero otherwise

Definition at line 22384 of file chan_sip.c.

References ast_clear_flag, ast_copy_string(), ast_false(), ast_log(), ast_set2_flag, ast_set_flag, ast_true(), buf, ast_channel::flags, ast_variable::lineno, LOG_WARNING, ast_variable::name, ast_channel::next, set_insecure_flags(), SIP_CAN_REINVITE, SIP_CAN_REINVITE_NAT, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_DTMF_SHORTINFO, SIP_G726_NONSTANDARD, SIP_INSECURE, SIP_NAT, SIP_NAT_ALWAYS, SIP_NAT_NEVER, SIP_NAT_RFC3581, SIP_NAT_ROUTE, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_BUGGY_MWI, SIP_PAGE2_FAX_DETECT, SIP_PAGE2_IGNORESDPVERSION, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_TEXTSUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_PAGE2_VIDEOSUPPORT_ALWAYS, SIP_PROG_INBAND, SIP_PROG_INBAND_NO, SIP_PROG_INBAND_YES, SIP_PROMISCREDIR, SIP_REINVITE, SIP_REINVITE_UPDATE, SIP_SENDRPID, SIP_TRUSTRPID, SIP_USECLIENTCODE, strsep(), and ast_variable::value.

Referenced by build_peer().

22385 {
22386    int res = 1;
22387 
22388    if (!strcasecmp(v->name, "trustrpid")) {
22389       ast_set_flag(&mask[0], SIP_TRUSTRPID);
22390       ast_set2_flag(&flags[0], ast_true(v->value), SIP_TRUSTRPID);
22391    } else if (!strcasecmp(v->name, "sendrpid")) {
22392       ast_set_flag(&mask[0], SIP_SENDRPID);
22393       ast_set2_flag(&flags[0], ast_true(v->value), SIP_SENDRPID);
22394    } else if (!strcasecmp(v->name, "g726nonstandard")) {
22395       ast_set_flag(&mask[0], SIP_G726_NONSTANDARD);
22396       ast_set2_flag(&flags[0], ast_true(v->value), SIP_G726_NONSTANDARD);
22397    } else if (!strcasecmp(v->name, "useclientcode")) {
22398       ast_set_flag(&mask[0], SIP_USECLIENTCODE);
22399       ast_set2_flag(&flags[0], ast_true(v->value), SIP_USECLIENTCODE);
22400    } else if (!strcasecmp(v->name, "dtmfmode")) {
22401       ast_set_flag(&mask[0], SIP_DTMF);
22402       ast_clear_flag(&flags[0], SIP_DTMF);
22403       if (!strcasecmp(v->value, "inband"))
22404          ast_set_flag(&flags[0], SIP_DTMF_INBAND);
22405       else if (!strcasecmp(v->value, "rfc2833"))
22406          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
22407       else if (!strcasecmp(v->value, "info"))
22408          ast_set_flag(&flags[0], SIP_DTMF_INFO);
22409       else if (!strcasecmp(v->value, "shortinfo"))
22410          ast_set_flag(&flags[0], SIP_DTMF_SHORTINFO);
22411       else if (!strcasecmp(v->value, "auto"))
22412          ast_set_flag(&flags[0], SIP_DTMF_AUTO);
22413       else {
22414          ast_log(LOG_WARNING, "Unknown dtmf mode '%s' on line %d, using rfc2833\n", v->value, v->lineno);
22415          ast_set_flag(&flags[0], SIP_DTMF_RFC2833);
22416       }
22417    } else if (!strcasecmp(v->name, "nat")) {
22418       ast_set_flag(&mask[0], SIP_NAT);
22419       ast_clear_flag(&flags[0], SIP_NAT);
22420       if (!strcasecmp(v->value, "never"))
22421          ast_set_flag(&flags[0], SIP_NAT_NEVER);
22422       else if (!strcasecmp(v->value, "route"))
22423          ast_set_flag(&flags[0], SIP_NAT_ROUTE);
22424       else if (ast_true(v->value))
22425          ast_set_flag(&flags[0], SIP_NAT_ALWAYS);
22426       else
22427          ast_set_flag(&flags[0], SIP_NAT_RFC3581);
22428    } else if (!strcasecmp(v->name, "canreinvite")) {
22429       ast_set_flag(&mask[0], SIP_REINVITE);
22430       ast_clear_flag(&flags[0], SIP_REINVITE);
22431       if (ast_true(v->value)) {
22432          ast_set_flag(&flags[0], SIP_CAN_REINVITE | SIP_CAN_REINVITE_NAT);
22433       } else if (!ast_false(v->value)) {
22434          char buf[64];
22435          char *word, *next = buf;
22436 
22437          ast_copy_string(buf, v->value, sizeof(buf));
22438          while ((word = strsep(&next, ","))) {
22439             if (!strcasecmp(word, "update")) {
22440                ast_set_flag(&flags[0], SIP_REINVITE_UPDATE | SIP_CAN_REINVITE);
22441             } else if (!strcasecmp(word, "nonat")) {
22442                ast_set_flag(&flags[0], SIP_CAN_REINVITE);
22443                ast_clear_flag(&flags[0], SIP_CAN_REINVITE_NAT);
22444             } else {
22445                ast_log(LOG_WARNING, "Unknown canreinvite mode '%s' on line %d\n", v->value, v->lineno);
22446             }
22447          }
22448       }
22449    } else if (!strcasecmp(v->name, "insecure")) {
22450       ast_set_flag(&mask[0], SIP_INSECURE);
22451       ast_clear_flag(&flags[0], SIP_INSECURE);
22452       set_insecure_flags(&flags[0], v->value, v->lineno);   
22453    } else if (!strcasecmp(v->name, "progressinband")) {
22454       ast_set_flag(&mask[0], SIP_PROG_INBAND);
22455       ast_clear_flag(&flags[0], SIP_PROG_INBAND);
22456       if (ast_true(v->value))
22457          ast_set_flag(&flags[0], SIP_PROG_INBAND_YES);
22458       else if (strcasecmp(v->value, "never"))
22459          ast_set_flag(&flags[0], SIP_PROG_INBAND_NO);
22460    } else if (!strcasecmp(v->name, "promiscredir")) {
22461       ast_set_flag(&mask[0], SIP_PROMISCREDIR);
22462       ast_set2_flag(&flags[0], ast_true(v->value), SIP_PROMISCREDIR);
22463    } else if (!strcasecmp(v->name, "videosupport")) {
22464       if (!strcasecmp(v->value, "always")) {
22465          ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS);
22466          ast_set_flag(&flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS);
22467       } else {
22468          ast_set_flag(&mask[1], SIP_PAGE2_VIDEOSUPPORT);
22469          ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_VIDEOSUPPORT);
22470       }
22471    } else if (!strcasecmp(v->name, "textsupport")) {
22472       ast_set_flag(&mask[1], SIP_PAGE2_TEXTSUPPORT);
22473       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_TEXTSUPPORT);
22474       res = 1;
22475    } else if (!strcasecmp(v->name, "allowoverlap")) {
22476       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWOVERLAP);
22477       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWOVERLAP);
22478    } else if (!strcasecmp(v->name, "allowsubscribe")) {
22479       ast_set_flag(&mask[1], SIP_PAGE2_ALLOWSUBSCRIBE);
22480       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_ALLOWSUBSCRIBE);
22481    } else if (!strcasecmp(v->name, "ignoresdpversion")) {
22482       ast_set_flag(&mask[1], SIP_PAGE2_IGNORESDPVERSION);
22483       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_IGNORESDPVERSION);
22484    } else if (!strcasecmp(v->name, "rfc2833compensate")) {
22485       ast_set_flag(&mask[1], SIP_PAGE2_RFC2833_COMPENSATE);
22486       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_RFC2833_COMPENSATE);
22487    } else if (!strcasecmp(v->name, "buggymwi")) {
22488       ast_set_flag(&mask[1], SIP_PAGE2_BUGGY_MWI);
22489       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_BUGGY_MWI);
22490    } else if (!strcasecmp(v->name, "faxdetect")) {
22491                 ast_set_flag(&mask[1], SIP_PAGE2_FAX_DETECT);
22492                 ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_FAX_DETECT);
22493    } else
22494       res = 0;
22495 
22496    return res;
22497 }

static int handle_incoming ( struct sip_pvt p,
struct sip_request req,
struct sockaddr_in *  sin,
int *  recount,
int *  nounlock 
) [static]

Handle incoming SIP requests (methods).

Note:
This is where all incoming requests go first

Definition at line 20650 of file chan_sip.c.

References __sip_ack(), ast_debug, ast_inet_ntoa(), ast_log(), ast_skip_blanks(), ast_string_field_set, ast_strlen_zero(), ast_verbose, check_pendings(), sip_request::debug, debug, DEFAULT_TRANS_TIMEOUT, extract_uri(), find_sdp(), get_header(), gettag(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_message(), handle_request_notify(), handle_request_options(), handle_request_refer(), handle_request_register(), handle_request_subscribe(), handle_response(), sip_request::has_to_tag, sip_request::headers, cfsip_methods::id, sip_request::ignore, sip_pvt::initreq, INV_TERMINATED, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, sip_request::method, sip_pvt::method, sip_pvt::needdestroy, option_debug, process_sdp(), REQ_OFFSET_TO_STR, SDP_T38_NONE, SIP_ACK, SIP_BYE, SIP_CANCEL, sip_debug_test_pvt(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NOTIFY, SIP_OPTIONS, SIP_REFER, SIP_REGISTER, SIP_RESPONSE, sip_scheddestroy(), SIP_SUBSCRIBE, cfsip_methods::text, sip_pvt::theirtag, transmit_response(), transmit_response_reliable(), transmit_response_with_allow(), and sip_pvt::useragent.

Referenced by handle_request_do(), and process_request_queue().

20651 {
20652    /* Called with p->lock held, as well as p->owner->lock if appropriate, keeping things
20653       relatively static */
20654    const char *cmd;
20655    const char *cseq;
20656    const char *useragent;
20657    int seqno;
20658    int len;
20659    int respid;
20660    int res = 0;
20661    int debug = sip_debug_test_pvt(p);
20662    char *e;
20663    int error = 0;
20664    int oldmethod = p->method;
20665    int acked = 0;
20666 
20667    /* Get Method and Cseq */
20668    cseq = get_header(req, "Cseq");
20669    cmd = REQ_OFFSET_TO_STR(req, header[0]);
20670 
20671    /* Must have Cseq */
20672    if (ast_strlen_zero(cmd) || ast_strlen_zero(cseq)) {
20673       ast_log(LOG_ERROR, "Missing Cseq. Dropping this SIP message, it's incomplete.\n");
20674       error = 1;
20675    }
20676    if (!error && sscanf(cseq, "%30d%n", &seqno, &len) != 1) {
20677       ast_log(LOG_ERROR, "No seqno in '%s'. Dropping incomplete message.\n", cmd);
20678       error = 1;
20679    }
20680    if (error) {
20681       if (!p->initreq.headers)   /* New call */
20682          p->needdestroy = 1; /* Make sure we destroy this dialog */
20683       return -1;
20684    }
20685    /* Get the command XXX */
20686 
20687    cmd = REQ_OFFSET_TO_STR(req, rlPart1);
20688    e = ast_skip_blanks(REQ_OFFSET_TO_STR(req, rlPart2));
20689 
20690    /* Save useragent of the client */
20691    useragent = get_header(req, "User-Agent");
20692    if (!ast_strlen_zero(useragent))
20693       ast_string_field_set(p, useragent, useragent);
20694 
20695    /* Find out SIP method for incoming request */
20696    if (req->method == SIP_RESPONSE) {  /* Response to our request */
20697       /* ignore means "don't do anything with it" but still have to 
20698        * respond appropriately.
20699        * But in this case this is a response already, so we really
20700        * have nothing to do with this message, and even setting the
20701        * ignore flag is pointless.
20702        */
20703       if (ast_strlen_zero(e)) {
20704          return 0;
20705       }
20706       if (sscanf(e, "%30d %n", &respid, &len) != 1) {
20707          ast_log(LOG_WARNING, "Invalid response: '%s'\n", e);
20708          return 0;
20709       }
20710       if (respid <= 0) {
20711          ast_log(LOG_WARNING, "Invalid SIP response code: '%d'\n", respid);
20712          return 0;
20713       }
20714       if (p->ocseq && (p->ocseq < seqno)) {
20715          if (option_debug)
20716             ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq);
20717          return -1;
20718       } else {
20719          if ((respid == 200) || ((respid >= 300) && (respid <= 399))) {
20720             extract_uri(p, req);
20721          }
20722          handle_response(p, respid, e + len, req, seqno);
20723       }
20724       return 0;
20725    }
20726 
20727    /* New SIP request coming in 
20728       (could be new request in existing SIP dialog as well...) 
20729     */         
20730    
20731    p->method = req->method;   /* Find out which SIP method they are using */
20732    ast_debug(4, "**** Received %s (%d) - Command in SIP %s\n", sip_methods[p->method].text, sip_methods[p->method].id, cmd); 
20733 
20734    if (p->icseq && (p->icseq > seqno) ) {
20735       if (p->pendinginvite && seqno == p->pendinginvite && (req->method == SIP_ACK || req->method == SIP_CANCEL)) {
20736          ast_debug(2, "Got CANCEL or ACK on INVITE with transactions in between.\n");
20737       }  else {
20738          ast_debug(1, "Ignoring too old SIP packet packet %d (expecting >= %d)\n", seqno, p->icseq);
20739          if (req->method != SIP_ACK)
20740             transmit_response(p, "503 Server error", req);  /* We must respond according to RFC 3261 sec 12.2 */
20741          return -1;
20742       }
20743    } else if (p->icseq &&
20744          p->icseq == seqno &&
20745          req->method != SIP_ACK &&
20746          (p->method != SIP_CANCEL || p->alreadygone)) {
20747       /* ignore means "don't do anything with it" but still have to 
20748          respond appropriately.  We do this if we receive a repeat of
20749          the last sequence number  */
20750       req->ignore = 1;
20751       ast_debug(3, "Ignoring SIP message because of retransmit (%s Seqno %d, ours %d)\n", sip_methods[p->method].text, p->icseq, seqno);
20752    }
20753       
20754    if (seqno >= p->icseq)
20755       /* Next should follow monotonically (but not necessarily 
20756          incrementally -- thanks again to the genius authors of SIP --
20757          increasing */
20758       p->icseq = seqno;
20759 
20760    /* Find their tag if we haven't got it */
20761    if (ast_strlen_zero(p->theirtag)) {
20762       char tag[128];
20763 
20764       gettag(req, "From", tag, sizeof(tag));
20765       ast_string_field_set(p, theirtag, tag);
20766    }
20767    snprintf(p->lastmsg, sizeof(p->lastmsg), "Rx: %s", cmd);
20768 
20769    if (pedanticsipchecking) {
20770       /* If this is a request packet without a from tag, it's not
20771          correct according to RFC 3261  */
20772       /* Check if this a new request in a new dialog with a totag already attached to it,
20773          RFC 3261 - section 12.2 - and we don't want to mess with recovery  */
20774       if (!p->initreq.headers && req->has_to_tag) {
20775          /* If this is a first request and it got a to-tag, it is not for us */
20776          if (!req->ignore && req->method == SIP_INVITE) {
20777             transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req);
20778             /* Will cease to exist after ACK */
20779          } else if (req->method != SIP_ACK) {
20780             transmit_response(p, "481 Call/Transaction Does Not Exist", req);
20781             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20782          } else {
20783             ast_debug(1, "Got ACK for unknown dialog... strange.\n");
20784          }
20785          return res;
20786       }
20787    }
20788 
20789    if (!e && (p->method == SIP_INVITE || p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER || p->method == SIP_NOTIFY)) {
20790       transmit_response(p, "400 Bad request", req);
20791       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20792       return -1;
20793    }
20794 
20795    /* Handle various incoming SIP methods in requests */
20796    switch (p->method) {
20797    case SIP_OPTIONS:
20798       res = handle_request_options(p, req);
20799       break;
20800    case SIP_INVITE:
20801       res = handle_request_invite(p, req, debug, seqno, sin, recount, e, nounlock);
20802       break;
20803    case SIP_REFER:
20804       res = handle_request_refer(p, req, debug, seqno, nounlock);
20805       break;
20806    case SIP_CANCEL:
20807       res = handle_request_cancel(p, req);
20808       break;
20809    case SIP_BYE:
20810       res = handle_request_bye(p, req);
20811       break;
20812    case SIP_MESSAGE:
20813       res = handle_request_message(p, req);
20814       break;
20815    case SIP_SUBSCRIBE:
20816       res = handle_request_subscribe(p, req, sin, seqno, e);
20817       break;
20818    case SIP_REGISTER:
20819       res = handle_request_register(p, req, sin, e);
20820       break;
20821    case SIP_INFO:
20822       if (req->debug)
20823          ast_verbose("Receiving INFO!\n");
20824       if (!req->ignore) 
20825          handle_request_info(p, req);
20826       else  /* if ignoring, transmit response */
20827          transmit_response(p, "200 OK", req);
20828       break;
20829    case SIP_NOTIFY:
20830       res = handle_request_notify(p, req, sin, seqno, e);
20831       break;
20832    case SIP_ACK:
20833       /* Make sure we don't ignore this */
20834       if (seqno == p->pendinginvite) {
20835          p->invitestate = INV_TERMINATED;
20836          p->pendinginvite = 0;
20837          acked = __sip_ack(p, seqno, 1 /* response */, 0);
20838          if (find_sdp(req)) {
20839             if (process_sdp(p, req, SDP_T38_NONE))
20840                return -1;
20841          }
20842          check_pendings(p);
20843       } else if (p->glareinvite == seqno) {
20844          /* handle ack for the 491 pending sent for glareinvite */
20845          p->glareinvite = 0;
20846          acked = __sip_ack(p, seqno, 1, 0);
20847       }
20848       if (!acked) {
20849          /* Got an ACK that did not match anything. Ignore
20850           * silently and restore previous method */
20851          p->method = oldmethod;
20852       }
20853       if (!p->lastinvite && ast_strlen_zero(p->randdata))
20854          p->needdestroy = 1;
20855       break;
20856    default:
20857       transmit_response_with_allow(p, "501 Method Not Implemented", req, 0);
20858       ast_log(LOG_NOTICE, "Unknown SIP command '%s' from '%s'\n", 
20859          cmd, ast_inet_ntoa(p->sa.sin_addr));
20860       /* If this is some new method, and we don't have a call, destroy it now */
20861       if (!p->initreq.headers)
20862          p->needdestroy = 1;
20863       break;
20864    }
20865    return res;
20866 }

static int handle_invite_replaces ( struct sip_pvt p,
struct sip_request req,
int  debug,
int  seqno,
struct sockaddr_in *  sin,
int *  nounlock 
) [static]

Handle the transfer part of INVITE with a replaces: header, meaning a target pickup or an attended transfer. Used only once. XXX 'ignore' is unused.

Note:
this function is called by handle_request_invite(). Four locks held at the beginning of this function, p, p->owner, p->refer->refer_call->owner... only p's lock should remain at the end of this function. p's lock is held by sipsock_read()

Definition at line 18351 of file chan_sip.c.

References ast_channel::_state, append_history, ast_bridged_channel(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_masquerade(), ast_channel_unlock, ast_debug, ast_do_masquerade(), ast_hangup(), ast_log(), ast_quiet_chan(), ast_set_flag, ast_setstate(), ast_state2str(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, DEFAULT_TRANS_TIMEOUT, dialog_unref(), FALSE, sip_pvt::flags, ast_channel::hangupcause, sip_request::ignore, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_channel::name, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_call, SIP_DEFER_BYE_ON_TRANSFER, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), ast_channel::tech_pvt, transmit_response(), transmit_response_reliable(), transmit_response_with_sdp(), and XMIT_RELIABLE.

Referenced by handle_request_invite().

18352 {
18353    int earlyreplace = 0;
18354    int oneleggedreplace = 0;     /* Call with no bridge, propably IVR or voice message */
18355    struct ast_channel *c = p->owner;   /* Our incoming call */
18356    struct ast_channel *replacecall = p->refer->refer_call->owner; /* The channel we're about to take over */
18357    struct ast_channel *targetcall;     /* The bridge to the take-over target */
18358 
18359    struct ast_channel *test;
18360 
18361    /* Check if we're in ring state */
18362    if (replacecall->_state == AST_STATE_RING)
18363       earlyreplace = 1;
18364 
18365    /* Check if we have a bridge */
18366    if (!(targetcall = ast_bridged_channel(replacecall))) {
18367       /* We have no bridge */
18368       if (!earlyreplace) {
18369          ast_debug(2, " Attended transfer attempted to replace call with no bridge (maybe ringing). Channel %s!\n", replacecall->name);
18370          oneleggedreplace = 1;
18371       }
18372    } 
18373    if (targetcall && targetcall->_state == AST_STATE_RINGING)
18374       ast_debug(4, "SIP transfer: Target channel is in ringing state\n");
18375 
18376    if (targetcall) 
18377       ast_debug(4, "SIP transfer: Invite Replace incoming channel should bridge to channel %s while hanging up channel %s\n", targetcall->name, replacecall->name); 
18378    else
18379       ast_debug(4, "SIP transfer: Invite Replace incoming channel should replace and hang up channel %s (one call leg)\n", replacecall->name); 
18380 
18381    if (req->ignore) {
18382       ast_log(LOG_NOTICE, "Ignoring this INVITE with replaces in a stupid way.\n");
18383       /* We should answer something here. If we are here, the
18384          call we are replacing exists, so an accepted 
18385          can't harm */
18386       transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE);
18387       /* Do something more clever here */
18388       if (c) {
18389          *nounlock = 1;
18390          ast_channel_unlock(c);
18391       }
18392       ast_channel_unlock(replacecall);
18393       sip_pvt_unlock(p->refer->refer_call);
18394       return 1;
18395    } 
18396    if (!c) {
18397       /* What to do if no channel ??? */
18398       ast_log(LOG_ERROR, "Unable to create new channel.  Invite/replace failed.\n");
18399       transmit_response_reliable(p, "503 Service Unavailable", req);
18400       append_history(p, "Xfer", "INVITE/Replace Failed. No new channel.");
18401       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
18402       ast_channel_unlock(replacecall);
18403       sip_pvt_unlock(p->refer->refer_call);
18404       return 1;
18405    }
18406    append_history(p, "Xfer", "INVITE/Replace received");
18407    /* We have three channels to play with
18408       channel c: New incoming call
18409       targetcall: Call from PBX to target
18410       p->refer->refer_call: SIP pvt dialog from transferer to pbx.
18411       replacecall: The owner of the previous
18412       We need to masq C into refer_call to connect to 
18413       targetcall;
18414       If we are talking to internal audio stream, target call is null.
18415    */
18416 
18417    /* Fake call progress */
18418    transmit_response(p, "100 Trying", req);
18419    ast_setstate(c, AST_STATE_RING);
18420 
18421    /* Masquerade the new call into the referred call to connect to target call 
18422       Targetcall is not touched by the masq */
18423 
18424    /* Answer the incoming call and set channel to UP state */
18425    transmit_response_with_sdp(p, "200 OK", req, XMIT_RELIABLE, FALSE);
18426       
18427    ast_setstate(c, AST_STATE_UP);
18428    
18429    /* Stop music on hold and other generators */
18430    ast_quiet_chan(replacecall);
18431    ast_quiet_chan(targetcall);
18432    ast_debug(4, "Invite/Replaces: preparing to masquerade %s into %s\n", c->name, replacecall->name);
18433 
18434    /* Make sure that the masq does not free our PVT for the old call */
18435    if (! earlyreplace && ! oneleggedreplace )
18436       ast_set_flag(&p->refer->refer_call->flags[0], SIP_DEFER_BYE_ON_TRANSFER);  /* Delay hangup */
18437 
18438    /* Prepare the masquerade - if this does not happen, we will be gone */
18439    if(ast_channel_masquerade(replacecall, c))
18440       ast_log(LOG_ERROR, "Failed to masquerade C into Replacecall\n");
18441    else
18442       ast_debug(4, "Invite/Replaces: Going to masquerade %s into %s\n", c->name, replacecall->name);
18443 
18444    /* C should now be in place of replacecall */
18445    if (ast_do_masquerade(replacecall)) {
18446       ast_log(LOG_WARNING, "Failed to perform masquerade with INVITE replaces\n");
18447    }
18448 
18449    if (earlyreplace || oneleggedreplace ) {
18450       c->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
18451    }
18452 
18453    ast_setstate(c, AST_STATE_DOWN);
18454    ast_debug(4, "After transfer:----------------------------\n");
18455    ast_debug(4, " -- C:        %s State %s\n", c->name, ast_state2str(c->_state));
18456    if (replacecall)
18457       ast_debug(4, " -- replacecall:        %s State %s\n", replacecall->name, ast_state2str(replacecall->_state));
18458    if (p->owner) {
18459       ast_debug(4, " -- P->owner: %s State %s\n", p->owner->name, ast_state2str(p->owner->_state));
18460       test = ast_bridged_channel(p->owner);
18461       if (test)
18462          ast_debug(4, " -- Call bridged to P->owner: %s State %s\n", test->name, ast_state2str(test->_state));
18463       else
18464          ast_debug(4, " -- No call bridged to C->owner \n");
18465    } else 
18466       ast_debug(4, " -- No channel yet \n");
18467    ast_debug(4, "End After transfer:----------------------------\n");
18468 
18469    /* unlock sip pvt and owner so hangup can do its thing */
18470    ast_channel_unlock(replacecall);
18471    ast_channel_unlock(c);
18472    sip_pvt_unlock(p->refer->refer_call);
18473    sip_pvt_unlock(p);
18474    *nounlock = 1;
18475 
18476    /* The call should be down with no ast_channel, so hang it up */
18477    c->tech_pvt = dialog_unref(c->tech_pvt, "unref dialog c->tech_pvt");
18478    ast_hangup(c);
18479    sip_pvt_lock(p); /* lock PVT structure again after hangup */
18480 
18481    return 0;
18482 }

static int handle_request_bye ( struct sip_pvt p,
struct sip_request req 
) [static]

Handle incoming BYE request.

Definition at line 20119 of file chan_sip.c.

References __sip_pretend_ack(), append_history, ast_async_goto(), ast_bridged_channel(), AST_CAUSE_PROTOCOL_ERROR, ast_channel_trylock, ast_channel_unlock, ast_clear_flag, AST_CONTROL_UNHOLD, ast_debug, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_rtp_get_quality(), ast_rtp_set_vars(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, sip_pvt::callid, check_via(), context, sip_pvt::context, copy_request(), DEFAULT_TRANS_TIMEOUT, sip_pvt::do_history, sip_pvt::flags, get_also_info(), get_header(), sip_request::ignore, sip_pvt::initreq, INV_TERMINATED, sip_pvt::invitestate, IS_SIP_TECH, LOG_NOTICE, LOG_WARNING, sip_request::method, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::pendinginvite, sip_pvt::recv, sip_pvt::refer, sip_refer::refer_to, sip_pvt::rtp, RTPQOS_JITTER, RTPQOS_LOSS, RTPQOS_RTT, RTPQOS_SUMMARY, sip_alreadygone(), sip_methods, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), stop_media_flows(), stop_session_timer(), ast_channel::tech, ast_channel::tech_pvt, transmit_response(), transmit_response_reliable(), sip_pvt::trtp, and sip_pvt::vrtp.

Referenced by handle_incoming().

20120 {
20121    struct ast_channel *c=NULL;
20122    int res;
20123    struct ast_channel *bridged_to;
20124    
20125    /* If we have an INCOMING invite that we haven't answered, terminate that transaction */
20126    if (p->pendinginvite && !ast_test_flag(&p->flags[0], SIP_OUTGOING) && !req->ignore) {
20127       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
20128    }
20129 
20130    __sip_pretend_ack(p);
20131 
20132    p->invitestate = INV_TERMINATED;
20133 
20134    copy_request(&p->initreq, req);
20135    if (sipdebug)
20136       ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
20137    check_via(p, req);
20138    sip_alreadygone(p);
20139 
20140    /* Get RTCP quality before end of call */
20141    if (p->do_history || p->owner) {
20142       struct ast_channel *bridge = p->owner ? ast_bridged_channel(p->owner) : NULL;
20143       char *videoqos, *textqos;
20144 
20145       /* We need to get the lock on bridge because ast_rtp_set_vars will attempt
20146        * to lock the bridge. This may get hairy...
20147        */
20148       while (bridge && ast_channel_trylock(bridge)) {
20149          ast_channel_unlock(p->owner);
20150          do {
20151             /* Can't use DEADLOCK_AVOIDANCE since p is an ao2 object */
20152             sip_pvt_unlock(p);
20153             usleep(1);
20154             sip_pvt_lock(p);
20155          } while (p->owner && ast_channel_trylock(p->owner));
20156          bridge = p->owner ? ast_bridged_channel(p->owner) : NULL;
20157       }
20158 
20159       if (p->rtp) {  
20160          if (p->do_history) {
20161             char *audioqos,
20162                  *audioqos_jitter,
20163                  *audioqos_loss,
20164                  *audioqos_rtt;
20165 
20166             audioqos        = ast_rtp_get_quality(p->rtp, NULL, RTPQOS_SUMMARY);
20167             audioqos_jitter = ast_rtp_get_quality(p->rtp, NULL, RTPQOS_JITTER);
20168             audioqos_loss   = ast_rtp_get_quality(p->rtp, NULL, RTPQOS_LOSS);
20169             audioqos_rtt    = ast_rtp_get_quality(p->rtp, NULL, RTPQOS_RTT);
20170 
20171             append_history(p, "RTCPaudio", "Quality:%s", audioqos);
20172             append_history(p, "RTCPaudioJitter", "Quality:%s", audioqos_jitter);
20173             append_history(p, "RTCPaudioLoss", "Quality:%s", audioqos_loss);
20174             append_history(p, "RTCPaudioRTT", "Quality:%s", audioqos_rtt);
20175          }
20176          
20177          if (p->owner) {
20178             ast_rtp_set_vars(p->owner, p->rtp);
20179          }
20180       }
20181 
20182       if (bridge) {
20183          struct sip_pvt *q = bridge->tech_pvt;
20184 
20185          if (IS_SIP_TECH(bridge->tech) && q && q->rtp)
20186             ast_rtp_set_vars(bridge, q->rtp);
20187          ast_channel_unlock(bridge);
20188       }
20189 
20190       if (p->vrtp) {
20191          videoqos = ast_rtp_get_quality(p->vrtp, NULL, RTPQOS_SUMMARY);
20192          if (p->do_history)
20193             append_history(p, "RTCPvideo", "Quality:%s", videoqos);
20194          if (p->owner)
20195             pbx_builtin_setvar_helper(p->owner, "RTPVIDEOQOS", videoqos);
20196       }
20197 
20198       if (p->trtp) {
20199          textqos = ast_rtp_get_quality(p->trtp, NULL, RTPQOS_SUMMARY);
20200          if (p->do_history)
20201             append_history(p, "RTCPtext", "Quality:%s", textqos);
20202          if (p->owner)
20203             pbx_builtin_setvar_helper(p->owner, "RTPTEXTQOS", textqos);
20204       }
20205    }
20206 
20207    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
20208    stop_session_timer(p); /* Stop Session-Timer */
20209 
20210    if (!ast_strlen_zero(get_header(req, "Also"))) {
20211       ast_log(LOG_NOTICE, "Client '%s' using deprecated BYE/Also transfer method.  Ask vendor to support REFER instead\n",
20212          ast_inet_ntoa(p->recv.sin_addr));
20213       if (ast_strlen_zero(p->context))
20214          ast_string_field_set(p, context, default_context);
20215       res = get_also_info(p, req);
20216       if (!res) {
20217          c = p->owner;
20218          if (c) {
20219             bridged_to = ast_bridged_channel(c);
20220             if (bridged_to) {
20221                /* Don't actually hangup here... */
20222                ast_queue_control(c, AST_CONTROL_UNHOLD);
20223                ast_async_goto(bridged_to, p->context, p->refer->refer_to, 1);
20224             } else
20225                ast_queue_hangup(p->owner);
20226          }
20227       } else {
20228          ast_log(LOG_WARNING, "Invalid transfer information from '%s'\n", ast_inet_ntoa(p->recv.sin_addr));
20229          if (p->owner)
20230             ast_queue_hangup_with_cause(p->owner, AST_CAUSE_PROTOCOL_ERROR);
20231       }
20232    } else if (p->owner) {
20233       ast_queue_hangup(p->owner);
20234       ast_debug(3, "Received bye, issuing owner hangup\n");
20235    } else {
20236       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20237       ast_debug(3, "Received bye, no owner, selfdestruct soon.\n");
20238    }
20239    ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
20240    transmit_response(p, "200 OK", req);
20241 
20242    return 1;
20243 }

static int handle_request_cancel ( struct sip_pvt p,
struct sip_request req 
) [static]

Handle incoming CANCEL request.

Definition at line 19943 of file chan_sip.c.

References __sip_pretend_ack(), ast_debug, ast_free, ast_queue_hangup(), AST_SCHED_DEL, AST_STATE_UP, ast_test_flag, check_via(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, INV_CANCELLED, INV_TERMINATED, sip_pvt::invitestate, sip_pkt::next, sip_dual::req, sip_pkt::response_code, sip_pkt::retransid, sched, sip_pkt::seqno, sip_alreadygone(), SIP_INC_COUNT, SIP_PAGE2_CALL_ONHOLD, sip_scheddestroy(), stop_media_flows(), transmit_response(), transmit_response_reliable(), UNLINK, and update_call_counter().

Referenced by handle_incoming().

19944 {
19945       
19946    check_via(p, req);
19947    sip_alreadygone(p);
19948 
19949    /* At this point, we could have cancelled the invite at the same time
19950       as the other side sends a CANCEL. Our final reply with error code
19951       might not have been received by the other side before the CANCEL
19952       was sent, so let's just give up retransmissions and waiting for
19953       ACK on our error code. The call is hanging up any way. */
19954    if (p->invitestate == INV_TERMINATED)
19955       __sip_pretend_ack(p);
19956    else
19957       p->invitestate = INV_CANCELLED;
19958    
19959    if (p->owner && p->owner->_state == AST_STATE_UP) {
19960       /* This call is up, cancel is ignored, we need a bye */
19961       transmit_response(p, "200 OK", req);
19962       ast_debug(1, "Got CANCEL on an answered call. Ignoring... \n");
19963       return 0;
19964    }
19965 
19966    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) 
19967       update_call_counter(p, DEC_CALL_LIMIT);
19968 
19969    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
19970    if (p->owner)
19971       ast_queue_hangup(p->owner);
19972    else
19973       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
19974    if (p->initreq.len > 0) {
19975       struct sip_pkt *pkt, *prev_pkt;
19976       /* If the CANCEL we are receiving is a retransmission, and we already have scheduled
19977        * a reliable 487, then we don't want to schedule another one on top of the previous
19978        * one.
19979        *
19980        * As odd as this may sound, we can't rely on the previously-transmitted "reliable" 
19981        * response in this situation. What if we've sent all of our reliable responses 
19982        * already and now all of a sudden, we get this second CANCEL?
19983        *
19984        * The only way to do this correctly is to cancel our previously-scheduled reliably-
19985        * transmitted response and send a new one in its place.
19986        */
19987       for (pkt = p->packets, prev_pkt = NULL; pkt; prev_pkt = pkt, pkt = pkt->next) {
19988          if (pkt->seqno == p->lastinvite && pkt->response_code == 487) {
19989             AST_SCHED_DEL(sched, pkt->retransid);
19990             UNLINK(pkt, p->packets, prev_pkt);
19991             ast_free(pkt);
19992             break;
19993          }
19994       }
19995       transmit_response_reliable(p, "487 Request Terminated", &p->initreq);
19996       transmit_response(p, "200 OK", req);
19997       return 1;
19998    } else {
19999       transmit_response(p, "481 Call Leg Does Not Exist", req);
20000       return 0;
20001    }
20002 }

static int handle_request_do ( struct sip_request req,
struct sockaddr_in *  sin 
) [static]

Definition at line 21008 of file chan_sip.c.

References ao2_t_ref, append_history, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), AST_SCHED_DEL_UNREF, ast_str_reset(), ast_update_use_count(), ast_verbose, sip_pvt::callid, copy_socket_data(), sip_request::data, sip_request::debug, dialog_unref(), sip_pvt::do_history, find_call(), find_sip_method(), get_header(), get_transport(), handle_incoming(), sip_request::headers, sip_request::len, sip_request::lines, LOG_ERROR, lws2sws(), sip_request::method, ast_channel::name, netlock, sip_pvt::owner, parse_request(), process_request_queue(), queue_request(), sip_pvt::recv, REQ_OFFSET_TO_STR, sip_pvt::request_queue, sip_pvt::request_queue_sched_id, S_OR, sched, SIP_ACK, sip_debug_test_addr(), sip_pvt_unlock, sip_pvt::socket, sip_request::socket, ast_str::str, transmit_response(), and sip_socket::type.

Referenced by _sip_tcp_helper_thread(), and sipsock_read().

21009 {
21010    struct sip_pvt *p;
21011    int recount = 0;
21012    int nounlock = 0;
21013    int lockretry;
21014 
21015    if (sip_debug_test_addr(sin)) /* Set the debug flag early on packet level */
21016       req->debug = 1;
21017    if (pedanticsipchecking)
21018       req->len = lws2sws(req->data->str, req->len);   /* Fix multiline headers */
21019    if (req->debug) {
21020       ast_verbose("\n<--- SIP read from %s://%s:%d --->\n%s\n<------------->\n", 
21021          get_transport(req->socket.type), ast_inet_ntoa(sin->sin_addr), 
21022          ntohs(sin->sin_port), req->data->str);
21023    }
21024 
21025    if (parse_request(req) == -1) { /* Bad packet, can't parse */
21026       ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */
21027       return 1;
21028    }
21029    req->method = find_sip_method(REQ_OFFSET_TO_STR(req, rlPart1));
21030 
21031    if (req->debug)
21032       ast_verbose("--- (%d headers %d lines)%s ---\n", req->headers, req->lines, (req->headers + req->lines == 0) ? " Nat keepalive" : "");
21033 
21034    if (req->headers < 2) { /* Must have at least two headers */
21035       ast_str_reset(req->data); /* nulling this out is NOT a good idea here. */
21036       return 1;
21037    }
21038 
21039    /* Process request, with netlock held, and with usual deadlock avoidance */
21040    for (lockretry = 10; lockretry > 0; lockretry--) {
21041       ast_mutex_lock(&netlock);
21042 
21043       /* Find the active SIP dialog or create a new one */
21044       p = find_call(req, sin, req->method);  /* returns p locked */
21045       if (p == NULL) {
21046          ast_debug(1, "Invalid SIP message - rejected , no callid, len %d\n", req->len);
21047          ast_mutex_unlock(&netlock);
21048          return 1;
21049       }
21050 
21051       copy_socket_data(&p->socket, &req->socket);
21052 
21053       /* Go ahead and lock the owner if it has one -- we may need it */
21054       /* becaues this is deadlock-prone, we need to try and unlock if failed */
21055       if (!p->owner || !ast_channel_trylock(p->owner))
21056          break;   /* locking succeeded */
21057 
21058       if (lockretry != 1) {
21059          sip_pvt_unlock(p);
21060          ao2_t_ref(p, -1, "release p (from find_call) inside lockretry loop"); /* we'll look for it again, but p is dead now */
21061          ast_mutex_unlock(&netlock);
21062          /* Sleep for a very short amount of time */
21063          usleep(1);
21064       }
21065    }
21066    p->recv = *sin;
21067 
21068    if (p->do_history) /* This is a request or response, note what it was for */
21069       append_history(p, "Rx", "%s / %s / %s", req->data->str, get_header(req, "CSeq"), REQ_OFFSET_TO_STR(req, rlPart2));
21070 
21071    if (!lockretry) {
21072       if (!queue_request(p, req)) {
21073          /* the request has been queued for later handling */
21074          sip_pvt_unlock(p);
21075          ao2_t_ref(p, -1, "release p (from find_call) after queueing request");
21076          ast_mutex_unlock(&netlock);
21077          return 1;
21078       }
21079 
21080       if (p->owner)
21081          ast_log(LOG_ERROR, "Channel lock for %s could not be obtained, and request was unable to be queued.\n", S_OR(p->owner->name, "- no channel name ??? - "));
21082       ast_log(LOG_ERROR, "SIP transaction failed: %s \n", p->callid);
21083       if (req->method != SIP_ACK)
21084          transmit_response(p, "503 Server error", req);  /* We must respond according to RFC 3261 sec 12.2 */
21085       /* XXX We could add retry-after to make sure they come back */
21086       append_history(p, "LockFail", "Owner lock failed, transaction failed.");
21087       sip_pvt_unlock(p);
21088       ao2_t_ref(p, -1, "release p (from find_call) at end of lockretry"); /* p is gone after the return */
21089       ast_mutex_unlock(&netlock);
21090       return 1;
21091    }
21092 
21093    /* if there are queued requests on this sip_pvt, process them first, so that everything is
21094       handled in order
21095    */
21096    if (!AST_LIST_EMPTY(&p->request_queue)) {
21097       AST_SCHED_DEL_UNREF(sched, p->request_queue_sched_id, dialog_unref(p, "when you delete the request_queue_sched_id sched, you should dec the refcount for the stored dialog ptr"));
21098       process_request_queue(p, &recount, &nounlock);
21099    }
21100 
21101    if (handle_incoming(p, req, sin, &recount, &nounlock) == -1) {
21102       /* Request failed */
21103       ast_debug(1, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
21104    }
21105       
21106    if (recount)
21107       ast_update_use_count();
21108 
21109    if (p->owner && !nounlock)
21110       ast_channel_unlock(p->owner);
21111    sip_pvt_unlock(p);
21112    ast_mutex_unlock(&netlock);
21113    ao2_t_ref(p, -1, "throw away dialog ptr from find_call at end of routine"); /* p is gone after the return */
21114    return 1;
21115 }

static void handle_request_info ( struct sip_pvt p,
struct sip_request req 
) [static]

Receive SIP INFO Message.

Todo:
Note: Doesn't read the duration of the DTMF. Should be fixed.

Definition at line 15807 of file chan_sip.c.

References ast_bridged_channel(), ast_cdr_setuserfield(), AST_CONTROL_FLASH, AST_CONTROL_VIDUPDATE, ast_copy_string(), ast_debug, ast_find_call_feature(), AST_FRAME_CONTROL, AST_FRAME_DTMF, ast_log(), ast_queue_control(), ast_queue_frame(), ast_rdlock_call_features(), ast_strlen_zero(), ast_test_flag, ast_unlock_call_features(), ast_verbose, buf, sip_pvt::callid, ast_channel::cdr, DEFAULT_TRANS_TIMEOUT, sip_history::event, ast_call_feature::exten, f, sip_pvt::flags, get_body(), get_header(), get_msg_text(), LOG_WARNING, sip_pvt::owner, sip_scheddestroy(), SIP_USECLIENTCODE, transmit_response(), and TRUE.

Referenced by handle_incoming().

15808 {
15809    char buf[1024];
15810    unsigned int event;
15811    const char *c = get_header(req, "Content-Type");
15812 
15813    /* Need to check the media/type */
15814    if (!strcasecmp(c, "application/dtmf-relay") ||
15815        !strcasecmp(c, "application/vnd.nortelnetworks.digits")) {
15816       unsigned int duration = 0;
15817 
15818       if (!p->owner) {  /* not a PBX call */
15819          transmit_response(p, "481 Call leg/transaction does not exist", req);
15820          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15821          return;
15822       }
15823 
15824       /* Try getting the "signal=" part */
15825       if (ast_strlen_zero(c = get_body(req, "Signal")) && ast_strlen_zero(c = get_body(req, "d"))) {
15826          ast_log(LOG_WARNING, "Unable to retrieve DTMF signal from INFO message from %s\n", p->callid);
15827          transmit_response(p, "200 OK", req); /* Should return error */
15828          return;
15829       } else {
15830          ast_copy_string(buf, c, sizeof(buf));
15831       }
15832 
15833       if (!ast_strlen_zero((c = get_body(req, "Duration"))))
15834          duration = atoi(c);
15835       if (!duration)
15836          duration = 100; /* 100 ms */
15837 
15838 
15839       if (ast_strlen_zero(buf)) {
15840          transmit_response(p, "200 OK", req);
15841          return;
15842       }
15843 
15844       if (buf[0] == '*')
15845          event = 10;
15846       else if (buf[0] == '#')
15847          event = 11;
15848       else if ((buf[0] >= 'A') && (buf[0] <= 'D'))
15849          event = 12 + buf[0] - 'A';
15850       else if (buf[0] == '!')
15851          event = 16;
15852       else
15853          event = atoi(buf);
15854       if (event == 16) {
15855          /* send a FLASH event */
15856          struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, };
15857          ast_queue_frame(p->owner, &f);
15858          if (sipdebug)
15859             ast_verbose("* DTMF-relay event received: FLASH\n");
15860       } else {
15861          /* send a DTMF event */
15862          struct ast_frame f = { AST_FRAME_DTMF, };
15863          if (event < 10) {
15864             f.subclass = '0' + event;
15865          } else if (event < 11) {
15866             f.subclass = '*';
15867          } else if (event < 12) {
15868             f.subclass = '#';
15869          } else if (event < 16) {
15870             f.subclass = 'A' + (event - 12);
15871          }
15872          f.len = duration;
15873          ast_queue_frame(p->owner, &f);
15874          if (sipdebug)
15875             ast_verbose("* DTMF-relay event received: %c\n", f.subclass);
15876       }
15877       transmit_response(p, "200 OK", req);
15878       return;
15879    } else if (!strcasecmp(c, "application/dtmf")) {
15880       /*! \todo Note: Doesn't read the duration of the DTMF. Should be fixed. */
15881       unsigned int duration = 0;
15882 
15883       if (!p->owner) {  /* not a PBX call */
15884          transmit_response(p, "481 Call leg/transaction does not exist", req);
15885          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
15886          return;
15887       }
15888 
15889       get_msg_text(buf, sizeof(buf), req, TRUE);
15890       duration = 100; /* 100 ms */
15891 
15892       if (ast_strlen_zero(buf)) {
15893          transmit_response(p, "200 OK", req);
15894          return;
15895       }
15896       event = atoi(buf);
15897       if (event == 16) {
15898          /* send a FLASH event */
15899          struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_FLASH, };
15900          ast_queue_frame(p->owner, &f);
15901          if (sipdebug)
15902             ast_verbose("* DTMF-relay event received: FLASH\n");
15903       } else {
15904          /* send a DTMF event */
15905          struct ast_frame f = { AST_FRAME_DTMF, };
15906          if (event < 10) {
15907             f.subclass = '0' + event;
15908          } else if (event < 11) {
15909             f.subclass = '*';
15910          } else if (event < 12) {
15911             f.subclass = '#';
15912          } else if (event < 16) {
15913             f.subclass = 'A' + (event - 12);
15914          }
15915          f.len = duration;
15916          ast_queue_frame(p->owner, &f);
15917          if (sipdebug)
15918             ast_verbose("* DTMF-relay event received: %c\n", f.subclass);
15919       }
15920       transmit_response(p, "200 OK", req);
15921       return;
15922 
15923    } else if (!strcasecmp(c, "application/media_control+xml")) {
15924       /* Eh, we'll just assume it's a fast picture update for now */
15925       if (p->owner)
15926          ast_queue_control(p->owner, AST_CONTROL_VIDUPDATE);
15927       transmit_response(p, "200 OK", req);
15928       return;
15929    } else if (!ast_strlen_zero(c = get_header(req, "X-ClientCode"))) {
15930       /* Client code (from SNOM phone) */
15931       if (ast_test_flag(&p->flags[0], SIP_USECLIENTCODE)) {
15932          if (p->owner && p->owner->cdr)
15933             ast_cdr_setuserfield(p->owner, c);
15934          if (p->owner && ast_bridged_channel(p->owner) && ast_bridged_channel(p->owner)->cdr)
15935             ast_cdr_setuserfield(ast_bridged_channel(p->owner), c);
15936          transmit_response(p, "200 OK", req);
15937       } else {
15938          transmit_response(p, "403 Forbidden", req);
15939       }
15940       return;
15941    } else if (!ast_strlen_zero(c = get_header(req, "Record"))) {
15942       /* INFO messages generated by some phones to start/stop recording
15943          on phone calls. 
15944          OEJ: I think this should be something that is enabled/disabled
15945          per device. I don't want incoming callers to record calls in my
15946          pbx.
15947       */
15948       /* first, get the feature string, if it exists */
15949       struct ast_call_feature *feat;
15950       int j;
15951       struct ast_frame f = { AST_FRAME_DTMF, };
15952 
15953       ast_rdlock_call_features();
15954       feat = ast_find_call_feature("automon");
15955       if (!feat || ast_strlen_zero(feat->exten)) {
15956          ast_log(LOG_WARNING, "Recording requested, but no One Touch Monitor registered. (See features.conf)\n");
15957          /* 403 means that we don't support this feature, so don't request it again */
15958          transmit_response(p, "403 Forbidden", req);
15959          ast_unlock_call_features();
15960          return;
15961       } 
15962       /* Send the feature code to the PBX as DTMF, just like the handset had sent it */
15963       f.len = 100;
15964       for (j=0; j < strlen(feat->exten); j++) {
15965          f.subclass = feat->exten[j];
15966          ast_queue_frame(p->owner, &f);
15967          if (sipdebug)
15968             ast_verbose("* DTMF-relay event faked: %c\n", f.subclass);
15969       }
15970       ast_unlock_call_features();
15971 
15972       ast_debug(1, "Got a Request to Record the channel, state %s\n", c);
15973       transmit_response(p, "200 OK", req);
15974       return;
15975    } else if (ast_strlen_zero(c = get_header(req, "Content-Length")) || !strcasecmp(c, "0")) {
15976       /* This is probably just a packet making sure the signalling is still up, just send back a 200 OK */
15977       transmit_response(p, "200 OK", req);
15978       return;
15979    }
15980 
15981    /* Other type of INFO message, not really understood by Asterisk */
15982    /* if (get_msg_text(buf, sizeof(buf), req)) { */
15983 
15984    ast_log(LOG_WARNING, "Unable to parse INFO message from %s. Content %s\n", p->callid, buf);
15985    transmit_response(p, "415 Unsupported media type", req);
15986    return;
15987 }

static int handle_request_invite ( struct sip_pvt p,
struct sip_request req,
int  debug,
int  seqno,
struct sockaddr_in *  sin,
int *  recount,
char *  e,
int *  nounlock 
) [static]

Handle incoming INVITE request.

Note:
If the INVITE has a Replaces header, it is part of an attended transfer. If so, we do not go through the dial plan but tries to find the active call and masquerade into it

This is a spiral. What we need to do is to just change the outgoing INVITE so that it now routes to the new Request URI. Since we created the INVITE ourselves that should be all we need to do.

Todo:
XXX This needs to be reviewed. YOu don't change the request URI really, you route the packet correctly instead...

Definition at line 18787 of file chan_sip.c.

References __sip_ack(), ast_channel::_state, append_history, AST_CAUSE_CALL_REJECTED, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_clear_flag, AST_CONTROL_BUSY, AST_CONTROL_SRCUPDATE, ast_debug, ast_hangup(), ast_log(), ast_null_frame, AST_PBX_CALL_LIMIT, AST_PBX_FAILED, ast_pbx_start(), AST_PBX_SUCCESS, ast_pickup_call(), ast_pickup_ext(), ast_queue_control(), ast_queue_frame(), ast_rtp_set_alt_peer(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_sched_add(), ast_set_flag, ast_setstate(), ast_skip_blanks(), AST_STATE_DOWN, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_new_with_bindaddr(), ast_uri_decode(), ast_verbose, AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), build_route(), ast_channel::call_forward, sip_pvt::callid, sip_pvt::capability, check_user(), check_via(), context, sip_pvt::context, copy_request(), DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, dialog_ref(), dialog_unref(), sip_pvt::do_history, exten, sip_pvt::exten, extract_uri(), FALSE, find_sdp(), sip_pvt::flags, get_destination(), get_header(), get_ip_and_port_from_sdp(), get_rdnis(), get_sip_pvt_byid_locked(), sip_pvt::glareinvite, handle_invite_replaces(), ast_channel::hangupcause, sip_request::headers, sip_request::ignore, INC_CALL_LIMIT, sip_pvt::initreq, INV_COMPLETED, INV_CONFIRMED, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, io, sip_pvt::jointcapability, sip_pvt::lastinvite, LOG_ERROR, LOG_NOTICE, LOG_WARNING, make_our_tag(), sip_request::method, msg, ast_channel::name, sip_pvt::owner, parse_minse(), parse_ok_contact(), parse_session_expires(), parse_sip_options(), sip_pvt::peername, sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_refer::refer_call, REQ_OFFSET_TO_STR, sip_pvt::reqsipoptions, restart_session_timer(), sip_pvt::rtp, S_OR, sched, SDP_AUDIO, SDP_T38_INITIATE, SDP_VIDEO, sip_pvt::session_modify, SESSION_TIMER_MODE_ACCEPT, SESSION_TIMER_MODE_ORIGINATE, SESSION_TIMER_MODE_REFUSE, SESSION_TIMER_REFRESHER_AUTO, SESSION_TIMER_REFRESHER_UAS, set_t38_capabilities(), sip_alreadygone(), sip_cancel_destroy(), SIP_DTMF, SIP_DTMF_RFC2833, SIP_INVITE, sip_methods, sip_new(), SIP_OPT_REPLACES, SIP_OPT_TIMER, SIP_OUTGOING, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, sip_pvt_lock, sip_pvt_unlock, sip_refer_allocate(), sip_scheddestroy(), sip_st_alloc(), sip_t38_abort(), sip_uri_cmp(), sip_pvt::sipoptions, sip_st_dlg::st_active, sip_st_dlg::st_active_peer_ua, sip_st_dlg::st_expirys, st_get_mode(), st_get_refresher(), st_get_se(), sip_st_dlg::st_interval, sip_st_dlg::st_ref, start_session_timer(), t38properties::state, sip_pvt::stimer, strcasestr(), strsep(), sip_pvt::t38, T38_DISABLED, T38_ENABLED, sip_pvt::t38_maxdatagram, T38_PEER_REINVITE, sip_pvt::t38id, sip_pvt::tag, transmit_fake_auth_response(), transmit_provisional_response(), transmit_response(), transmit_response_reliable(), transmit_response_with_minse(), transmit_response_with_sdp(), transmit_response_with_t38_sdp(), transmit_response_with_unsupported(), TRUE, sip_pvt::udptl, update_call_counter(), sip_pvt::username, sip_pvt::vrtp, XMIT_CRITICAL, XMIT_RELIABLE, and XMIT_UNRELIABLE.

Referenced by handle_incoming().

18788 {
18789    int res = 1;
18790    int gotdest;
18791    const char *p_replaces;
18792    char *replace_id = NULL;
18793    int refer_locked = 0;
18794    const char *required;
18795    unsigned int required_profile = 0;
18796    struct ast_channel *c = NULL;    /* New channel */
18797    int reinvite = 0;
18798    int rtn;
18799 
18800    const char *p_uac_se_hdr;       /* UAC's Session-Expires header string                      */
18801    const char *p_uac_min_se;       /* UAC's requested Min-SE interval (char string)            */
18802    int uac_max_se = -1;            /* UAC's Session-Expires in integer format                  */
18803    int uac_min_se = -1;            /* UAC's Min-SE in integer format                           */
18804    int st_active = FALSE;          /* Session-Timer on/off boolean                             */
18805    int st_interval = 0;            /* Session-Timer negotiated refresh interval                */
18806    enum st_refresher st_ref;       /* Session-Timer session refresher                          */
18807    int dlg_min_se = -1;
18808    st_ref = SESSION_TIMER_REFRESHER_AUTO;
18809 
18810    /* Find out what they support */
18811    if (!p->sipoptions) {
18812       const char *supported = get_header(req, "Supported");
18813       if (!ast_strlen_zero(supported))
18814          parse_sip_options(p, supported);
18815    }
18816 
18817    /* Find out what they require */
18818    required = get_header(req, "Require");
18819    if (!ast_strlen_zero(required)) {
18820       required_profile = parse_sip_options(NULL, required);
18821       if (required_profile && !(required_profile & (SIP_OPT_REPLACES | SIP_OPT_TIMER))) {
18822          /* At this point we only support REPLACES and Session-Timer */
18823          transmit_response_with_unsupported(p, "420 Bad extension (unsupported)", req, required);
18824          ast_log(LOG_WARNING, "Received SIP INVITE with unsupported required extension: %s\n", required);
18825          p->invitestate = INV_COMPLETED;
18826          if (!p->lastinvite)
18827             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
18828          res = -1;
18829          goto request_invite_cleanup;
18830       }
18831    }
18832 
18833    /* The option tags may be present in Supported: or Require: headers.
18834    Include the Require: option tags for further processing as well */
18835    p->sipoptions |= required_profile;
18836    p->reqsipoptions = required_profile;
18837 
18838    /* Check if this is a loop */
18839    if (ast_test_flag(&p->flags[0], SIP_OUTGOING) && p->owner && (p->invitestate != INV_TERMINATED && p->invitestate != INV_CONFIRMED)) {
18840       /* This is a call to ourself.  Send ourselves an error code and stop
18841          processing immediately, as SIP really has no good mechanism for
18842          being able to call yourself */
18843       /* If pedantic is on, we need to check the tags. If they're different, this is
18844          in fact a forked call through a SIP proxy somewhere. */
18845       int different;
18846       char *initial_rlPart2 = REQ_OFFSET_TO_STR(&p->initreq, rlPart2);
18847       char *this_rlPart2 = REQ_OFFSET_TO_STR(req, rlPart2);
18848       if (pedanticsipchecking)
18849          different = sip_uri_cmp(initial_rlPart2, this_rlPart2);
18850       else
18851          different = strcmp(initial_rlPart2, this_rlPart2);
18852       if (!different) {
18853          transmit_response(p, "482 Loop Detected", req);
18854          p->invitestate = INV_COMPLETED;
18855          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
18856          res = 0;
18857          goto request_invite_cleanup;
18858       } else {
18859          /*! This is a spiral. What we need to do is to just change the outgoing INVITE
18860           * so that it now routes to the new Request URI. Since we created the INVITE ourselves
18861           * that should be all we need to do.
18862           * 
18863           * \todo XXX This needs to be reviewed.  YOu don't change the request URI really, you route the packet
18864           * correctly instead...
18865           */
18866          char *uri = ast_strdupa(this_rlPart2);
18867          char *at = strchr(uri, '@');
18868          char *peerorhost;
18869          ast_debug(2, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", initial_rlPart2, this_rlPart2);
18870          transmit_response(p, "100 Trying", req);
18871          if (at) {
18872             *at = '\0';
18873          }
18874          /* Parse out "sip:" */
18875          if ((peerorhost = strchr(uri, ':'))) {
18876             *peerorhost++ = '\0';
18877          }
18878          ast_string_field_set(p, theirtag, NULL);
18879          /* Treat this as if there were a call forward instead...
18880           */
18881          ast_string_field_set(p->owner, call_forward, peerorhost);
18882          ast_queue_control(p->owner, AST_CONTROL_BUSY);
18883          res = 0;
18884          goto request_invite_cleanup;
18885       }
18886    }
18887 
18888    if (!req->ignore && p->pendinginvite) {
18889       if (!ast_test_flag(&p->flags[0], SIP_OUTGOING) && (p->invitestate == INV_COMPLETED || p->invitestate == INV_TERMINATED)) {
18890          /* What do these circumstances mean? We have received an INVITE for an "incoming" dialog for which we
18891           * have sent a final response. We have not yet received an ACK, though (which is why p->pendinginvite is non-zero).
18892           * We also know that the INVITE is not a retransmission, because otherwise the "ignore" flag would be set.
18893           * This means that either we are receiving a reinvite for a terminated dialog, or we are receiving an INVITE with
18894           * credentials based on one we challenged earlier.
18895           *
18896           * The action to take in either case is to treat the INVITE as though it contains an implicit ACK for the previous
18897           * transaction. Calling __sip_ack will take care of this by clearing the p->pendinginvite and removing the response
18898           * from the previous transaction from the list of outstanding packets.
18899           */
18900          __sip_ack(p, p->pendinginvite, 1, 0);
18901       } else {
18902          /* We already have a pending invite. Sorry. You are on hold. */
18903          p->glareinvite = seqno;
18904          if (p->rtp && find_sdp(req)) {
18905             struct sockaddr_in sin;
18906             if (get_ip_and_port_from_sdp(req, SDP_AUDIO, &sin)) {
18907                ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Audio may not work properly on this call.\n");
18908             } else {
18909                ast_rtp_set_alt_peer(p->rtp, &sin);
18910             }
18911             if (p->vrtp) {
18912                if (get_ip_and_port_from_sdp(req, SDP_VIDEO, &sin)) {
18913                   ast_log(LOG_WARNING, "Failed to set an alternate media source on glared reinvite. Video may not work properly on this call.\n");
18914                } else {
18915                   ast_rtp_set_alt_peer(p->vrtp, &sin);
18916                }
18917             }
18918          }
18919          transmit_response_reliable(p, "491 Request Pending", req);
18920          ast_debug(1, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid);
18921          /* Don't destroy dialog here */
18922          res = 0;
18923          goto request_invite_cleanup;
18924       }
18925    }
18926 
18927    p_replaces = get_header(req, "Replaces");
18928    if (!ast_strlen_zero(p_replaces)) {
18929       /* We have a replaces header */
18930       char *ptr;
18931       char *fromtag = NULL;
18932       char *totag = NULL;
18933       char *start, *to;
18934       int error = 0;
18935 
18936       if (p->owner) {
18937          ast_debug(3, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid);
18938          transmit_response_reliable(p, "400 Bad request", req);   /* The best way to not not accept the transfer */
18939          /* Do not destroy existing call */
18940          res = -1;
18941          goto request_invite_cleanup;
18942       }
18943 
18944       if (sipdebug)
18945          ast_debug(3, "INVITE part of call transfer. Replaces [%s]\n", p_replaces);
18946       /* Create a buffer we can manipulate */
18947       replace_id = ast_strdupa(p_replaces);
18948       ast_uri_decode(replace_id);
18949 
18950       if (!p->refer && !sip_refer_allocate(p)) {
18951          transmit_response_reliable(p, "500 Server Internal Error", req);
18952          append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory.");
18953          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
18954          p->invitestate = INV_COMPLETED;
18955          res = -1;
18956          goto request_invite_cleanup;
18957       }
18958 
18959       /*  Todo: (When we find phones that support this)
18960          if the replaces header contains ";early-only"
18961          we can only replace the call in early
18962          stage, not after it's up.
18963 
18964          If it's not in early mode, 486 Busy.
18965       */
18966       
18967       /* Skip leading whitespace */
18968       replace_id = ast_skip_blanks(replace_id);
18969 
18970       start = replace_id;
18971       while ( (ptr = strsep(&start, ";")) ) {
18972          ptr = ast_skip_blanks(ptr); /* XXX maybe unnecessary ? */
18973          if ( (to = strcasestr(ptr, "to-tag=") ) )
18974             totag = to + 7;   /* skip the keyword */
18975          else if ( (to = strcasestr(ptr, "from-tag=") ) ) {
18976             fromtag = to + 9; /* skip the keyword */
18977             fromtag = strsep(&fromtag, "&"); /* trim what ? */
18978          }
18979       }
18980 
18981       if (sipdebug) 
18982          ast_debug(4, "Invite/replaces: Will use Replace-Call-ID : %s Fromtag: %s Totag: %s\n", replace_id, fromtag ? fromtag : "<no from tag>", totag ? totag : "<no to tag>");
18983 
18984 
18985       /* Try to find call that we are replacing 
18986          If we have a Replaces  header, we need to cancel that call if we succeed with this call 
18987       */
18988       if ((p->refer->refer_call = get_sip_pvt_byid_locked(replace_id, totag, fromtag)) == NULL) {
18989          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existent call id (%s)!\n", replace_id);
18990          transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replaces)", req);
18991          error = 1;
18992       } else {
18993          refer_locked = 1;
18994       }
18995 
18996       /* At this point, bot the pvt and the owner of the call to be replaced is locked */
18997 
18998       /* The matched call is the call from the transferer to Asterisk .
18999          We want to bridge the bridged part of the call to the 
19000          incoming invite, thus taking over the refered call */
19001 
19002       if (p->refer->refer_call == p) {
19003          ast_log(LOG_NOTICE, "INVITE with replaces into it's own call id (%s == %s)!\n", replace_id, p->callid);
19004          p->refer->refer_call = dialog_unref(p->refer->refer_call, "unref dialog p->refer->refer_call");
19005          transmit_response_reliable(p, "400 Bad request", req);   /* The best way to not not accept the transfer */
19006          error = 1;
19007       }
19008 
19009       if (!error && !p->refer->refer_call->owner) {
19010          /* Oops, someting wrong anyway, no owner, no call */
19011          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-existing call id (%s)!\n", replace_id);
19012          /* Check for better return code */
19013          transmit_response_reliable(p, "481 Call Leg Does Not Exist (Replace)", req);
19014          error = 1;
19015       }
19016 
19017       if (!error && p->refer->refer_call->owner->_state != AST_STATE_RINGING && p->refer->refer_call->owner->_state != AST_STATE_RING && p->refer->refer_call->owner->_state != AST_STATE_UP ) {
19018          ast_log(LOG_NOTICE, "Supervised transfer attempted to replace non-ringing or active call id (%s)!\n", replace_id);
19019          transmit_response_reliable(p, "603 Declined (Replaces)", req);
19020          error = 1;
19021       }
19022 
19023       if (error) {   /* Give up this dialog */
19024          append_history(p, "Xfer", "INVITE/Replace Failed.");
19025          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
19026          sip_pvt_unlock(p);
19027          if (p->refer->refer_call) {
19028             sip_pvt_unlock(p->refer->refer_call);
19029             if (p->refer->refer_call->owner) {
19030                ast_channel_unlock(p->refer->refer_call->owner);
19031             }
19032          }
19033          refer_locked = 0;
19034          p->invitestate = INV_COMPLETED;
19035          res = -1;
19036          goto request_invite_cleanup;
19037       }
19038    }
19039 
19040    /* Check if this is an INVITE that sets up a new dialog or
19041       a re-invite in an existing dialog */
19042 
19043    if (!req->ignore) {
19044       int newcall = (p->initreq.headers ? TRUE : FALSE);
19045 
19046       if (sip_cancel_destroy(p))
19047          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
19048       /* This also counts as a pending invite */
19049       p->pendinginvite = seqno;
19050       check_via(p, req);
19051 
19052       copy_request(&p->initreq, req);     /* Save this INVITE as the transaction basis */
19053       if (sipdebug)
19054          ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
19055       if (!p->owner) {  /* Not a re-invite */
19056          if (debug)
19057             ast_verbose("Using INVITE request as basis request - %s\n", p->callid);
19058          if (newcall)
19059             append_history(p, "Invite", "New call: %s", p->callid);
19060          parse_ok_contact(p, req);
19061       } else { /* Re-invite on existing call */
19062          ast_clear_flag(&p->flags[0], SIP_OUTGOING);  /* This is now an inbound dialog */
19063          /* Handle SDP here if we already have an owner */
19064          if (find_sdp(req)) {
19065             if (process_sdp(p, req, SDP_T38_INITIATE)) {
19066                transmit_response_reliable(p, "488 Not acceptable here", req);
19067                if (!p->lastinvite)
19068                   sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
19069                res = -1;
19070                goto request_invite_cleanup;
19071             }
19072             ast_queue_control(p->owner, AST_CONTROL_SRCUPDATE);
19073          } else {
19074             p->jointcapability = p->capability;
19075             ast_debug(1, "Hm....  No sdp for the moment\n");
19076          }
19077          if (p->do_history) /* This is a response, note what it was for */
19078             append_history(p, "ReInv", "Re-invite received");
19079       }
19080    } else if (debug)
19081       ast_verbose("Ignoring this INVITE request\n");
19082 
19083    
19084    if (!p->lastinvite && !req->ignore && !p->owner) {
19085       /* This is a new invite */
19086       /* Handle authentication if this is our first invite */
19087       res = check_user(p, req, SIP_INVITE, e, XMIT_RELIABLE, sin);
19088       if (res == AUTH_CHALLENGE_SENT) {
19089          p->invitestate = INV_COMPLETED;     /* Needs to restart in another INVITE transaction */
19090          res = 0;
19091          goto request_invite_cleanup;
19092       }
19093       if (res < 0) { /* Something failed in authentication */
19094          if (res == AUTH_FAKE_AUTH) {
19095             ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From"));
19096             transmit_fake_auth_response(p, SIP_INVITE, req, XMIT_RELIABLE);
19097          } else {
19098             ast_log(LOG_NOTICE, "Failed to authenticate device %s\n", get_header(req, "From"));
19099             transmit_response_reliable(p, "403 Forbidden", req);
19100          }
19101          p->invitestate = INV_COMPLETED;  
19102          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
19103          ast_string_field_set(p, theirtag, NULL);
19104          res = 0;
19105          goto request_invite_cleanup;
19106       }
19107 
19108       /* If T38 is needed but not present, then make it magically appear */
19109       if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT) && !p->udptl && (p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr))) {
19110          p->t38_maxdatagram = global_t38_maxdatagram;
19111          set_t38_capabilities(p);
19112       }
19113 
19114       /* We have a succesful authentication, process the SDP portion if there is one */
19115       if (find_sdp(req)) {
19116          if (process_sdp(p, req, SDP_T38_INITIATE)) {
19117             /* Unacceptable codecs */
19118             transmit_response_reliable(p, "488 Not acceptable here", req);
19119             p->invitestate = INV_COMPLETED;  
19120             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
19121             ast_debug(1, "No compatible codecs for this SIP call.\n");
19122             res = -1;
19123             goto request_invite_cleanup;
19124          }
19125       } else { /* No SDP in invite, call control session */
19126          p->jointcapability = p->capability;
19127          ast_debug(2, "No SDP in Invite, third party call control\n");
19128       }
19129 
19130       /* Queue NULL frame to prod ast_rtp_bridge if appropriate */
19131       /* This seems redundant ... see !p-owner above */
19132       if (p->owner)
19133          ast_queue_frame(p->owner, &ast_null_frame);
19134 
19135 
19136       /* Initialize the context if it hasn't been already */
19137       if (ast_strlen_zero(p->context))
19138          ast_string_field_set(p, context, default_context);
19139 
19140 
19141       /* Check number of concurrent calls -vs- incoming limit HERE */
19142       ast_debug(1, "Checking SIP call limits for device %s\n", p->username);
19143       if ((res = update_call_counter(p, INC_CALL_LIMIT))) {
19144          if (res < 0) {
19145             ast_log(LOG_NOTICE, "Failed to place call for device %s, too many calls\n", p->username);
19146             transmit_response_reliable(p, "480 Temporarily Unavailable (Call limit) ", req);
19147             sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
19148             p->invitestate = INV_COMPLETED;  
19149          }
19150          res = 0;
19151          goto request_invite_cleanup;
19152       }
19153       gotdest = get_destination(p, NULL); /* Get destination right away */
19154       get_rdnis(p, NULL);        /* Get redirect information */
19155       extract_uri(p, req);       /* Get the Contact URI */
19156       build_contact(p);       /* Build our contact header */
19157 
19158       if (p->rtp) {
19159          ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
19160          ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
19161       }
19162 
19163       if (!replace_id && gotdest) { /* No matching extension found */
19164          if (gotdest == 1 && ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWOVERLAP))
19165             transmit_response_reliable(p, "484 Address Incomplete", req);
19166          else {
19167             char *decoded_exten = ast_strdupa(p->exten);
19168             
19169             transmit_response_reliable(p, "404 Not Found", req);
19170             ast_uri_decode(decoded_exten);
19171             ast_log(LOG_NOTICE, "Call from '%s' to extension"
19172                " '%s' rejected because extension not found in context '%s'.\n",
19173                S_OR(p->username, p->peername), decoded_exten, p->context);
19174          }
19175          p->invitestate = INV_COMPLETED;  
19176          update_call_counter(p, DEC_CALL_LIMIT);
19177          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
19178          res = 0;
19179          goto request_invite_cleanup;
19180       } else {
19181 
19182          /* If no extension was specified, use the s one */
19183          /* Basically for calling to IP/Host name only */
19184          if (ast_strlen_zero(p->exten))
19185             ast_string_field_set(p, exten, "s");
19186          /* Initialize our tag */   
19187 
19188          make_our_tag(p->tag, sizeof(p->tag));
19189          /* First invitation - create the channel */
19190          c = sip_new(p, AST_STATE_DOWN, S_OR(p->peername, NULL));
19191          *recount = 1;
19192 
19193          /* Save Record-Route for any later requests we make on this dialogue */
19194          build_route(p, req, 0);
19195 
19196          if (c) {
19197             /* Pre-lock the call */
19198             ast_channel_lock(c);
19199          }
19200       }
19201    } else {
19202       if (sipdebug) {
19203          if (!req->ignore)
19204             ast_debug(2, "Got a SIP re-invite for call %s\n", p->callid);
19205          else
19206             ast_debug(2, "Got a SIP re-transmit of INVITE for call %s\n", p->callid);
19207       }
19208       if (!req->ignore)
19209          reinvite = 1;
19210       c = p->owner;
19211    }
19212 
19213    /* Session-Timers */
19214    if (p->sipoptions & SIP_OPT_TIMER) {
19215       /* The UAC has requested session-timers for this session. Negotiate
19216       the session refresh interval and who will be the refresher */
19217       ast_debug(2, "Incoming INVITE with 'timer' option enabled\n");
19218 
19219       /* Allocate Session-Timers struct w/in the dialog */
19220       if (!p->stimer)
19221          sip_st_alloc(p);
19222 
19223       /* Parse the Session-Expires header */
19224       p_uac_se_hdr = get_header(req, "Session-Expires");
19225       if (!ast_strlen_zero(p_uac_se_hdr)) {
19226          rtn = parse_session_expires(p_uac_se_hdr, &uac_max_se, &st_ref);
19227          if (rtn != 0) {
19228             transmit_response_reliable(p, "400 Session-Expires Invalid Syntax", req);
19229             p->invitestate = INV_COMPLETED;
19230             if (!p->lastinvite) {
19231                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
19232             }
19233             res = -1;
19234             goto request_invite_cleanup;
19235          }
19236       }
19237 
19238       /* Parse the Min-SE header */
19239       p_uac_min_se = get_header(req, "Min-SE");
19240       if (!ast_strlen_zero(p_uac_min_se)) {
19241          rtn = parse_minse(p_uac_min_se, &uac_min_se); 
19242          if (rtn != 0) {
19243                transmit_response_reliable(p, "400 Min-SE Invalid Syntax", req);
19244                      p->invitestate = INV_COMPLETED;
19245                      if (!p->lastinvite) {
19246                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
19247             }
19248             res = -1;
19249             goto request_invite_cleanup;
19250          }
19251       }
19252 
19253       dlg_min_se = st_get_se(p, FALSE);
19254       switch (st_get_mode(p)) {
19255       case SESSION_TIMER_MODE_ACCEPT:
19256       case SESSION_TIMER_MODE_ORIGINATE:
19257          if (uac_max_se > 0 && uac_max_se < dlg_min_se) {
19258             transmit_response_with_minse(p, "422 Session Interval Too Small", req, dlg_min_se);
19259             p->invitestate = INV_COMPLETED;
19260             if (!p->lastinvite) {
19261                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
19262             }
19263             res = -1;
19264             goto request_invite_cleanup;
19265          }
19266 
19267          p->stimer->st_active_peer_ua = TRUE;
19268          st_active = TRUE;
19269          if (st_ref == SESSION_TIMER_REFRESHER_AUTO) {
19270             st_ref = st_get_refresher(p);
19271          }
19272 
19273          if (uac_max_se > 0) {
19274             int dlg_max_se = st_get_se(p, TRUE);
19275             if (dlg_max_se >= uac_min_se) {
19276                st_interval = (uac_max_se < dlg_max_se) ? uac_max_se : dlg_max_se;
19277             } else {
19278                st_interval = uac_max_se;
19279             }
19280          } else {
19281             /* Set to default max value */
19282             st_interval = global_max_se;
19283          }
19284          break;
19285 
19286       case SESSION_TIMER_MODE_REFUSE:
19287          if (p->reqsipoptions & SIP_OPT_TIMER) {
19288             transmit_response_with_unsupported(p, "420 Option Disabled", req, required);
19289             ast_log(LOG_WARNING, "Received SIP INVITE with supported but disabled option: %s\n", required);
19290             p->invitestate = INV_COMPLETED;
19291             if (!p->lastinvite) {
19292                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
19293             }
19294             res = -1;
19295             goto request_invite_cleanup;
19296          }
19297          break;
19298 
19299       default:
19300          ast_log(LOG_ERROR, "Internal Error %d at %s:%d\n", st_get_mode(p), __FILE__, __LINE__);
19301          break;
19302       }
19303    } else {
19304       /* The UAC did not request session-timers.  Asterisk (UAS), will now decide
19305       (based on session-timer-mode in sip.conf) whether to run session-timers for
19306       this session or not. */
19307       switch (st_get_mode(p)) {
19308       case SESSION_TIMER_MODE_ORIGINATE:
19309          st_active = TRUE;
19310          st_interval = st_get_se(p, TRUE);
19311          st_ref = SESSION_TIMER_REFRESHER_UAS;
19312          p->stimer->st_active_peer_ua = FALSE;
19313          break;
19314 
19315       default:
19316          break;
19317       }
19318    }
19319 
19320    if (reinvite == 0) {
19321       /* Session-Timers: Start session refresh timer based on negotiation/config */
19322       if (st_active == TRUE) {
19323          p->stimer->st_active   = TRUE;
19324          p->stimer->st_interval = st_interval;
19325          p->stimer->st_ref      = st_ref;
19326          start_session_timer(p);
19327       }
19328    } else {
19329       if (p->stimer->st_active == TRUE) {
19330          /* Session-Timers:  A re-invite request sent within a dialog will serve as 
19331          a refresh request, no matter whether the re-invite was sent for refreshing 
19332          the session or modifying it.*/
19333          ast_debug (2, "Restarting session-timers on a refresh - %s\n", p->callid);
19334 
19335          /* The UAC may be adjusting the session-timers mid-session */
19336          if (st_interval > 0) {
19337             p->stimer->st_interval = st_interval;
19338             p->stimer->st_ref      = st_ref;
19339          }
19340 
19341          restart_session_timer(p);
19342          if (p->stimer->st_expirys > 0) {
19343             p->stimer->st_expirys--;
19344          }
19345       }
19346    }
19347 
19348    if (!req->ignore && p)
19349       p->lastinvite = seqno;
19350 
19351    if (replace_id) {    /* Attended transfer or call pickup - we're the target */
19352       /* Go and take over the target call */
19353       if (sipdebug)
19354          ast_debug(4, "Sending this call to the invite/replcaes handler %s\n", p->callid);
19355       res = handle_invite_replaces(p, req, debug, seqno, sin, nounlock);
19356       refer_locked = 0;
19357       goto request_invite_cleanup;
19358 
19359    }
19360 
19361 
19362    if (c) { /* We have a call  -either a new call or an old one (RE-INVITE) */
19363       enum ast_channel_state c_state = c->_state;
19364 
19365       if (c_state != AST_STATE_UP && reinvite &&
19366          (p->invitestate == INV_TERMINATED || p->invitestate == INV_CONFIRMED)) {
19367          /* If these conditions are true, and the channel is still in the 'ringing'
19368           * state, then this likely means that we have a situation where the initial
19369           * INVITE transaction has completed *but* the channel's state has not yet been
19370           * changed to UP. The reason this could happen is if the reinvite is received
19371           * on the SIP socket prior to an application calling ast_read on this channel
19372           * to read the answer frame we earlier queued on it. In this case, the reinvite
19373           * is completely legitimate so we need to handle this the same as if the channel 
19374           * were already UP. Thus we are purposely falling through to the AST_STATE_UP case.
19375           */
19376          c_state = AST_STATE_UP;
19377       }
19378 
19379       switch(c_state) {
19380       case AST_STATE_DOWN:
19381          ast_debug(2, "%s: New call is still down.... Trying... \n", c->name);
19382          transmit_provisional_response(p, "100 Trying", req, 0);
19383          p->invitestate = INV_PROCEEDING;
19384          ast_setstate(c, AST_STATE_RING);
19385          if (strcmp(p->exten, ast_pickup_ext())) { /* Call to extension -start pbx on this call */
19386             enum ast_pbx_result result;
19387 
19388             result = ast_pbx_start(c);
19389 
19390             switch(result) {
19391             case AST_PBX_FAILED:
19392                ast_log(LOG_WARNING, "Failed to start PBX :(\n");
19393                p->invitestate = INV_COMPLETED;
19394                transmit_response_reliable(p, "503 Unavailable", req);
19395                break;
19396             case AST_PBX_CALL_LIMIT:
19397                ast_log(LOG_WARNING, "Failed to start PBX (call limit reached) \n");
19398                p->invitestate = INV_COMPLETED;
19399                transmit_response_reliable(p, "480 Temporarily Unavailable", req);
19400                break;
19401             case AST_PBX_SUCCESS:
19402                /* nothing to do */
19403                break;
19404             }
19405 
19406             if (result) {
19407 
19408                /* Unlock locks so ast_hangup can do its magic */
19409                ast_channel_unlock(c);
19410                sip_pvt_unlock(p);
19411                ast_hangup(c);
19412                sip_pvt_lock(p);
19413                c = NULL;
19414             }
19415          } else { /* Pickup call in call group */
19416             ast_channel_unlock(c);
19417             *nounlock = 1;
19418             if (ast_pickup_call(c)) {
19419                ast_log(LOG_NOTICE, "Nothing to pick up for %s\n", p->callid);
19420                transmit_response_reliable(p, "503 Unavailable", req);
19421                sip_alreadygone(p);
19422                /* Unlock locks so ast_hangup can do its magic */
19423                sip_pvt_unlock(p);
19424                c->hangupcause = AST_CAUSE_CALL_REJECTED;
19425             } else {
19426                sip_pvt_unlock(p);
19427                ast_setstate(c, AST_STATE_DOWN);
19428                c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
19429             }
19430             p->invitestate = INV_COMPLETED;
19431             ast_hangup(c);
19432             sip_pvt_lock(p);
19433             c = NULL;
19434          }
19435          break;
19436       case AST_STATE_RING:
19437          transmit_provisional_response(p, "100 Trying", req, 0);
19438          p->invitestate = INV_PROCEEDING;
19439          break;
19440       case AST_STATE_RINGING:
19441          transmit_provisional_response(p, "180 Ringing", req, 0);
19442          p->invitestate = INV_PROCEEDING;
19443          break;
19444       case AST_STATE_UP:
19445          ast_debug(2, "%s: This call is UP.... \n", c->name);
19446 
19447          transmit_response(p, "100 Trying", req);
19448 
19449          if (p->t38.state == T38_PEER_REINVITE) {
19450             p->t38id = ast_sched_add(sched, 5000, sip_t38_abort, dialog_ref(p, "passing dialog ptr into sched structure based on t38id for sip_t38_abort."));
19451          } else if (p->t38.state == T38_ENABLED) {
19452             ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
19453             transmit_response_with_t38_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ?  XMIT_UNRELIABLE : XMIT_CRITICAL)));
19454          } else if (p->t38.state == T38_DISABLED) {
19455             /* If this is not a re-invite or something to ignore - it's critical */
19456             ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
19457             transmit_response_with_sdp(p, "200 OK", req, (reinvite ? XMIT_RELIABLE : (req->ignore ?  XMIT_UNRELIABLE : XMIT_CRITICAL)), p->session_modify == TRUE ? FALSE:TRUE); 
19458          }
19459 
19460          p->invitestate = INV_TERMINATED;
19461          break;
19462       default:
19463          ast_log(LOG_WARNING, "Don't know how to handle INVITE in state %d\n", c->_state);
19464          transmit_response(p, "100 Trying", req);
19465          break;
19466       }
19467    } else {
19468       if (p && (p->autokillid == -1)) {
19469          const char *msg;
19470 
19471          if (!p->jointcapability)
19472             msg = "488 Not Acceptable Here (codec error)";
19473          else {
19474             ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n");
19475             msg = "503 Unavailable";
19476          }
19477          transmit_response_reliable(p, msg, req);
19478          p->invitestate = INV_COMPLETED;
19479          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
19480       }
19481    }
19482 
19483 request_invite_cleanup:
19484 
19485    if (refer_locked && p->refer && p->refer->refer_call) {
19486       sip_pvt_unlock(p->refer->refer_call);
19487       if (p->refer->refer_call->owner) {
19488          ast_channel_unlock(p->refer->refer_call->owner);
19489       }
19490    }
19491 
19492    return res;
19493 }

static int handle_request_message ( struct sip_pvt p,
struct sip_request req 
) [static]

Handle incoming MESSAGE request.

Definition at line 20246 of file chan_sip.c.

References ast_verbose, sip_request::debug, sip_request::ignore, receive_message(), and transmit_response().

Referenced by handle_incoming().

20247 {
20248    if (!req->ignore) {
20249       if (req->debug)
20250          ast_verbose("Receiving message!\n");
20251       receive_message(p, req);
20252    } else
20253       transmit_response(p, "202 Accepted", req);
20254    return 1;
20255 }

static int handle_request_notify ( struct sip_pvt p,
struct sip_request req,
struct sockaddr_in *  sin,
int  seqno,
char *  e 
) [static]

Handle incoming notifications.

Definition at line 18169 of file chan_sip.c.

References ast_debug, ast_log(), ast_skip_blanks(), buf, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, FALSE, get_header(), get_msg_text(), sip_pvt::lastinvite, LOG_NOTICE, LOG_WARNING, sip_scheddestroy(), transmit_response(), and TRUE.

Referenced by handle_incoming().

18170 {
18171    /* This is mostly a skeleton for future improvements */
18172    /* Mostly created to return proper answers on notifications on outbound REFER's */
18173    int res = 0;
18174    const char *event = get_header(req, "Event");
18175    char *eventid = NULL;
18176    char *sep;
18177 
18178    if( (sep = strchr(event, ';')) ) {  /* XXX bug here - overwriting string ? */
18179       *sep++ = '\0';
18180       eventid = sep;
18181    }
18182    
18183    if (sipdebug)
18184       ast_debug(2, "Got NOTIFY Event: %s\n", event);
18185 
18186    if (strcmp(event, "refer")) {
18187       /* We don't understand this event. */
18188       /* Here's room to implement incoming voicemail notifications :-) */
18189       transmit_response(p, "489 Bad event", req);
18190       res = -1;
18191    } else {
18192       /* Save nesting depth for now, since there might be other events we will
18193          support in the future */
18194 
18195       /* Handle REFER notifications */
18196 
18197       char buf[1024];
18198       char *cmd, *code;
18199       int respcode;
18200       int success = TRUE;
18201 
18202       /* EventID for each transfer... EventID is basically the REFER cseq 
18203 
18204        We are getting notifications on a call that we transfered
18205        We should hangup when we are getting a 200 OK in a sipfrag
18206        Check if we have an owner of this event */
18207       
18208       /* Check the content type */
18209       if (strncasecmp(get_header(req, "Content-Type"), "message/sipfrag", strlen("message/sipfrag"))) {
18210          /* We need a sipfrag */
18211          transmit_response(p, "400 Bad request", req);
18212          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
18213          return -1;
18214       }
18215 
18216       /* Get the text of the attachment */
18217       if (get_msg_text(buf, sizeof(buf), req, TRUE)) {
18218          ast_log(LOG_WARNING, "Unable to retrieve attachment from NOTIFY %s\n", p->callid);
18219          transmit_response(p, "400 Bad request", req);
18220          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
18221          return -1;
18222       }
18223 
18224       /*
18225       From the RFC...
18226       A minimal, but complete, implementation can respond with a single
18227       NOTIFY containing either the body:
18228          SIP/2.0 100 Trying
18229       
18230       if the subscription is pending, the body:
18231          SIP/2.0 200 OK
18232       if the reference was successful, the body:
18233          SIP/2.0 503 Service Unavailable
18234       if the reference failed, or the body:
18235          SIP/2.0 603 Declined
18236 
18237       if the REFER request was accepted before approval to follow the
18238       reference could be obtained and that approval was subsequently denied
18239       (see Section 2.4.7).
18240       
18241       If there are several REFERs in the same dialog, we need to
18242       match the ID of the event header...
18243       */
18244       ast_debug(3, "* SIP Transfer NOTIFY Attachment: \n---%s\n---\n", buf);
18245       cmd = ast_skip_blanks(buf);
18246       code = cmd;
18247       /* We are at SIP/2.0 */
18248       while(*code && (*code > 32)) {   /* Search white space */
18249          code++;
18250       }
18251       *code++ = '\0';
18252       code = ast_skip_blanks(code);
18253       sep = code;
18254       sep++;
18255       while(*sep && (*sep > 32)) {  /* Search white space */
18256          sep++;
18257       }
18258       *sep++ = '\0';       /* Response string */
18259       respcode = atoi(code);
18260       switch (respcode) {
18261       case 100:   /* Trying: */
18262       case 101:   /* dialog establishment */
18263          /* Don't do anything yet */
18264          break;
18265       case 183:   /* Ringing: */
18266          /* Don't do anything yet */
18267          break;
18268       case 200:   /* OK: The new call is up, hangup this call */
18269          /* Hangup the call that we are replacing */
18270          break;
18271       case 301: /* Moved permenantly */
18272       case 302: /* Moved temporarily */
18273          /* Do we get the header in the packet in this case? */
18274          success = FALSE;
18275          break;
18276       case 503:   /* Service Unavailable: The new call failed */
18277             /* Cancel transfer, continue the call */
18278          success = FALSE;
18279          break;
18280       case 603:   /* Declined: Not accepted */
18281             /* Cancel transfer, continue the current call */
18282          success = FALSE;
18283          break;
18284       }
18285       if (!success) {
18286          ast_log(LOG_NOTICE, "Transfer failed. Sorry. Nothing further to do with this call\n");
18287       }
18288       
18289       /* Confirm that we received this packet */
18290       transmit_response(p, "200 OK", req);
18291    };
18292 
18293    if (!p->lastinvite)
18294       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
18295 
18296    return res;
18297 }

static int handle_request_options ( struct sip_pvt p,
struct sip_request req 
) [static]

Handle incoming OPTIONS request An OPTIONS request should be answered like an INVITE from the same UA, including SDP.

XXX get_destination assumes we're already authenticated. This means that a request from a known device (peer) will end up in the wrong context if this is out-of-dialog. However, we want to handle OPTIONS as light as possible, so we might want to have a configuration option whether we care or not. Some devices use this for testing capabilities, which means that we need to match device to answer with proper capabilities (including SDP).

Todo:
Fix handle_request_options device handling with optional authentication (this needs to be fixed in 1.4 as well)

Definition at line 18302 of file chan_sip.c.

References ast_shutting_down(), ast_string_field_set, ast_strlen_zero(), build_contact(), context, sip_pvt::context, DEFAULT_TRANS_TIMEOUT, get_destination(), sip_pvt::lastinvite, sip_scheddestroy(), and transmit_response_with_allow().

Referenced by handle_incoming().

18303 {
18304    int res;
18305 
18306    /*! XXX get_destination assumes we're already authenticated. This means that a request from
18307       a known device (peer) will end up in the wrong context if this is out-of-dialog.
18308       However, we want to handle OPTIONS as light as possible, so we might want to have
18309       a configuration option whether we care or not. Some devices use this for testing
18310       capabilities, which means that we need to match device to answer with proper 
18311       capabilities (including SDP).
18312       \todo Fix handle_request_options device handling with optional authentication
18313          (this needs to be fixed in 1.4 as well)
18314    */
18315 
18316    if (p->lastinvite) {
18317       /* if this is a request in an active dialog, just confirm that the dialog exists. */
18318       transmit_response_with_allow(p, "200 OK", req, 0);
18319       return 0;
18320    }
18321 
18322    res = get_destination(p, req);
18323    build_contact(p);
18324 
18325    if (ast_strlen_zero(p->context))
18326       ast_string_field_set(p, context, default_context);
18327 
18328    if (ast_shutting_down())
18329       transmit_response_with_allow(p, "503 Unavailable", req, 0);
18330    else if (res < 0)
18331       transmit_response_with_allow(p, "404 Not Found", req, 0);
18332    else 
18333       transmit_response_with_allow(p, "200 OK", req, 0);
18334 
18335    /* Destroy if this OPTIONS was the opening request, but not if
18336       it's in the middle of a normal call flow. */
18337    sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
18338 
18339    return res;
18340 }

static int handle_request_refer ( struct sip_pvt p,
struct sip_request req,
int  debug,
int  seqno,
int *  nounlock 
) [static]

Definition at line 19660 of file chan_sip.c.

References sip_pvt::allowtransfer, append_history, ast_async_goto(), ast_bridged_channel(), AST_CAUSE_NORMAL_CLEARING, ast_channel_unlock, ast_clear_flag, AST_CONTROL_UNHOLD, ast_debug, AST_LIST_EMPTY, ast_parking_ext(), ast_queue_control(), ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verbose, sip_refer::attendedtransfer, sip_pvt::callid, sip_dual::chan1, sip_dual::chan2, check_sip_domain(), context, sip_pvt::context, copy_request(), sip_request::data, sip_request::debug, EVENT_FLAG_CALL, FALSE, sip_pvt::flags, get_refer_info(), ast_channel::hangupcause, sip_request::ignore, local_attended_transfer(), sip_refer::localtransfer, manager_event, ast_channel::name, sip_pvt::needdestroy, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, REFER_200OK, REFER_FAILED, REFER_SENT, sip_refer::refer_to, sip_refer::refer_to_context, sip_refer::refer_to_domain, sip_refer::referred_by, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, sip_dual::req, sip_alreadygone(), SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, SIP_OUTGOING, sip_park(), sip_refer_allocate(), SIPBUFSIZE, sip_refer::status, TRANSFER_CLOSED, transmit_notify_with_sipfrag(), transmit_response(), TRUE, and ast_channel::uniqueid.

Referenced by handle_incoming().

19661 {
19662    struct sip_dual current;   /* Chan1: Call between asterisk and transferer */
19663                /* Chan2: Call between asterisk and transferee */
19664 
19665    int res = 0;
19666    current.req.data = NULL;
19667 
19668    if (req->debug)
19669       ast_verbose("Call %s got a SIP call transfer from %s: (REFER)!\n", p->callid, ast_test_flag(&p->flags[0], SIP_OUTGOING) ? "callee" : "caller");
19670 
19671    if (!p->owner) {
19672       /* This is a REFER outside of an existing SIP dialog */
19673       /* We can't handle that, so decline it */
19674       ast_debug(3, "Call %s: Declined REFER, outside of dialog...\n", p->callid);
19675       transmit_response(p, "603 Declined (No dialog)", req);
19676       if (!req->ignore) {
19677          append_history(p, "Xfer", "Refer failed. Outside of dialog.");
19678          sip_alreadygone(p);
19679          p->needdestroy = 1;
19680       }
19681       return 0;
19682    }  
19683 
19684 
19685    /* Check if transfer is allowed from this device */
19686    if (p->allowtransfer == TRANSFER_CLOSED ) {
19687       /* Transfer not allowed, decline */
19688       transmit_response(p, "603 Declined (policy)", req);
19689       append_history(p, "Xfer", "Refer failed. Allowtransfer == closed.");
19690       /* Do not destroy SIP session */
19691       return 0;
19692    }
19693 
19694    if (!req->ignore && ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
19695       /* Already have a pending REFER */  
19696       transmit_response(p, "491 Request pending", req);
19697       append_history(p, "Xfer", "Refer failed. Request pending.");
19698       return 0;
19699    }
19700 
19701    /* Allocate memory for call transfer data */
19702    if (!p->refer && !sip_refer_allocate(p)) {
19703       transmit_response(p, "500 Internal Server Error", req);
19704       append_history(p, "Xfer", "Refer failed. Memory allocation error.");
19705       return -3;
19706    }
19707 
19708    res = get_refer_info(p, req); /* Extract headers */
19709 
19710    p->refer->status = REFER_SENT;
19711 
19712    if (res != 0) {
19713       switch (res) {
19714       case -2: /* Syntax error */
19715          transmit_response(p, "400 Bad Request (Refer-to missing)", req);
19716          append_history(p, "Xfer", "Refer failed. Refer-to missing.");
19717          if (req->debug)
19718             ast_debug(1, "SIP transfer to black hole can't be handled (no refer-to: )\n");
19719          break;
19720       case -3:
19721          transmit_response(p, "603 Declined (Non sip: uri)", req);
19722          append_history(p, "Xfer", "Refer failed. Non SIP uri");
19723          if (req->debug)
19724             ast_debug(1, "SIP transfer to non-SIP uri denied\n");
19725          break;
19726       default:
19727          /* Refer-to extension not found, fake a failed transfer */
19728          transmit_response(p, "202 Accepted", req);
19729          append_history(p, "Xfer", "Refer failed. Bad extension.");
19730          transmit_notify_with_sipfrag(p, seqno, "404 Not found", TRUE);
19731          ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
19732          if (req->debug)
19733             ast_debug(1, "SIP transfer to bad extension: %s\n", p->refer->refer_to);
19734          break;
19735       } 
19736       return 0;
19737    }
19738    if (ast_strlen_zero(p->context))
19739       ast_string_field_set(p, context, default_context);
19740 
19741    /* If we do not support SIP domains, all transfers are local */
19742    if (allow_external_domains && check_sip_domain(p->refer->refer_to_domain, NULL, 0)) {
19743       p->refer->localtransfer = 1;
19744       if (sipdebug)
19745          ast_debug(3, "This SIP transfer is local : %s\n", p->refer->refer_to_domain);
19746    } else if (AST_LIST_EMPTY(&domain_list) || check_sip_domain(p->refer->refer_to_domain, NULL, 0)) {
19747       /* This PBX doesn't bother with SIP domains or domain is local, so this transfer is local */
19748       p->refer->localtransfer = 1;
19749    } else if (sipdebug)
19750          ast_debug(3, "This SIP transfer is to a remote SIP extension (remote domain %s)\n", p->refer->refer_to_domain);
19751    
19752    /* Is this a repeat of a current request? Ignore it */
19753    /* Don't know what else to do right now. */
19754    if (req->ignore) 
19755       return res;
19756 
19757    /* If this is a blind transfer, we have the following
19758    channels to work with:
19759    - chan1, chan2: The current call between transferer and transferee (2 channels)
19760    - target_channel: A new call from the transferee to the target (1 channel)
19761    We need to stay tuned to what happens in order to be able
19762    to bring back the call to the transferer */
19763 
19764    /* If this is a attended transfer, we should have all call legs within reach:
19765    - chan1, chan2: The call between the transferer and transferee (2 channels)
19766    - target_channel, targetcall_pvt: The call between the transferer and the target (2 channels)
19767    We want to bridge chan2 with targetcall_pvt!
19768    
19769    The replaces call id in the refer message points
19770    to the call leg between Asterisk and the transferer.
19771    So we need to connect the target and the transferee channel
19772    and hangup the two other channels silently 
19773    
19774    If the target is non-local, the call ID could be on a remote
19775    machine and we need to send an INVITE with replaces to the
19776    target. We basically handle this as a blind transfer
19777    and let the sip_call function catch that we need replaces
19778    header in the INVITE.
19779    */
19780 
19781 
19782    /* Get the transferer's channel */
19783    current.chan1 = p->owner;
19784 
19785    /* Find the other part of the bridge (2) - transferee */
19786    current.chan2 = ast_bridged_channel(current.chan1);
19787    
19788    if (sipdebug)
19789       ast_debug(3, "SIP %s transfer: Transferer channel %s, transferee channel %s\n", p->refer->attendedtransfer ? "attended" : "blind", current.chan1->name, current.chan2 ? current.chan2->name : "<none>");
19790 
19791    if (!current.chan2 && !p->refer->attendedtransfer) {
19792       /* No bridged channel, propably IVR or echo or similar... */
19793       /* Guess we should masquerade or something here */
19794       /* Until we figure it out, refuse transfer of such calls */
19795       if (sipdebug)
19796          ast_debug(3, "Refused SIP transfer on non-bridged channel.\n");
19797       p->refer->status = REFER_FAILED;
19798       append_history(p, "Xfer", "Refer failed. Non-bridged channel.");
19799       transmit_response(p, "603 Declined", req);
19800       return -1;
19801    }
19802 
19803    if (current.chan2) {
19804       if (sipdebug)
19805          ast_debug(4, "Got SIP transfer, applying to bridged peer '%s'\n", current.chan2->name);
19806 
19807       ast_queue_control(current.chan1, AST_CONTROL_UNHOLD);
19808    }
19809 
19810    ast_set_flag(&p->flags[0], SIP_GOTREFER); 
19811 
19812    /* Attended transfer: Find all call legs and bridge transferee with target*/
19813    if (p->refer->attendedtransfer) {
19814       if ((res = local_attended_transfer(p, &current, req, seqno)))
19815          return res; /* We're done with the transfer */
19816       /* Fall through for remote transfers that we did not find locally */
19817       if (sipdebug)
19818          ast_debug(4, "SIP attended transfer: Still not our call - generating INVITE with replaces\n");
19819       /* Fallthrough if we can't find the call leg internally */
19820    }
19821 
19822 
19823    /* Parking a call */
19824    if (p->refer->localtransfer && !strcmp(p->refer->refer_to, ast_parking_ext())) {
19825       /* Must release c's lock now, because it will not longer be accessible after the transfer! */
19826       *nounlock = 1;
19827       ast_channel_unlock(current.chan1);
19828       copy_request(&current.req, req);
19829       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
19830       p->refer->status = REFER_200OK;
19831       append_history(p, "Xfer", "REFER to call parking.");
19832       manager_event(EVENT_FLAG_CALL, "Transfer", "TransferMethod: SIP\r\nTransferType: Blind\r\nChannel: %s\r\nUniqueid: %s\r\nSIP-Callid: %s\r\nTargetChannel: %s\r\nTargetUniqueid: %s\r\nTransferExten: %s\r\nTransfer2Parking: Yes\r\n",
19833          current.chan1->name,
19834          current.chan1->uniqueid,
19835          p->callid,
19836          current.chan2->name,
19837          current.chan2->uniqueid,
19838          p->refer->refer_to);
19839       if (sipdebug)
19840          ast_debug(4, "SIP transfer to parking: trying to park %s. Parked by %s\n", current.chan2->name, current.chan1->name);
19841       sip_park(current.chan2, current.chan1, req, seqno);
19842       return res;
19843    } 
19844 
19845    /* Blind transfers and remote attended xfers */
19846    transmit_response(p, "202 Accepted", req);
19847 
19848    if (current.chan1 && current.chan2) {
19849       ast_debug(3, "chan1->name: %s\n", current.chan1->name);
19850       pbx_builtin_setvar_helper(current.chan1, "BLINDTRANSFER", current.chan2->name);
19851    }
19852    if (current.chan2) {
19853       pbx_builtin_setvar_helper(current.chan2, "BLINDTRANSFER", current.chan1->name);
19854       pbx_builtin_setvar_helper(current.chan2, "SIPDOMAIN", p->refer->refer_to_domain);
19855       pbx_builtin_setvar_helper(current.chan2, "SIPTRANSFER", "yes");
19856       /* One for the new channel */
19857       pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER", "yes");
19858       /* Attended transfer to remote host, prepare headers for the INVITE */
19859       if (p->refer->referred_by) 
19860          pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REFERER", p->refer->referred_by);
19861    }
19862    /* Generate a Replaces string to be used in the INVITE during attended transfer */
19863    if (!ast_strlen_zero(p->refer->replaces_callid)) {
19864       char tempheader[SIPBUFSIZE];
19865       snprintf(tempheader, sizeof(tempheader), "%s%s%s%s%s", p->refer->replaces_callid, 
19866             p->refer->replaces_callid_totag ? ";to-tag=" : "", 
19867             p->refer->replaces_callid_totag, 
19868             p->refer->replaces_callid_fromtag ? ";from-tag=" : "",
19869             p->refer->replaces_callid_fromtag);
19870       if (current.chan2)
19871          pbx_builtin_setvar_helper(current.chan2, "_SIPTRANSFER_REPLACES", tempheader);
19872    }
19873    /* Must release lock now, because it will not longer
19874       be accessible after the transfer! */
19875    *nounlock = 1;
19876    ast_channel_unlock(current.chan1);
19877 
19878    /* Connect the call */
19879 
19880    /* FAKE ringing if not attended transfer */
19881    if (!p->refer->attendedtransfer)
19882       transmit_notify_with_sipfrag(p, seqno, "183 Ringing", FALSE); 
19883       
19884    /* For blind transfer, this will lead to a new call */
19885    /* For attended transfer to remote host, this will lead to
19886       a new SIP call with a replaces header, if the dial plan allows it 
19887    */
19888    if (!current.chan2) {
19889       /* We have no bridge, so we're talking with Asterisk somehow */
19890       /* We need to masquerade this call */
19891       /* What to do to fix this situation:
19892          * Set up the new call in a new channel 
19893          * Let the new channel masq into this channel
19894          Please add that code here :-)
19895       */
19896       p->refer->status = REFER_FAILED;
19897       transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable (can't handle one-legged xfers)", TRUE);
19898       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
19899       append_history(p, "Xfer", "Refer failed (only bridged calls).");
19900       return -1;
19901    }
19902    ast_set_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
19903 
19904 
19905    /* For blind transfers, move the call to the new extensions. For attended transfers on multiple
19906       servers - generate an INVITE with Replaces. Either way, let the dial plan decided  */
19907    res = ast_async_goto(current.chan2, p->refer->refer_to_context, p->refer->refer_to, 1);
19908 
19909    if (!res) {
19910       manager_event(EVENT_FLAG_CALL, "Transfer", "TransferMethod: SIP\r\nTransferType: Blind\r\nChannel: %s\r\nUniqueid: %s\r\nSIP-Callid: %s\r\nTargetChannel: %s\r\nTargetUniqueid: %s\r\nTransferExten: %s\r\nTransferContext: %s\r\n",
19911          current.chan1->name,
19912          current.chan1->uniqueid,
19913          p->callid,
19914          current.chan2->name,
19915          current.chan2->uniqueid,
19916          p->refer->refer_to, p->refer->refer_to_context);
19917       /* Success  - we have a new channel */
19918       ast_debug(3, "%s transfer succeeded. Telling transferer.\n", p->refer->attendedtransfer? "Attended" : "Blind");
19919       transmit_notify_with_sipfrag(p, seqno, "200 Ok", TRUE);
19920       if (p->refer->localtransfer)
19921          p->refer->status = REFER_200OK;
19922       if (p->owner)
19923          p->owner->hangupcause = AST_CAUSE_NORMAL_CLEARING;
19924       append_history(p, "Xfer", "Refer succeeded.");
19925       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
19926       /* Do not hangup call, the other side do that when we say 200 OK */
19927       /* We could possibly implement a timer here, auto congestion */
19928       res = 0;
19929    } else {
19930       ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Don't delay hangup */
19931       ast_debug(3, "%s transfer failed. Resuming original call.\n", p->refer->attendedtransfer? "Attended" : "Blind");
19932       append_history(p, "Xfer", "Refer failed.");
19933       /* Failure of some kind */
19934       p->refer->status = REFER_FAILED;
19935       transmit_notify_with_sipfrag(p, seqno, "503 Service Unavailable", TRUE);
19936       ast_clear_flag(&p->flags[0], SIP_GOTREFER);  
19937       res = -1;
19938    }
19939    return res;
19940 }

static int handle_request_register ( struct sip_pvt p,
struct sip_request req,
struct sockaddr_in *  sin,
char *  e 
) [static]

Handle incoming REGISTER request.

Definition at line 20594 of file chan_sip.c.

References append_history, ast_debug, ast_inet_ntoa(), ast_log(), AUTH_ACL_FAILED, AUTH_BAD_TRANSPORT, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, sip_pvt::callid, check_via(), copy_request(), DEFAULT_TRANS_TIMEOUT, get_header(), sip_pvt::initreq, LOG_NOTICE, sip_request::method, register_verify(), sip_methods, and sip_scheddestroy().

Referenced by handle_incoming().

20595 {
20596    enum check_auth_result res;
20597 
20598    /* Use this as the basis */
20599    copy_request(&p->initreq, req);
20600    if (sipdebug)
20601       ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
20602    check_via(p, req);
20603    if ((res = register_verify(p, sin, req, e)) < 0) {
20604       const char *reason;
20605 
20606       switch (res) {
20607       case AUTH_SECRET_FAILED:
20608          reason = "Wrong password";
20609          break;
20610       case AUTH_USERNAME_MISMATCH:
20611          reason = "Username/auth name mismatch";
20612          break;
20613       case AUTH_NOT_FOUND:
20614          reason = "No matching peer found";
20615          break;
20616       case AUTH_UNKNOWN_DOMAIN:
20617          reason = "Not a local domain";
20618          break;
20619       case AUTH_PEER_NOT_DYNAMIC:
20620          reason = "Peer is not supposed to register";
20621          break;
20622       case AUTH_ACL_FAILED:
20623          reason = "Device does not match ACL";
20624          break;
20625       case AUTH_BAD_TRANSPORT:
20626          reason = "Device not configured to use this transport type";
20627          break;
20628       default:
20629          reason = "Unknown failure";
20630          break;
20631       }
20632       ast_log(LOG_NOTICE, "Registration from '%s' failed for '%s' - %s\n",
20633          get_header(req, "To"), ast_inet_ntoa(sin->sin_addr),
20634          reason);
20635       append_history(p, "RegRequest", "Failed : Account %s : %s", get_header(req, "To"), reason);
20636    } else
20637       append_history(p, "RegRequest", "Succeeded : Account %s", get_header(req, "To"));
20638 
20639    if (res < 1) {
20640       /* Destroy the session, but keep us around for just a bit in case they don't
20641          get our 200 OK */
20642       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
20643    }
20644    return res;
20645 }

static int handle_request_subscribe ( struct sip_pvt p,
struct sip_request req,
struct sockaddr_in *  sin,
int  seqno,
char *  e 
) [static]

Handle incoming SUBSCRIBE request.

Definition at line 20270 of file chan_sip.c.

References add_peer_mwi_subs(), ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock(), ao2_t_iterator_next, ao2_t_ref, ao2_unlock(), append_history, ast_debug, AST_EXTENSION_REMOVED, ast_extension_state(), ast_extension_state2str(), ast_extension_state_add(), ast_extension_state_del(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_set_flag, ast_strdupa, ast_string_field_build, ast_strlen_zero(), ast_test_flag, ast_verbose, AUTH_CHALLENGE_SENT, AUTH_FAKE_AUTH, sip_pvt::autokillid, build_contact(), build_route(), sip_pvt::callid, cb_extensionstate(), check_user_full(), check_via(), sip_pvt::context, copy_request(), CPIM_PIDF_XML, sip_request::debug, DIALOG_INFO_XML, dialog_ref(), dialog_unlink_all(), dialog_unref(), dialogs, sip_pvt::dialogver, sip_pvt::expiry, sip_pvt::exten, FALSE, sip_peer::flags, sip_pvt::flags, get_destination(), get_header(), gettag(), sip_request::headers, sip_request::ignore, sip_pvt::initreq, sip_pvt::lastinvite, sip_pvt::laststate, LOG_NOTICE, LOG_WARNING, sip_peer::mailboxes, make_our_tag(), sip_request::method, sip_peer::mwipvt, sip_peer::name, sip_pvt::needdestroy, NONE, parse_ok_contact(), PIDF_XML, ref_peer(), sip_pvt::relatedpeer, sip_pvt::sa, sip_cancel_destroy(), sip_methods, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_SUBSCRIBEMWIONLY, sip_pvt_lock, sip_pvt_unlock, sip_scheddestroy(), sip_send_mwi_to_peer(), SIP_SUBSCRIBE, sip_pvt::stateid, sip_pvt::subscribecontext, sip_pvt::subscribed, sip_pvt::subscribeuri, sip_pvt::tag, cfsip_methods::text, transmit_fake_auth_response(), transmit_response(), transmit_response_reliable(), transmit_state_notify(), TRUE, unref_peer(), sip_pvt::useragent, sip_pvt::username, XMIT_UNRELIABLE, and XPIDF_XML.

Referenced by handle_incoming().

20271 {
20272    int gotdest = 0;
20273    int res = 0;
20274    int firststate = AST_EXTENSION_REMOVED;
20275    struct sip_peer *authpeer = NULL;
20276    const char *eventheader = get_header(req, "Event");   /* Get Event package name */
20277    const char *acceptheader = get_header(req, "Accept");
20278    int resubscribe = (p->subscribed != NONE);
20279    char *temp, *event;
20280    struct ao2_iterator i;
20281 
20282    if (p->initreq.headers) {  
20283       /* We already have a dialog */
20284       if (p->initreq.method != SIP_SUBSCRIBE) {
20285          /* This is a SUBSCRIBE within another SIP dialog, which we do not support */
20286          /* For transfers, this could happen, but since we haven't seen it happening, let us just refuse this */
20287          transmit_response(p, "403 Forbidden (within dialog)", req);
20288          /* Do not destroy session, since we will break the call if we do */
20289          ast_debug(1, "Got a subscription within the context of another call, can't handle that - %s (Method %s)\n", p->callid, sip_methods[p->initreq.method].text);
20290          return 0;
20291       } else if (req->debug) {
20292          if (resubscribe)
20293             ast_debug(1, "Got a re-subscribe on existing subscription %s\n", p->callid);
20294          else
20295             ast_debug(1, "Got a new subscription %s (possibly with auth)\n", p->callid);
20296       }
20297    }
20298 
20299    /* Check if we have a global disallow setting on subscriptions. 
20300       if so, we don't have to check peer settings after auth, which saves a lot of processing
20301    */
20302    if (!global_allowsubscribe) {
20303       transmit_response(p, "403 Forbidden (policy)", req);
20304       p->needdestroy = 1;
20305       return 0;
20306    }
20307 
20308    if (!req->ignore && !resubscribe) { /* Set up dialog, new subscription */
20309       const char *to = get_header(req, "To");
20310       char totag[128];
20311 
20312       /* Check to see if a tag was provided, if so this is actually a resubscription of a dialog we no longer know about */
20313       if (!ast_strlen_zero(to) && gettag(req, "To", totag, sizeof(totag))) {
20314          if (req->debug)
20315             ast_verbose("Received resubscription for a dialog we no longer know about. Telling remote side to subscribe again.\n");
20316          transmit_response(p, "481 Subscription does not exist", req);
20317          p->needdestroy = 1;
20318          return 0;
20319       }
20320 
20321       /* Use this as the basis */
20322       if (req->debug)
20323          ast_verbose("Creating new subscription\n");
20324 
20325       copy_request(&p->initreq, req);
20326       if (sipdebug)
20327          ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
20328       check_via(p, req);
20329       build_route(p, req, 0);
20330    } else if (req->debug && req->ignore)
20331       ast_verbose("Ignoring this SUBSCRIBE request\n");
20332 
20333    /* Find parameters to Event: header value and remove them for now */
20334    if (ast_strlen_zero(eventheader)) {
20335       transmit_response(p, "489 Bad Event", req);
20336       ast_debug(2, "Received SIP subscribe for unknown event package: <none>\n");
20337       p->needdestroy = 1;
20338       return 0;
20339    }
20340 
20341    if ( (strchr(eventheader, ';'))) {
20342       event = ast_strdupa(eventheader);   /* Since eventheader is a const, we can't change it */
20343       temp = strchr(event, ';');       
20344       *temp = '\0';           /* Remove any options for now */
20345                      /* We might need to use them later :-) */
20346    } else
20347       event = (char *) eventheader;    /* XXX is this legal ? */
20348 
20349    /* Handle authentication */
20350    res = check_user_full(p, req, SIP_SUBSCRIBE, e, 0, sin, &authpeer);
20351    /* if an authentication response was sent, we are done here */
20352    if (res == AUTH_CHALLENGE_SENT)  /* authpeer = NULL here */
20353       return 0;
20354    if (res < 0) {
20355       if (res == AUTH_FAKE_AUTH) {
20356          ast_log(LOG_NOTICE, "Sending fake auth rejection for device %s\n", get_header(req, "From"));
20357          transmit_fake_auth_response(p, SIP_SUBSCRIBE, req, XMIT_UNRELIABLE);
20358       } else {
20359          ast_log(LOG_NOTICE, "Failed to authenticate device %s for SUBSCRIBE\n", get_header(req, "From"));
20360          transmit_response_reliable(p, "403 Forbidden", req);
20361       }
20362       p->needdestroy = 1;
20363       return 0;
20364    }
20365 
20366    /* At this point, authpeer cannot be NULL. Remember we hold a reference,
20367     * so we must release it when done.
20368     * XXX must remove all the checks for authpeer == NULL.
20369     */
20370 
20371    /* Check if this device  is allowed to subscribe at all */
20372    if (!ast_test_flag(&p->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
20373       transmit_response(p, "403 Forbidden (policy)", req);
20374       p->needdestroy = 1;
20375       if (authpeer)
20376          unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 1)");
20377       return 0;
20378    }
20379 
20380    if (strcmp(event, "message-summary")) {
20381       /* Get destination right away */
20382       gotdest = get_destination(p, NULL);
20383    }
20384 
20385    /* Get full contact header - this needs to be used as a request URI in NOTIFY's */
20386    parse_ok_contact(p, req);
20387 
20388    build_contact(p);
20389    if (gotdest) {
20390       transmit_response(p, "404 Not Found", req);
20391       p->needdestroy = 1;
20392       if (authpeer)
20393          unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)");
20394       return 0;
20395    }
20396 
20397    /* Initialize tag for new subscriptions */   
20398    if (ast_strlen_zero(p->tag))
20399       make_our_tag(p->tag, sizeof(p->tag));
20400 
20401    if (!strcmp(event, "presence") || !strcmp(event, "dialog")) { /* Presence, RFC 3842 */
20402       unsigned int pidf_xml;
20403 
20404       if (authpeer)  /* We do not need the authpeer any more */
20405          unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 2)");
20406 
20407       /* Header from Xten Eye-beam Accept: multipart/related, application/rlmi+xml, application/pidf+xml, application/xpidf+xml */
20408 
20409       pidf_xml = strstr(acceptheader, "application/pidf+xml") ? 1 : 0;
20410 
20411       /* Older versions of Polycom firmware will claim pidf+xml, but really
20412        * they only support xpidf+xml. */
20413       if (pidf_xml && strstr(p->useragent, "Polycom")) {
20414          p->subscribed = XPIDF_XML;
20415       } else if (pidf_xml) {
20416          p->subscribed = PIDF_XML;         /* RFC 3863 format */
20417       } else if (strstr(acceptheader, "application/dialog-info+xml")) {
20418          p->subscribed = DIALOG_INFO_XML;
20419          /* IETF draft: draft-ietf-sipping-dialog-package-05.txt */
20420       } else if (strstr(acceptheader, "application/cpim-pidf+xml")) {
20421          p->subscribed = CPIM_PIDF_XML;    /* RFC 3863 format */
20422       } else if (strstr(acceptheader, "application/xpidf+xml")) {
20423          p->subscribed = XPIDF_XML;        /* Early pre-RFC 3863 format with MSN additions (Microsoft Messenger) */
20424       } else if (ast_strlen_zero(acceptheader)) {
20425          if (p->subscribed == NONE) { /* if the subscribed field is not already set, and there is no accept header... */
20426             transmit_response(p, "489 Bad Event", req);
20427   
20428             ast_log(LOG_WARNING, "SUBSCRIBE failure: no Accept header: pvt: stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
20429                p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
20430             p->needdestroy = 1;
20431             return 0;
20432          }
20433          /* if p->subscribed is non-zero, then accept is not obligatory; according to rfc 3265 section 3.1.3, at least.
20434             so, we'll just let it ride, keeping the value from a previous subscription, and not abort the subscription */
20435       } else {
20436          /* Can't find a format for events that we know about */
20437          char mybuf[200];
20438          snprintf(mybuf, sizeof(mybuf), "489 Bad Event (format %s)", acceptheader);
20439          transmit_response(p, mybuf, req);
20440  
20441          ast_log(LOG_WARNING, "SUBSCRIBE failure: unrecognized format: '%s' pvt: subscribed: %d, stateid: %d, laststate: %d, dialogver: %d, subscribecont: '%s', subscribeuri: '%s'\n",
20442             acceptheader, (int)p->subscribed, p->stateid, p->laststate, p->dialogver, p->subscribecontext, p->subscribeuri);
20443          p->needdestroy = 1;
20444          return 0;
20445       }
20446    } else if (!strcmp(event, "message-summary")) { 
20447       if (!ast_strlen_zero(acceptheader) && strcmp(acceptheader, "application/simple-message-summary")) {
20448          /* Format requested that we do not support */
20449          transmit_response(p, "406 Not Acceptable", req);
20450          ast_debug(2, "Received SIP mailbox subscription for unknown format: %s\n", acceptheader);
20451          p->needdestroy = 1;
20452          if (authpeer)
20453             unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 3)");
20454          return 0;
20455       }
20456       /* Looks like they actually want a mailbox status 
20457         This version of Asterisk supports mailbox subscriptions
20458         The subscribed URI needs to exist in the dial plan
20459         In most devices, this is configurable to the voicemailmain extension you use
20460       */
20461       if (!authpeer || AST_LIST_EMPTY(&authpeer->mailboxes)) {
20462          transmit_response(p, "404 Not found (no mailbox)", req);
20463          p->needdestroy = 1;
20464          ast_log(LOG_NOTICE, "Received SIP subscribe for peer without mailbox: %s\n", authpeer->name);
20465          if (authpeer)
20466             unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 4)");
20467          return 0;
20468       }
20469 
20470       p->subscribed = MWI_NOTIFICATION;
20471       if (ast_test_flag(&authpeer->flags[1], SIP_PAGE2_SUBSCRIBEMWIONLY)) {
20472          add_peer_mwi_subs(authpeer);
20473       }
20474       if (authpeer->mwipvt && authpeer->mwipvt != p) {   /* Destroy old PVT if this is a new one */
20475          /* We only allow one subscription per peer */
20476          dialog_unlink_all(authpeer->mwipvt, TRUE, TRUE);
20477          authpeer->mwipvt = dialog_unref(authpeer->mwipvt, "unref dialog authpeer->mwipvt");
20478          /* sip_destroy(authpeer->mwipvt); */
20479       }
20480       if (authpeer->mwipvt)
20481          dialog_unref(authpeer->mwipvt, "Unref previously stored mwipvt dialog pointer");
20482       authpeer->mwipvt = dialog_ref(p, "setting peers' mwipvt to p");      /* Link from peer to pvt UH- should this be dialog_ref()? */
20483       if (p->relatedpeer)
20484          unref_peer(p->relatedpeer, "Unref previously stored relatedpeer ptr");
20485       p->relatedpeer = ref_peer(authpeer, "setting dialog's relatedpeer pointer");  /* already refcounted...Link from pvt to peer UH- should this be dialog_ref()? */
20486       /* Do not release authpeer here */
20487    } else { /* At this point, Asterisk does not understand the specified event */
20488       transmit_response(p, "489 Bad Event", req);
20489       ast_debug(2, "Received SIP subscribe for unknown event package: %s\n", event);
20490       p->needdestroy = 1;
20491       if (authpeer)
20492          unref_peer(authpeer, "unref_peer, from handle_request_subscribe (authpeer 5)");
20493       return 0;
20494    }
20495 
20496    /* Add subscription for extension state from the PBX core */
20497    if (p->subscribed != MWI_NOTIFICATION && !resubscribe) {
20498       if (p->stateid > -1) {
20499          ast_extension_state_del(p->stateid, cb_extensionstate);
20500          /* we need to dec the refcount, now that the extensionstate is removed */
20501          dialog_unref(p, "the extensionstate containing this dialog ptr was deleted");
20502       }
20503       p->stateid = ast_extension_state_add(p->context, p->exten, cb_extensionstate, dialog_ref(p,"copying dialog ptr into extension state struct"));
20504    }
20505 
20506    if (!req->ignore && p)
20507       p->lastinvite = seqno;
20508    if (p && !p->needdestroy) {
20509       p->expiry = atoi(get_header(req, "Expires"));
20510 
20511       /* check if the requested expiry-time is within the approved limits from sip.conf */
20512       if (p->expiry > max_expiry)
20513          p->expiry = max_expiry;
20514       if (p->expiry < min_expiry && p->expiry > 0)
20515          p->expiry = min_expiry;
20516 
20517       if (sipdebug) {
20518          if (p->subscribed == MWI_NOTIFICATION && p->relatedpeer)
20519             ast_debug(2, "Adding subscription for mailbox notification - peer %s\n", p->relatedpeer->name);
20520          else
20521             ast_debug(2, "Adding subscription for extension %s context %s for peer %s\n", p->exten, p->context, p->username);
20522       }
20523       if (p->autokillid > -1 && sip_cancel_destroy(p))   /* Remove subscription expiry for renewals */
20524          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
20525       if (p->expiry > 0)
20526          sip_scheddestroy(p, (p->expiry + 10) * 1000);   /* Set timer for destruction of call at expiration */
20527 
20528       if (p->subscribed == MWI_NOTIFICATION) {
20529          ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
20530          transmit_response(p, "200 OK", req);
20531          if (p->relatedpeer) {   /* Send first notification */
20532             ao2_lock(p->relatedpeer); /* was WRLOCK */
20533             sip_send_mwi_to_peer(p->relatedpeer, NULL, 0);
20534             ao2_unlock(p->relatedpeer);
20535          }
20536       } else {
20537          struct sip_pvt *p_old;
20538 
20539          if ((firststate = ast_extension_state(NULL, p->context, p->exten)) < 0) {
20540 
20541             ast_log(LOG_NOTICE, "Got SUBSCRIBE for extension %s@%s from %s, but there is no hint for that extension.\n", p->exten, p->context, ast_inet_ntoa(p->sa.sin_addr));
20542             transmit_response(p, "404 Not found", req);
20543             p->needdestroy = 1;
20544             return 0;
20545          }
20546          ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
20547          transmit_response(p, "200 OK", req);
20548          transmit_state_notify(p, firststate, 1, FALSE); /* Send first notification */
20549          append_history(p, "Subscribestatus", "%s", ast_extension_state2str(firststate));
20550          /* hide the 'complete' exten/context in the refer_to field for later display */
20551          ast_string_field_build(p, subscribeuri, "%s@%s", p->exten, p->context);
20552 
20553          /* remove any old subscription from this peer for the same exten/context,
20554          as the peer has obviously forgotten about it and it's wasteful to wait
20555          for it to expire and send NOTIFY messages to the peer only to have them
20556          ignored (or generate errors)
20557          */
20558          i = ao2_iterator_init(dialogs, 0);
20559          while ((p_old = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
20560             if (p_old == p) {
20561                ao2_t_ref(p_old, -1, "toss dialog ptr from iterator_next before continue");
20562                continue;
20563             }
20564             if (p_old->initreq.method != SIP_SUBSCRIBE) {
20565                ao2_t_ref(p_old, -1, "toss dialog ptr from iterator_next before continue");
20566                continue;
20567             }
20568             if (p_old->subscribed == NONE) {
20569                ao2_t_ref(p_old, -1, "toss dialog ptr from iterator_next before continue");
20570                continue;
20571             }
20572             sip_pvt_lock(p_old);
20573             if (!strcmp(p_old->username, p->username)) {
20574                if (!strcmp(p_old->exten, p->exten) &&
20575                    !strcmp(p_old->context, p->context)) {
20576                   p_old->needdestroy = 1;
20577                   sip_pvt_unlock(p_old);
20578                   ao2_t_ref(p_old, -1, "toss dialog ptr from iterator_next before break");
20579                   break;
20580                }
20581             }
20582             sip_pvt_unlock(p_old);
20583             ao2_t_ref(p_old, -1, "toss dialog ptr from iterator_next");
20584          }
20585          ao2_iterator_destroy(&i);
20586       }
20587       if (!p->expiry)
20588          p->needdestroy = 1;
20589    }
20590    return 1;
20591 }

static void handle_response ( struct sip_pvt p,
int  resp,
char *  rest,
struct sip_request req,
int  seqno 
) [static]

Handle SIP response in dialogue.

Note:
only called by handle_incoming

Note:
SIP is incapable of performing a hairpin call, which is yet another failure of not having a layer 2 (again, YAY IETF for thinking ahead). So we treat this as a call forward and hope we end up at the right place...

Definition at line 17460 of file chan_sip.c.

References __sip_ack(), __sip_semi_ack(), append_history, AST_CAUSE_PROTOCOL_ERROR, ast_clear_flag, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, ast_debug, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_queue_hangup_with_cause(), ast_set_flag, ast_skip_blanks(), ast_skip_nonblanks(), ast_strdupa, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verb, ast_verbose, ast_channel::call_forward, cb_extensionstate(), sip_pvt::context, sip_request::debug, do_proxy_auth(), sip_pvt::exten, FALSE, find_sdp(), find_sip_method(), sip_pvt::flags, get_header(), gettag(), handle_response_invite(), handle_response_notify(), handle_response_peerpoke(), handle_response_refer(), handle_response_register(), hangup_sip2cause(), ast_channel::hangupcause, sip_request::ignore, sip_pvt::laststate, LOG_NOTICE, LOG_WARNING, MAX_AUTHTRIES, sip_pvt::method, msg, sip_pvt::needdestroy, sip_pvt::owner, parse_moved_contact(), sip_pvt::pendinginvite, process_sdp(), sip_pvt::refer, sip_pvt::relatedpeer, SDP_T38_NONE, SIP_ACK, sip_alreadygone(), SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_INFO, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_NOTIFY, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PAGE2_STATECHANGEQUEUE, SIP_REFER, SIP_REGISTER, SIP_SUBSCRIBE, SIP_TRANSPORT_UDP, sip_pvt::socket, stop_media_flows(), sip_pvt::subscribed, text, sip_pvt::theirtag, transmit_request(), sip_socket::type, and XMIT_UNRELIABLE.

17461 {
17462    struct ast_channel *owner;
17463    int sipmethod;
17464    int res = 1;
17465    const char *c = get_header(req, "Cseq");
17466    /* GCC 4.2 complains if I try to cast c as a char * when passing it to ast_skip_nonblanks, so make a copy of it */
17467    char *c_copy = ast_strdupa(c);
17468    /* Skip the Cseq and its subsequent spaces */
17469    const char *msg = ast_skip_blanks(ast_skip_nonblanks(c_copy));
17470 
17471    if (!msg)
17472       msg = "";
17473 
17474    sipmethod = find_sip_method(msg);
17475 
17476    owner = p->owner;
17477    if (owner) 
17478       owner->hangupcause = hangup_sip2cause(resp);
17479 
17480    if (p->socket.type == SIP_TRANSPORT_UDP) {
17481       int ack_res;
17482 
17483       /* Acknowledge whatever it is destined for */
17484       if ((resp >= 100) && (resp <= 199)) {
17485          ack_res = __sip_semi_ack(p, seqno, 0, sipmethod);
17486       } else {
17487          ack_res = __sip_ack(p, seqno, 0, sipmethod);
17488       }
17489 
17490       if (ack_res == FALSE) {
17491          append_history(p, "Ignore", "Ignoring this retransmit\n");
17492          return;
17493       }
17494    }
17495 
17496    /* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */
17497    if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) 
17498       p->pendinginvite = 0;
17499 
17500    /* Get their tag if we haven't already */
17501    if (ast_strlen_zero(p->theirtag) || (resp >= 200)) {
17502       char tag[128];
17503 
17504       gettag(req, "To", tag, sizeof(tag));
17505       ast_string_field_set(p, theirtag, tag);
17506    }
17507    /* This needs to be configurable on a channel/peer level,
17508       not mandatory for all communication. Sadly enough, NAT implementations
17509       are not so stable so we can always rely on these headers. 
17510       Temporarily disabled, while waiting for fix.
17511       Fix assigned to Rizzo :-)
17512    */
17513    /* check_via_response(p, req); */
17514 
17515    /* RFC 3261 Section 15 specifies that if we receive a 408 or 481
17516     * in response to a BYE, then we should end the current dialog
17517     * and session.  It is known that at least one phone manufacturer
17518     * potentially will send a 404 in response to a BYE, so we'll be
17519     * liberal in what we accept and end the dialog and session if we
17520     * receive any of those responses to a BYE.
17521     */
17522    if ((resp == 404 || resp == 408 || resp == 481) && sipmethod == SIP_BYE) {
17523       p->needdestroy = 1;
17524       return;
17525    }
17526 
17527    if (p->relatedpeer && p->method == SIP_OPTIONS) {
17528       /* We don't really care what the response is, just that it replied back. 
17529          Well, as long as it's not a 100 response...  since we might
17530          need to hang around for something more "definitive" */
17531       if (resp != 100)
17532          handle_response_peerpoke(p, resp, req);
17533    } else if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
17534       switch(resp) {
17535       case 100:   /* 100 Trying */
17536       case 101:   /* 101 Dialog establishment */
17537          if (sipmethod == SIP_INVITE) 
17538             handle_response_invite(p, resp, rest, req, seqno);
17539          break;
17540       case 183:   /* 183 Session Progress */
17541          if (sipmethod == SIP_INVITE) 
17542             handle_response_invite(p, resp, rest, req, seqno);
17543          break;
17544       case 180:   /* 180 Ringing */
17545          if (sipmethod == SIP_INVITE) 
17546             handle_response_invite(p, resp, rest, req, seqno);
17547          break;
17548       case 182:       /* 182 Queued */
17549          if (sipmethod == SIP_INVITE)
17550             handle_response_invite(p, resp, rest, req, seqno);
17551          break;
17552       case 200:   /* 200 OK */
17553          p->authtries = 0; /* Reset authentication counter */
17554          if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO) {
17555             /* We successfully transmitted a message 
17556                or a video update request in INFO */
17557             /* Nothing happens here - the message is inside a dialog */
17558          } else if (sipmethod == SIP_INVITE) {
17559             handle_response_invite(p, resp, rest, req, seqno);
17560          } else if (sipmethod == SIP_NOTIFY) {
17561             handle_response_notify(p, resp, rest, req, seqno);
17562          } else if (sipmethod == SIP_REGISTER) 
17563             res = handle_response_register(p, resp, rest, req, seqno);
17564          else if (sipmethod == SIP_BYE) {    /* Ok, we're ready to go */
17565             p->needdestroy = 1;
17566             ast_clear_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
17567          } else if (sipmethod == SIP_SUBSCRIBE) {
17568             ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
17569          }
17570          break;
17571       case 202:   /* Transfer accepted */
17572          if (sipmethod == SIP_REFER) 
17573             handle_response_refer(p, resp, rest, req, seqno);
17574          break;
17575       case 401: /* Not www-authorized on SIP method */
17576       case 407: /* Proxy auth required */
17577          if (sipmethod == SIP_INVITE)
17578             handle_response_invite(p, resp, rest, req, seqno);
17579          else if (sipmethod == SIP_NOTIFY)
17580             handle_response_notify(p, resp, rest, req, seqno);
17581          else if (sipmethod == SIP_REFER)
17582             handle_response_refer(p, resp, rest, req, seqno);
17583          else if (p->registry && sipmethod == SIP_REGISTER)
17584             res = handle_response_register(p, resp, rest, req, seqno);
17585          else if (sipmethod == SIP_BYE) {
17586             if (p->options)
17587                p->options->auth_type = resp;
17588             if (ast_strlen_zero(p->authname)) {
17589                ast_log(LOG_WARNING, "Asked to authenticate %s, to %s:%d but we have no matching peer!\n",
17590                      msg, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
17591                p->needdestroy = 1;
17592             } else if ((p->authtries == MAX_AUTHTRIES) || do_proxy_auth(p, req, resp,  sipmethod, 0)) {
17593                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
17594                p->needdestroy = 1;
17595             }
17596          } else {
17597             ast_log(LOG_WARNING, "Got authentication request (%d) on %s to '%s'\n", resp, sip_methods[sipmethod].text, get_header(req, "To"));
17598             p->needdestroy = 1;
17599          }
17600          break;
17601       case 403: /* Forbidden - we failed authentication */
17602          if (sipmethod == SIP_INVITE)
17603             handle_response_invite(p, resp, rest, req, seqno);
17604          else if (p->registry && sipmethod == SIP_REGISTER) 
17605             res = handle_response_register(p, resp, rest, req, seqno);
17606          else {
17607             ast_log(LOG_WARNING, "Forbidden - maybe wrong password on authentication for %s\n", msg);
17608             p->needdestroy = 1;
17609          }
17610          break;
17611       case 404: /* Not found */
17612          if (p->registry && sipmethod == SIP_REGISTER)
17613             res = handle_response_register(p, resp, rest, req, seqno);
17614          else if (sipmethod == SIP_INVITE)
17615             handle_response_invite(p, resp, rest, req, seqno);
17616          else if (owner)
17617             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
17618          break;
17619       case 423: /* Interval too brief */
17620          if (sipmethod == SIP_REGISTER)
17621             res = handle_response_register(p, resp, rest, req, seqno);
17622          break;
17623       case 408: /* Request timeout - terminate dialog */
17624          if (sipmethod == SIP_INVITE)
17625             handle_response_invite(p, resp, rest, req, seqno);
17626          else if (sipmethod == SIP_REGISTER) 
17627             res = handle_response_register(p, resp, rest, req, seqno);
17628          else if (sipmethod == SIP_BYE) {
17629             p->needdestroy = 1;
17630             ast_debug(4, "Got timeout on bye. Thanks for the answer. Now, kill this call\n");
17631          } else {
17632             if (owner)
17633                ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
17634             p->needdestroy = 1;
17635          }
17636          break;
17637 
17638       case 422: /* Session-Timers: Session Interval Too Small */
17639          if (sipmethod == SIP_INVITE) {
17640             handle_response_invite(p, resp, rest, req, seqno);
17641          }
17642          break;
17643 
17644       case 481: /* Call leg does not exist */
17645          if (sipmethod == SIP_INVITE) {
17646             handle_response_invite(p, resp, rest, req, seqno);
17647          } else if (sipmethod == SIP_REFER) {
17648             handle_response_refer(p, resp, rest, req, seqno);
17649          } else if (sipmethod == SIP_BYE) {
17650             /* The other side has no transaction to bye,
17651             just assume it's all right then */
17652             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
17653          } else if (sipmethod == SIP_CANCEL) {
17654             /* The other side has no transaction to cancel,
17655             just assume it's all right then */
17656             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
17657          } else {
17658             ast_log(LOG_WARNING, "Remote host can't match request %s to call '%s'. Giving up.\n", sip_methods[sipmethod].text, p->callid);
17659             /* Guessing that this is not an important request */
17660          }
17661          break;
17662       case 487:
17663          if (sipmethod == SIP_INVITE)
17664             handle_response_invite(p, resp, rest, req, seqno);
17665          break;
17666       case 415: /* Unsupported media type */
17667       case 488: /* Not acceptable here - codec error */
17668       case 606: /* Not Acceptable */
17669          if (sipmethod == SIP_INVITE)
17670             handle_response_invite(p, resp, rest, req, seqno);
17671          break;
17672       case 491: /* Pending */
17673          if (sipmethod == SIP_INVITE)
17674             handle_response_invite(p, resp, rest, req, seqno);
17675          else {
17676             ast_debug(1, "Got 491 on %s, unspported. Call ID %s\n", sip_methods[sipmethod].text, p->callid);
17677             p->needdestroy = 1;
17678          }
17679          break;
17680       case 501: /* Not Implemented */
17681          if (sipmethod == SIP_INVITE)
17682             handle_response_invite(p, resp, rest, req, seqno);
17683          else if (sipmethod == SIP_REFER)
17684             handle_response_refer(p, resp, rest, req, seqno);
17685          else
17686             ast_log(LOG_WARNING, "Host '%s' does not implement '%s'\n", ast_inet_ntoa(p->sa.sin_addr), msg);
17687          break;
17688       case 603:   /* Declined transfer */
17689          if (sipmethod == SIP_REFER) {
17690             handle_response_refer(p, resp, rest, req, seqno);
17691             break;
17692          }
17693          /* Fallthrough */
17694       default:
17695          if ((resp >= 300) && (resp < 700)) {
17696             /* Fatal response */
17697             if ((resp != 487))
17698                ast_verb(3, "Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr));
17699    
17700             if (sipmethod == SIP_INVITE)
17701                stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
17702 
17703             /* XXX Locking issues?? XXX */
17704             switch(resp) {
17705             case 300: /* Multiple Choices */
17706             case 301: /* Moved permanently */
17707             case 302: /* Moved temporarily */
17708             case 305: /* Use Proxy */
17709                parse_moved_contact(p, req);
17710                /* Fall through */
17711             case 486: /* Busy here */
17712             case 600: /* Busy everywhere */
17713             case 603: /* Decline */
17714                if (p->owner)
17715                   ast_queue_control(p->owner, AST_CONTROL_BUSY);
17716                break;
17717             case 482: /*!
17718                \note SIP is incapable of performing a hairpin call, which
17719                is yet another failure of not having a layer 2 (again, YAY
17720                 IETF for thinking ahead).  So we treat this as a call
17721                 forward and hope we end up at the right place... */
17722                ast_debug(1, "Hairpin detected, setting up call forward for what it's worth\n");
17723                if (p->owner)
17724                   ast_string_field_build(p->owner, call_forward,
17725                                "Local/%s@%s", p->username, p->context);
17726                /* Fall through */
17727             case 480: /* Temporarily Unavailable */
17728             case 404: /* Not Found */
17729             case 410: /* Gone */
17730             case 400: /* Bad Request */
17731             case 500: /* Server error */
17732                if (sipmethod == SIP_REFER) {
17733                   handle_response_refer(p, resp, rest, req, seqno);
17734                   break;
17735                }
17736                /* Fall through */
17737             case 502: /* Bad gateway */
17738             case 503: /* Service Unavailable */
17739             case 504: /* Server Timeout */
17740                if (owner)
17741                   ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
17742                break;
17743             default:
17744                /* Send hangup */ 
17745                if (owner && sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO && sipmethod != SIP_BYE)
17746                   ast_queue_hangup_with_cause(p->owner, AST_CAUSE_PROTOCOL_ERROR);
17747                break;
17748             }
17749             /* ACK on invite */
17750             if (sipmethod == SIP_INVITE) 
17751                transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
17752             if (sipmethod != SIP_MESSAGE && sipmethod != SIP_INFO) 
17753                sip_alreadygone(p);
17754             if (!p->owner)
17755                p->needdestroy = 1;
17756          } else if ((resp >= 100) && (resp < 200)) {
17757             if (sipmethod == SIP_INVITE) {
17758                if (!req->ignore && sip_cancel_destroy(p))
17759                   ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
17760                if (find_sdp(req))
17761                   process_sdp(p, req, SDP_T38_NONE);
17762                if (p->owner) {
17763                   /* Queue a progress frame */
17764                   ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
17765                }
17766             }
17767          } else
17768             ast_log(LOG_NOTICE, "Dont know how to handle a %d %s response from %s\n", resp, rest, p->owner ? p->owner->name : ast_inet_ntoa(p->sa.sin_addr));
17769       }
17770    } else { 
17771       /* Responses to OUTGOING SIP requests on INCOMING calls 
17772          get handled here. As well as out-of-call message responses */
17773       if (req->debug)
17774          ast_verbose("SIP Response message for INCOMING dialog %s arrived\n", msg);
17775 
17776       if (sipmethod == SIP_INVITE && resp == 200) {
17777          /* Tags in early session is replaced by the tag in 200 OK, which is 
17778          the final reply to our INVITE */
17779          char tag[128];
17780 
17781          gettag(req, "To", tag, sizeof(tag));
17782          ast_string_field_set(p, theirtag, tag);
17783       }
17784 
17785       switch(resp) {
17786       case 200:
17787          if (sipmethod == SIP_INVITE) {
17788             handle_response_invite(p, resp, rest, req, seqno);
17789          } else if (sipmethod == SIP_CANCEL) {
17790             ast_debug(1, "Got 200 OK on CANCEL\n");
17791 
17792             /* Wait for 487, then destroy */
17793          } else if (sipmethod == SIP_NOTIFY) {
17794             /* They got the notify, this is the end */
17795             if (p->owner) {
17796                if (p->refer) {
17797                   ast_debug(1, "Got 200 OK on NOTIFY for transfer\n");
17798                } else
17799                   ast_log(LOG_WARNING, "Notify answer on an owned channel?\n");
17800                /* ast_queue_hangup(p->owner); Disabled */
17801             } else {
17802                if (!p->subscribed && !p->refer)
17803                   p->needdestroy = 1;
17804                if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) {
17805                   /* Ready to send the next state we have on queue */
17806                   ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
17807                   cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p);
17808                }
17809             }
17810          } else if (sipmethod == SIP_BYE)
17811             p->needdestroy = 1;
17812          else if (sipmethod == SIP_MESSAGE || sipmethod == SIP_INFO)
17813             /* We successfully transmitted a message or
17814                a video update request in INFO */
17815             ;
17816          else if (sipmethod == SIP_BYE) 
17817             /* Ok, we're ready to go */
17818             p->needdestroy = 1;
17819          break;
17820       case 202:   /* Transfer accepted */
17821          if (sipmethod == SIP_REFER) 
17822             handle_response_refer(p, resp, rest, req, seqno);
17823          break;
17824       case 401:   /* www-auth */
17825       case 407:
17826          if (sipmethod == SIP_REFER)
17827             handle_response_refer(p, resp, rest, req, seqno);
17828          else if (sipmethod == SIP_INVITE) 
17829             handle_response_invite(p, resp, rest, req, seqno);
17830          else if (sipmethod == SIP_BYE) {
17831             if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, sipmethod, 0)) {
17832                ast_log(LOG_NOTICE, "Failed to authenticate on %s to '%s'\n", msg, get_header(&p->initreq, "From"));
17833                p->needdestroy = 1;
17834             }
17835          }
17836          break;
17837       case 481:   /* Call leg does not exist */
17838          if (sipmethod == SIP_INVITE) {
17839             /* Re-invite failed */
17840             handle_response_invite(p, resp, rest, req, seqno);
17841          } else if (sipmethod == SIP_BYE) {
17842             p->needdestroy = 1;
17843          } else if (sipdebug) {
17844             ast_debug(1, "Remote host can't match request %s to call '%s'. Giving up\n", sip_methods[sipmethod].text, p->callid);
17845          }
17846          break;
17847       case 501: /* Not Implemented */
17848          if (sipmethod == SIP_INVITE) 
17849             handle_response_invite(p, resp, rest, req, seqno);
17850          else if (sipmethod == SIP_REFER) 
17851             handle_response_refer(p, resp, rest, req, seqno);
17852          break;
17853       case 603:   /* Declined transfer */
17854          if (sipmethod == SIP_REFER) {
17855             handle_response_refer(p, resp, rest, req, seqno);
17856             break;
17857          }
17858          /* Fallthrough */
17859       default: /* Errors without handlers */
17860          if ((resp >= 100) && (resp < 200)) {
17861             if (sipmethod == SIP_INVITE) {   /* re-invite */
17862                if (!req->ignore && sip_cancel_destroy(p))
17863                   ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
17864             }
17865          }
17866          if ((resp >= 300) && (resp < 700)) {
17867             if ((resp != 487))
17868                ast_verb(3, "Incoming call: Got SIP response %d \"%s\" back from %s\n", resp, rest, ast_inet_ntoa(p->sa.sin_addr));
17869             switch(resp) {
17870             case 415: /* Unsupported media type */
17871             case 488: /* Not acceptable here - codec error */
17872             case 603: /* Decline */
17873             case 500: /* Server error */
17874             case 502: /* Bad gateway */
17875             case 503: /* Service Unavailable */
17876             case 504: /* Server timeout */
17877 
17878                /* re-invite failed */
17879                if (sipmethod == SIP_INVITE && sip_cancel_destroy(p))
17880                   ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
17881                break;
17882             }
17883          }
17884          break;
17885       }
17886    }
17887 }

static void handle_response_invite ( struct sip_pvt p,
int  resp,
char *  rest,
struct sip_request req,
int  seqno 
) [static]

Handle SIP response to INVITE dialogue.

Definition at line 16833 of file chan_sip.c.

References ast_channel::_state, sip_pvt::alreadygone, append_history, AST_CAUSE_NORMAL_CLEARING, AST_CONTROL_ANSWER, AST_CONTROL_CONGESTION, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, ast_debug, ast_log(), ast_null_frame, ast_queue_control(), ast_queue_frame(), ast_queue_hangup_with_cause(), ast_random(), ast_rtp_set_rtptimers_onhold(), ast_sched_add(), AST_SCHED_DEL_UNREF, ast_set_flag, ast_setstate(), AST_STATE_RINGING, AST_STATE_UP, ast_string_field_set, ast_strlen_zero(), ast_test_flag, sip_invite_param::auth_type, sip_pvt::authtries, build_route(), sip_pvt::callid, change_t38_state(), check_pendings(), DEC_CALL_LIMIT, DEC_CALL_RINGING, DEFAULT_TRANS_TIMEOUT, dialog_ref(), dialog_unref(), do_proxy_auth(), EVENT_FLAG_SYSTEM, FALSE, find_sdp(), sip_pvt::flags, sip_pvt::fullcontact, get_header(), sip_request::ignore, sip_pvt::initid, sip_pvt::initreq, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, INV_TERMINATED, sip_pvt::invitestate, LOG_NOTICE, LOG_WARNING, manager_event, MAX_AUTHTRIES, ast_channel::name, sip_pvt::needdestroy, sip_pvt::options, sip_pvt::outgoing_call, sip_pvt::owner, parse_ok_contact(), parse_session_expires(), sip_pvt::peername, sip_pvt::pendinginvite, proc_422_rsp(), process_sdp(), sched, SDP_T38_ACCEPT, SDP_T38_NONE, SESSION_TIMER_MODE_ORIGINATE, SESSION_TIMER_MODE_REFUSE, SESSION_TIMER_REFRESHER_AUTO, SESSION_TIMER_REFRESHER_UAC, SESSION_TIMER_REFRESHER_UAS, set_address_from_contact(), SIP_ACK, sip_alreadygone(), sip_cancel_destroy(), SIP_INVITE, SIP_OUTGOING, SIP_PAGE2_DIALOG_ESTABLISHED, SIP_PENDINGBYE, sip_reinvite_retry(), sip_scheddestroy(), sip_st_dlg::st_active, sip_st_dlg::st_active_peer_ua, st_get_mode(), sip_st_dlg::st_interval, sip_st_dlg::st_ref, start_session_timer(), t38properties::state, sip_pvt::stimer, sip_pvt::t38, T38_DISABLED, T38_LOCAL_REINVITE, sip_pvt::theirtag, transmit_reinvite_with_sdp(), transmit_request(), TRUE, sip_pvt::udptl, ast_channel::uniqueid, update_call_counter(), sip_pvt::waitid, XMIT_ERROR, and XMIT_UNRELIABLE.

Referenced by handle_response().

16834 {
16835    int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING);
16836    int res = 0;
16837    int xmitres = 0;
16838    int reinvite = (p->owner && p->owner->_state == AST_STATE_UP);
16839    char *p_hdrval;
16840    int rtn;
16841 
16842    if (reinvite)
16843       ast_debug(4, "SIP response %d to RE-invite on %s call %s\n", resp, outgoing ? "outgoing" : "incoming", p->callid);
16844    else
16845       ast_debug(4, "SIP response %d to standard invite\n", resp);
16846 
16847    if (p->alreadygone) { /* This call is already gone */
16848       ast_debug(1, "Got response on call that is already terminated: %s (ignoring)\n", p->callid);
16849       return;
16850    }
16851 
16852    /* Acknowledge sequence number - This only happens on INVITE from SIP-call */
16853    /* Don't auto congest anymore since we've gotten something useful back */
16854    AST_SCHED_DEL_UNREF(sched, p->initid, dialog_unref(p, "when you delete the initid sched, you should dec the refcount for the stored dialog ptr"));
16855 
16856    /* RFC3261 says we must treat every 1xx response (but not 100)
16857       that we don't recognize as if it was 183.
16858    */
16859    if (resp > 100 && resp < 200 && resp!=101 && resp != 180 && resp != 182 && resp != 183)
16860       resp = 183;
16861 
16862    /* Any response between 100 and 199 is PROCEEDING */
16863    if (resp >= 100 && resp < 200 && p->invitestate == INV_CALLING)
16864       p->invitestate = INV_PROCEEDING;
16865  
16866    /* Final response, not 200 ? */
16867    if (resp >= 300 && (p->invitestate == INV_CALLING || p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA ))
16868       p->invitestate = INV_COMPLETED;
16869    
16870    /* Final response, clear out pending invite */
16871    if ((resp == 200 || resp >= 300) && p->pendinginvite && seqno == p->pendinginvite)
16872       p->pendinginvite = 0;
16873 
16874    switch (resp) {
16875    case 100:   /* Trying */
16876    case 101:   /* Dialog establishment */
16877       if (!req->ignore && p->invitestate != INV_CANCELLED && sip_cancel_destroy(p))
16878          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
16879       check_pendings(p);
16880       break;
16881 
16882    case 180:   /* 180 Ringing */
16883    case 182:       /* 182 Queued */
16884       if (!req->ignore && p->invitestate != INV_CANCELLED && sip_cancel_destroy(p))
16885          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
16886       if (!req->ignore && p->owner) {
16887          ast_queue_control(p->owner, AST_CONTROL_RINGING);
16888          if (p->owner->_state != AST_STATE_UP) {
16889             ast_setstate(p->owner, AST_STATE_RINGING);
16890          }
16891       }
16892       if (find_sdp(req)) {
16893          if (p->invitestate != INV_CANCELLED)
16894             p->invitestate = INV_EARLY_MEDIA;
16895          res = process_sdp(p, req, SDP_T38_NONE);
16896          if (!req->ignore && p->owner) {
16897             /* Queue a progress frame only if we have SDP in 180 or 182 */
16898             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
16899          }
16900       }
16901       check_pendings(p);
16902       break;
16903 
16904    case 183:   /* Session progress */
16905       if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
16906          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
16907       if (find_sdp(req)) {
16908          if (p->invitestate != INV_CANCELLED)
16909             p->invitestate = INV_EARLY_MEDIA;
16910          res = process_sdp(p, req, SDP_T38_NONE);
16911          if (!req->ignore && p->owner) {
16912             /* Queue a progress frame */
16913             ast_queue_control(p->owner, AST_CONTROL_PROGRESS);
16914          }
16915       } else {
16916          /* Alcatel PBXs are known to send 183s with no SDP after sending
16917           * a 100 Trying response. We're just going to treat this sort of thing
16918           * the same as we would treat a 180 Ringing
16919           */
16920          if (!req->ignore && p->owner) {
16921             ast_queue_control(p->owner, AST_CONTROL_RINGING);
16922          }
16923       }
16924       check_pendings(p);
16925       break;
16926 
16927    case 200:   /* 200 OK on invite - someone's answering our call */
16928       if (!req->ignore && (p->invitestate != INV_CANCELLED) && sip_cancel_destroy(p))
16929          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
16930       p->authtries = 0;
16931       if (find_sdp(req)) {
16932          if ((res = process_sdp(p, req, SDP_T38_ACCEPT)) && !req->ignore)
16933             if (!reinvite)
16934                /* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */
16935                /* For re-invites, we try to recover */
16936                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
16937       }
16938 
16939       /* Parse contact header for continued conversation */
16940       /* When we get 200 OK, we know which device (and IP) to contact for this call */
16941       /* This is important when we have a SIP proxy between us and the phone */
16942       if (outgoing) {
16943          update_call_counter(p, DEC_CALL_RINGING);
16944          parse_ok_contact(p, req);
16945          /* Save Record-Route for any later requests we make on this dialogue */
16946          if (!reinvite)
16947             build_route(p, req, 1);
16948 
16949          if(set_address_from_contact(p)) {
16950             /* Bad contact - we don't know how to reach this device */
16951             /* We need to ACK, but then send a bye */
16952             if (!p->route && !req->ignore)
16953                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
16954          } 
16955 
16956       }
16957 
16958       if (!req->ignore && p->owner) {
16959          if (!reinvite) {
16960             ast_queue_control(p->owner, AST_CONTROL_ANSWER);
16961             if (global_callevents)
16962                manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
16963                   "Channel: %s\r\nChanneltype: %s\r\nUniqueid: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n",
16964                   p->owner->name, "SIP", p->owner->uniqueid, p->callid, p->fullcontact, p->peername);
16965          } else { /* RE-invite */
16966             ast_queue_frame(p->owner, &ast_null_frame);
16967          }
16968       } else {
16969           /* It's possible we're getting an 200 OK after we've tried to disconnect
16970               by sending CANCEL */
16971          /* First send ACK, then send bye */
16972          if (!req->ignore)
16973             ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
16974       }
16975 
16976       /* Check for Session-Timers related headers */
16977       if (st_get_mode(p) != SESSION_TIMER_MODE_REFUSE && p->outgoing_call == TRUE && !reinvite) {
16978          p_hdrval = (char*)get_header(req, "Session-Expires");
16979             if (!ast_strlen_zero(p_hdrval)) {
16980             /* UAS supports Session-Timers */
16981             enum st_refresher tmp_st_ref = SESSION_TIMER_REFRESHER_AUTO;
16982             int tmp_st_interval = 0;
16983             rtn = parse_session_expires(p_hdrval, &tmp_st_interval, &tmp_st_ref);
16984             if (rtn != 0) {
16985                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
16986             }
16987             if (tmp_st_ref == SESSION_TIMER_REFRESHER_UAC || 
16988                tmp_st_ref == SESSION_TIMER_REFRESHER_UAS) {
16989                p->stimer->st_ref = tmp_st_ref;
16990             } 
16991             if (tmp_st_interval) {
16992                p->stimer->st_interval = tmp_st_interval;
16993             }
16994             p->stimer->st_active = TRUE;
16995             p->stimer->st_active_peer_ua = TRUE;
16996             start_session_timer(p);
16997          } else {
16998             /* UAS doesn't support Session-Timers */
16999             if (st_get_mode(p) == SESSION_TIMER_MODE_ORIGINATE) {
17000                p->stimer->st_ref = SESSION_TIMER_REFRESHER_UAC;
17001                p->stimer->st_active_peer_ua = FALSE;
17002                start_session_timer(p);
17003             }
17004          }
17005       }
17006 
17007 
17008       /* If I understand this right, the branch is different for a non-200 ACK only */
17009       p->invitestate = INV_TERMINATED;
17010       ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
17011       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, TRUE);
17012       check_pendings(p);
17013       break;
17014 
17015    case 407: /* Proxy authentication */
17016    case 401: /* Www auth */
17017       /* First we ACK */
17018       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
17019       if (p->options)
17020          p->options->auth_type = resp;
17021 
17022       /* Then we AUTH */
17023       ast_string_field_set(p, theirtag, NULL);  /* forget their old tag, so we don't match tags when getting response */
17024       if (!req->ignore) {
17025          if (p->authtries < MAX_AUTHTRIES)
17026             p->invitestate = INV_CALLING;
17027          if (p->authtries == MAX_AUTHTRIES || do_proxy_auth(p, req, resp, SIP_INVITE, 1)) {
17028             ast_log(LOG_NOTICE, "Failed to authenticate on INVITE to '%s'\n", get_header(&p->initreq, "From"));
17029             p->needdestroy = 1;
17030             sip_alreadygone(p);
17031             if (p->owner)
17032                ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
17033          }
17034       }
17035       break;
17036 
17037    case 403: /* Forbidden */
17038       /* First we ACK */
17039       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
17040       ast_log(LOG_WARNING, "Received response: \"Forbidden\" from '%s'\n", get_header(&p->initreq, "From"));
17041       if (!req->ignore && p->owner)
17042          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
17043       p->needdestroy = 1;
17044       sip_alreadygone(p);
17045       break;
17046 
17047    case 404: /* Not found */
17048       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
17049       if (p->owner && !req->ignore)
17050          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
17051       sip_alreadygone(p);
17052       break;
17053 
17054    case 408: /* Request timeout */
17055    case 481: /* Call leg does not exist */
17056       /* Could be REFER caused INVITE with replaces */
17057       ast_log(LOG_WARNING, "Re-invite to non-existing call leg on other UA. SIP dialog '%s'. Giving up.\n", p->callid);
17058       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
17059       if (p->owner)
17060          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
17061       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
17062       break;
17063 
17064    case 422: /* Session-Timers: Session interval too small */
17065       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
17066       ast_string_field_set(p, theirtag, NULL);
17067       proc_422_rsp(p, req);
17068       break;
17069 
17070    case 487: /* Cancelled transaction */
17071       /* We have sent CANCEL on an outbound INVITE 
17072          This transaction is already scheduled to be killed by sip_hangup().
17073       */
17074       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
17075       if (p->owner && !req->ignore) {
17076          ast_queue_hangup_with_cause(p->owner, AST_CAUSE_NORMAL_CLEARING);
17077          append_history(p, "Hangup", "Got 487 on CANCEL request from us. Queued AST hangup request");
17078       } else if (!req->ignore) {
17079          update_call_counter(p, DEC_CALL_LIMIT);
17080          append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog.");
17081          p->needdestroy = 1;
17082          sip_alreadygone(p);
17083       }
17084       break;
17085    case 415: /* Unsupported media type */
17086    case 488: /* Not acceptable here */
17087    case 606: /* Not Acceptable */
17088       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
17089       if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) {
17090          change_t38_state(p, T38_DISABLED);
17091          /* Try to reset RTP timers */
17092          ast_rtp_set_rtptimers_onhold(p->rtp);
17093 
17094          /* Trigger a reinvite back to audio */
17095          transmit_reinvite_with_sdp(p, FALSE, FALSE);
17096       } else {
17097          /* We can't set up this call, so give up */
17098          if (p->owner && !req->ignore)
17099             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
17100          p->needdestroy = 1;
17101          /* If there's no dialog to end, then mark p as already gone */
17102          if (!reinvite)
17103             sip_alreadygone(p);
17104       }
17105       break;
17106    case 491: /* Pending */
17107       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
17108       if (p->owner && !req->ignore) {
17109          if (p->owner->_state != AST_STATE_UP) {
17110             ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
17111             p->needdestroy = 1;
17112          } else {
17113             /* This is a re-invite that failed. */
17114             /* Reset the flag after a while 
17115              */
17116             int wait;
17117             /* RFC 3261, if owner of call, wait between 2.1 to 4 seconds,
17118              * if not owner of call, wait 0 to 2 seconds */
17119             if (p->outgoing_call) {
17120                wait = 2100 + ast_random() % 2000;
17121             } else {
17122                wait = ast_random() % 2000;
17123             }
17124             p->waitid = ast_sched_add(sched, wait, sip_reinvite_retry, dialog_ref(p, "passing dialog ptr into sched structure based on waitid for sip_reinvite_retry."));
17125             ast_log(LOG_WARNING, "just did sched_add waitid(%d) for sip_reinvite_retry for dialog %s in handle_response_invite\n", p->waitid, p->callid);
17126             ast_debug(2, "Reinvite race. Waiting %d secs before retry\n", wait);
17127          }
17128       }
17129       break;
17130 
17131    case 501: /* Not implemented */
17132       xmitres = transmit_request(p, SIP_ACK, seqno, XMIT_UNRELIABLE, FALSE);
17133       if (p->owner)
17134          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
17135       break;
17136    }
17137    if (xmitres == XMIT_ERROR)
17138       ast_log(LOG_WARNING, "Could not transmit message in dialog %s\n", p->callid);
17139 }

static void handle_response_notify ( struct sip_pvt p,
int  resp,
char *  rest,
struct sip_request req,
int  seqno 
) [static]

Definition at line 17144 of file chan_sip.c.

References AST_CAUSE_NORMAL_UNSPECIFIED, ast_clear_flag, ast_debug, ast_inet_ntoa(), ast_log(), ast_queue_hangup_with_cause(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, sip_pvt::authname, sip_pvt::authtries, cb_extensionstate(), sip_pvt::context, do_proxy_auth(), sip_pvt::exten, sip_pvt::flags, get_header(), sip_pvt::initreq, sip_pvt::laststate, LOG_NOTICE, LOG_WARNING, ast_channel::name, sip_pvt::needdestroy, NONE, sip_pvt::notify_headers, sip_pvt::owner, sip_pvt::recv, sip_pvt::refer, SIP_NOTIFY, SIP_PAGE2_STATECHANGEQUEUE, sip_pvt::subscribed, and sip_pvt::theirtag.

Referenced by handle_response().

17145 {
17146    switch (resp) {
17147    case 200:   /* Notify accepted */
17148       /* They got the notify, this is the end */
17149       if (p->owner) {
17150          if (!p->refer) {
17151             ast_log(LOG_WARNING, "Notify answer on an owned channel? - %s\n", p->owner->name);
17152             ast_queue_hangup_with_cause(p->owner, AST_CAUSE_NORMAL_UNSPECIFIED);
17153          } else {
17154             ast_debug(4, "Got OK on REFER Notify message\n");
17155          }
17156       } else {
17157          if (p->subscribed == NONE) {
17158             ast_debug(4, "Got 200 accepted on NOTIFY\n");
17159             p->needdestroy = 1;
17160          }
17161          if (ast_test_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE)) {
17162             /* Ready to send the next state we have on queue */
17163             ast_clear_flag(&p->flags[1], SIP_PAGE2_STATECHANGEQUEUE);
17164             cb_extensionstate((char *)p->context, (char *)p->exten, p->laststate, (void *) p);
17165          }
17166       }
17167       break;
17168    case 401:   /* Not www-authorized on SIP method */
17169    case 407:   /* Proxy auth */
17170       if (!p->notify_headers) {
17171          break; /* Only device notify can use NOTIFY auth */
17172       }
17173       ast_string_field_set(p, theirtag, NULL);
17174       if (ast_strlen_zero(p->authname)) {
17175          ast_log(LOG_WARNING, "Asked to authenticate NOTIFY to %s:%d but we have no matching peer or realm auth!\n", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
17176          p->needdestroy = 1;
17177       }
17178       if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_NOTIFY, 0)) {
17179          ast_log(LOG_NOTICE, "Failed to authenticate on NOTYFY to '%s'\n", get_header(&p->initreq, "From"));
17180          p->needdestroy = 1;
17181       }
17182       break;
17183    }
17184 }

static void handle_response_peerpoke ( struct sip_pvt p,
int  resp,
struct sip_request req 
) [static]

Handle qualification responses (OPTIONS).

Definition at line 17390 of file chan_sip.c.

References ast_check_realtime(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_log(), AST_SCHED_REPLACE_UNREF, ast_tvdiff_ms(), ast_tvnow(), ast_update_realtime(), sip_peer::call, DEFAULT_FREQ_NOTOK, dialog_unref(), EVENT_FLAG_SYSTEM, sip_peer::lastms, LOG_NOTICE, manager_event, sip_peer::maxms, sip_peer::name, sip_pvt::needdestroy, sip_settings::peer_rtupdate, sip_peer::pokeexpire, sip_peer::ps, sip_peer::qualifyfreq, ref_peer(), register_peer_exten(), sip_pvt::relatedpeer, s, sched, SENTINEL, sip_cfg, sip_poke_peer_s(), TRUE, and unref_peer().

Referenced by handle_response().

17391 {
17392    struct sip_peer *peer = /* ref_peer( */ p->relatedpeer /* , "bump refcount on p, as it is being used in this function(handle_response_peerpoke)")*/ ; /* hope this is already refcounted! */
17393    int statechanged, is_reachable, was_reachable;
17394    int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps);
17395 
17396    /*
17397     * Compute the response time to a ping (goes in peer->lastms.)
17398     * -1 means did not respond, 0 means unknown,
17399     * 1..maxms is a valid response, >maxms means late response.
17400     */
17401    if (pingtime < 1) /* zero = unknown, so round up to 1 */
17402       pingtime = 1;
17403 
17404    /* Now determine new state and whether it has changed.
17405     * Use some helper variables to simplify the writing
17406     * of the expressions.
17407     */
17408    was_reachable = peer->lastms > 0 && peer->lastms <= peer->maxms;
17409    is_reachable = pingtime <= peer->maxms;
17410    statechanged = peer->lastms == 0 /* yes, unknown before */
17411       || was_reachable != is_reachable;
17412 
17413    peer->lastms = pingtime;
17414    peer->call = dialog_unref(peer->call, "unref dialog peer->call");
17415    if (statechanged) {
17416       const char *s = is_reachable ? "Reachable" : "Lagged";
17417       char str_lastms[20];
17418       snprintf(str_lastms, sizeof(str_lastms), "%d", pingtime);
17419 
17420       ast_log(LOG_NOTICE, "Peer '%s' is now %s. (%dms / %dms)\n",
17421          peer->name, s, pingtime, peer->maxms);
17422       ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
17423       if (sip_cfg.peer_rtupdate) {
17424          ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", str_lastms, SENTINEL);
17425       }
17426       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
17427          "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: %s\r\nTime: %d\r\n",
17428          peer->name, s, pingtime);
17429       if (is_reachable && global_regextenonqualify)
17430          register_peer_exten(peer, TRUE);
17431    }
17432 
17433    p->needdestroy = 1;
17434 
17435    /* Try again eventually */
17436    AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched,
17437          is_reachable ? peer->qualifyfreq : DEFAULT_FREQ_NOTOK,
17438          sip_poke_peer_s, peer,
17439          unref_peer(_data, "removing poke peer ref"),
17440          unref_peer(peer, "removing poke peer ref"),
17441          ref_peer(peer, "adding poke peer ref"));
17442 }

static void handle_response_refer ( struct sip_pvt p,
int  resp,
char *  rest,
struct sip_request req,
int  seqno 
) [static]

Definition at line 17189 of file chan_sip.c.

References AST_CONTROL_CONGESTION, ast_debug, ast_inet_ntoa(), ast_log(), ast_queue_control(), ast_strlen_zero(), sip_pvt::authname, sip_pvt::authtries, sip_pvt::callid, do_proxy_auth(), get_header(), sip_pvt::initreq, LOG_NOTICE, LOG_WARNING, sip_pvt::needdestroy, sip_pvt::owner, sip_pvt::recv, sip_pvt::refer, REFER_ACCEPTED, REFER_FAILED, REFER_NOAUTH, sip_refer::refer_to, SIP_REFER, and sip_refer::status.

Referenced by handle_response().

17190 {
17191    /* If no refer structure exists, then do nothing */
17192    if (!p->refer)
17193       return;
17194 
17195    switch (resp) {
17196    case 202:   /* Transfer accepted */
17197       /* We need  to do something here */
17198       /* The transferee is now sending INVITE to target */
17199       p->refer->status = REFER_ACCEPTED;
17200       /* Now wait for next message */
17201       ast_debug(3, "Got 202 accepted on transfer\n");
17202       /* We should hang along, waiting for NOTIFY's here */
17203       break;
17204 
17205    case 401:   /* Not www-authorized on SIP method */
17206    case 407:   /* Proxy auth */
17207       if (ast_strlen_zero(p->authname)) {
17208          ast_log(LOG_WARNING, "Asked to authenticate REFER to %s:%d but we have no matching peer or realm auth!\n",
17209             ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
17210          p->needdestroy = 1;
17211       }
17212       if (p->authtries > 1 || do_proxy_auth(p, req, resp, SIP_REFER, 0)) {
17213          ast_log(LOG_NOTICE, "Failed to authenticate on REFER to '%s'\n", get_header(&p->initreq, "From"));
17214          p->refer->status = REFER_NOAUTH;
17215          p->needdestroy = 1;
17216       }
17217       break;
17218    case 481: /* Call leg does not exist */
17219 
17220       /* A transfer with Replaces did not work */
17221       /* OEJ: We should Set flag, cancel the REFER, go back
17222       to original call - but right now we can't */
17223       ast_log(LOG_WARNING, "Remote host can't match REFER request to call '%s'. Giving up.\n", p->callid);
17224       if (p->owner)
17225          ast_queue_control(p->owner, AST_CONTROL_CONGESTION);
17226       p->needdestroy = 1;
17227       break;
17228 
17229    case 500:   /* Server error */
17230    case 501:   /* Method not implemented */
17231       /* Return to the current call onhold */
17232       /* Status flag needed to be reset */
17233       ast_log(LOG_NOTICE, "SIP transfer to %s failed, call miserably fails. \n", p->refer->refer_to);
17234       p->needdestroy = 1;
17235       p->refer->status = REFER_FAILED;
17236       break;
17237    case 603:   /* Transfer declined */
17238       ast_log(LOG_NOTICE, "SIP transfer to %s declined, call miserably fails. \n", p->refer->refer_to);
17239       p->refer->status = REFER_FAILED;
17240       p->needdestroy = 1;
17241       break;
17242    }
17243 }

static int handle_response_register ( struct sip_pvt p,
int  resp,
char *  rest,
struct sip_request req,
int  seqno 
) [static]

Handle responses on REGISTER to services.

Definition at line 17246 of file chan_sip.c.

References __get_header(), ast_debug, ast_log(), AST_SCHED_DEL_UNREF, AST_SCHED_REPLACE_UNREF, ast_strlen_zero(), ast_tvnow(), sip_pvt::authtries, sip_registry::call, sip_pvt::callid, sip_registry::configured_expiry, DEFAULT_TRANS_TIMEOUT, dialog_unref(), do_register_auth(), EVENT_FLAG_SYSTEM, sip_registry::expire, sip_registry::expiry, EXPIRY_GUARD_LIMIT, EXPIRY_GUARD_MIN, EXPIRY_GUARD_PCT, EXPIRY_GUARD_SECS, get_header(), sip_registry::hostname, sip_pvt::initreq, LOG_NOTICE, LOG_WARNING, manager_event, MAX, MAX_AUTHTRIES, sip_pvt::needdestroy, sip_pvt::our_contact, sip_pvt::peername, sip_registry::refresh, REG_STATE_NOAUTH, REG_STATE_REGISTERED, REG_STATE_REJECTED, REG_STATE_UNREGISTERED, sip_registry::regattempts, sip_pvt::registry, registry_addref(), registry_unref(), sip_registry::regstate, regstate2str(), sip_registry::regtime, S_OR, sched, SIP_REGISTER, sip_reregister(), sip_scheddestroy(), strcasestr(), sip_registry::timeout, transmit_register(), sip_pvt::username, and sip_registry::username.

Referenced by handle_response().

17247 {
17248    int expires, expires_ms;
17249    struct sip_registry *r;
17250    r=p->registry;
17251    
17252    switch (resp) {
17253    case 401:   /* Unauthorized */
17254       if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) {
17255          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s@%s' (Tries %d)\n", p->registry->username, p->registry->hostname, p->authtries);
17256          p->needdestroy = 1;
17257       }
17258       break;
17259    case 403:   /* Forbidden */
17260       ast_log(LOG_WARNING, "Forbidden - wrong password on authentication for REGISTER for '%s' to '%s'\n", p->registry->username, p->registry->hostname);
17261       AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 403"));
17262       r->regstate = REG_STATE_NOAUTH;
17263       p->needdestroy = 1;
17264       break;
17265    case 404:   /* Not found */
17266       ast_log(LOG_WARNING, "Got 404 Not found on SIP register to service %s@%s, giving up\n", p->registry->username, p->registry->hostname);
17267       p->needdestroy = 1;
17268       if (r->call)
17269          r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 404");
17270       r->regstate = REG_STATE_REJECTED;
17271       AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 404"));
17272       break;
17273    case 407:   /* Proxy auth */
17274       if (p->authtries == MAX_AUTHTRIES || do_register_auth(p, req, resp)) {
17275          ast_log(LOG_NOTICE, "Failed to authenticate on REGISTER to '%s' (tries '%d')\n", get_header(&p->initreq, "From"), p->authtries);
17276          p->needdestroy = 1;
17277       }
17278       break;
17279    case 408:   /* Request timeout */
17280       /* Got a timeout response, so reset the counter of failed responses */
17281       if (r) {
17282          r->regattempts = 0;
17283       } else {
17284          ast_log(LOG_WARNING, "Got a 408 response to our REGISTER on call %s after we had destroyed the registry object\n", p->callid);
17285       }
17286       break;
17287    case 423:   /* Interval too brief */
17288       r->expiry = atoi(get_header(req, "Min-Expires"));
17289       ast_log(LOG_WARNING, "Got 423 Interval too brief for service %s@%s, minimum is %d seconds\n", p->registry->username, p->registry->hostname, r->expiry);
17290       AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 423"));
17291       if (r->call) {
17292          r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 423");
17293          p->needdestroy = 1;
17294       }
17295       if (r->expiry > max_expiry) {
17296          ast_log(LOG_WARNING, "Required expiration time from %s@%s is too high, giving up\n", p->registry->username, p->registry->hostname);
17297          r->expiry = r->configured_expiry;
17298          r->regstate = REG_STATE_REJECTED;
17299       } else {
17300          r->regstate = REG_STATE_UNREGISTERED;
17301          transmit_register(r, SIP_REGISTER, NULL, NULL);
17302       }
17303       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate));
17304       break;
17305    case 479:   /* SER: Not able to process the URI - address is wrong in register*/
17306       ast_log(LOG_WARNING, "Got error 479 on register to %s@%s, giving up (check config)\n", p->registry->username, p->registry->hostname);
17307       p->needdestroy = 1;
17308       if (r->call)
17309          r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 479");
17310       r->regstate = REG_STATE_REJECTED;
17311       AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 479"));
17312       break;
17313    case 200:   /* 200 OK */
17314       if (!r) {
17315          ast_log(LOG_WARNING, "Got 200 OK on REGISTER, but there isn't a registry entry for '%s' (we probably already got the OK)\n", S_OR(p->peername, p->username));
17316          p->needdestroy = 1;
17317          return 0;
17318       }
17319       
17320       r->regstate = REG_STATE_REGISTERED;
17321       r->regtime = ast_tvnow();     /* Reset time of last succesful registration */
17322       manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nDomain: %s\r\nStatus: %s\r\n", r->hostname, regstate2str(r->regstate));
17323       r->regattempts = 0;
17324       ast_debug(1, "Registration successful\n");
17325       if (r->timeout > -1) {
17326          ast_debug(1, "Cancelling timeout %d\n", r->timeout);
17327       }
17328       AST_SCHED_DEL_UNREF(sched, r->timeout, registry_unref(r, "reg ptr unref from handle_response_register 200"));
17329       if (r->call)
17330          r->call = dialog_unref(r->call, "unsetting registry->call pointer-- case 200");
17331       p->registry = registry_unref(p->registry, "unref registry entry p->registry");
17332       /* Let this one hang around until we have all the responses */
17333       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
17334       /* p->needdestroy = 1; */
17335       
17336       /* set us up for re-registering
17337        * figure out how long we got registered for
17338        * according to section 6.13 of RFC, contact headers override
17339        * expires headers, so check those first */
17340       expires = 0;
17341 
17342       /* XXX todo: try to save the extra call */
17343       if (!ast_strlen_zero(get_header(req, "Contact"))) {
17344          const char *contact = NULL;
17345          const char *tmptmp = NULL;
17346          int start = 0;
17347          for(;;) {
17348             contact = __get_header(req, "Contact", &start);
17349             /* this loop ensures we get a contact header about our register request */
17350             if(!ast_strlen_zero(contact)) {
17351                if( (tmptmp=strstr(contact, p->our_contact))) {
17352                   contact=tmptmp;
17353                   break;
17354                }
17355             } else
17356                break;
17357          }
17358          tmptmp = strcasestr(contact, "expires=");
17359          if (tmptmp) {
17360             if (sscanf(tmptmp + 8, "%30d;", &expires) != 1)
17361                expires = 0;
17362          }
17363          
17364       }
17365       if (!expires) 
17366          expires=atoi(get_header(req, "expires"));
17367       if (!expires)
17368          expires=default_expiry;
17369       
17370       expires_ms = expires * 1000;
17371       if (expires <= EXPIRY_GUARD_LIMIT)
17372          expires_ms -= MAX((expires_ms * EXPIRY_GUARD_PCT), EXPIRY_GUARD_MIN);
17373       else
17374          expires_ms -= EXPIRY_GUARD_SECS * 1000;
17375       if (sipdebug)
17376          ast_log(LOG_NOTICE, "Outbound Registration: Expiry for %s is %d sec (Scheduling reregistration in %d s)\n", r->hostname, expires, expires_ms/1000); 
17377       
17378       r->refresh= (int) expires_ms / 1000;
17379       
17380       /* Schedule re-registration before we expire */
17381       AST_SCHED_REPLACE_UNREF(r->expire, sched, expires_ms, sip_reregister, r, 
17382                         registry_unref(_data,"unref in REPLACE del fail"), 
17383                         registry_unref(r,"unref in REPLACE add fail"), 
17384                         registry_addref(r,"The Addition side of REPLACE")); 
17385    }
17386    return 1;
17387 }

static int handle_t38_options ( struct ast_flags flags,
struct ast_flags mask,
struct ast_variable v,
int *  maxdatagram 
) [static]

Handle T.38 configuration options common to users and peers.

Returns:
non-zero if any config options were handled, zero otherwise

Definition at line 22339 of file chan_sip.c.

References ast_clear_flag, ast_log(), ast_set2_flag, ast_set_flag, ast_strdupa, ast_true(), buf, ast_channel::flags, ast_variable::lineno, LOG_WARNING, ast_variable::name, ast_channel::next, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_T38SUPPORT_UDPTL_FEC, SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY, SIP_PAGE2_UDPTL_DESTINATION, strsep(), and ast_variable::value.

Referenced by build_peer().

22341 {
22342    int res = 1;
22343 
22344    if (!strcasecmp(v->name, "t38pt_udptl")) {
22345       char *buf = ast_strdupa(v->value);
22346       char *word, *next = buf;
22347 
22348       ast_set_flag(&mask[1], SIP_PAGE2_T38SUPPORT);
22349 
22350       while ((word = strsep(&next, ","))) {
22351          if (ast_true(word) || !strcasecmp(word, "fec")) {
22352             ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT);
22353             ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL_FEC);
22354          } else if (!strcasecmp(word, "redundancy")) {
22355             ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT);
22356             ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY);
22357          } else if (!strcasecmp(word, "none")) {
22358             ast_clear_flag(&flags[1], SIP_PAGE2_T38SUPPORT);
22359             ast_set_flag(&flags[1], SIP_PAGE2_T38SUPPORT_UDPTL);
22360          } else if (!strncasecmp(word, "maxdatagram=", 12)) {
22361             if (sscanf(&word[12], "%30u", maxdatagram) != 1) {
22362                ast_log(LOG_WARNING, "Invalid maxdatagram '%s' at line %d of %s\n", v->value, v->lineno, config);
22363                *maxdatagram = global_t38_maxdatagram;
22364             }
22365          }
22366       }
22367    } else if (!strcasecmp(v->name, "t38pt_usertpsource")) {
22368       ast_set_flag(&mask[1], SIP_PAGE2_UDPTL_DESTINATION);
22369       ast_set2_flag(&flags[1], ast_true(v->value), SIP_PAGE2_UDPTL_DESTINATION);
22370    } else {
22371       res = 0;
22372    }
22373 
22374    return res;
22375 }

static const char * hangup_cause2sip ( int  cause  )  [static]

Convert Asterisk hangup causes to SIP codes.

 Possible values from causes.h
        AST_CAUSE_NOTDEFINED    AST_CAUSE_NORMAL        AST_CAUSE_BUSY
        AST_CAUSE_FAILURE       AST_CAUSE_CONGESTION    AST_CAUSE_UNALLOCATED

	In addition to these, a lot of PRI codes is defined in causes.h 
	...should we take care of them too ?
	
	Quote RFC 3398

   ISUP Cause value                        SIP response
   ----------------                        ------------
   1  unallocated number                   404 Not Found
   2  no route to network                  404 Not found
   3  no route to destination              404 Not found
   16 normal call clearing                 --- (*)
   17 user busy                            486 Busy here
   18 no user responding                   408 Request Timeout
   19 no answer from the user              480 Temporarily unavailable
   20 subscriber absent                    480 Temporarily unavailable
   21 call rejected                        403 Forbidden (+)
   22 number changed (w/o diagnostic)      410 Gone
   22 number changed (w/ diagnostic)       301 Moved Permanently
   23 redirection to new destination       410 Gone
   26 non-selected user clearing           404 Not Found (=)
   27 destination out of order             502 Bad Gateway
   28 address incomplete                   484 Address incomplete
   29 facility rejected                    501 Not implemented
   31 normal unspecified                   480 Temporarily unavailable

Definition at line 5502 of file chan_sip.c.

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CHAN_NOT_IMPLEMENTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_ROUTE_TRANSIT_NET, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL_UNSPECIFIED, AST_CAUSE_NOTDEFINED, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNALLOCATED, AST_CAUSE_UNREGISTERED, AST_CAUSE_USER_BUSY, and ast_debug.

Referenced by sip_hangup().

05503 {
05504    switch (cause) {
05505       case AST_CAUSE_UNALLOCATED:      /* 1 */
05506       case AST_CAUSE_NO_ROUTE_DESTINATION:   /* 3 IAX2: Can't find extension in context */
05507       case AST_CAUSE_NO_ROUTE_TRANSIT_NET:   /* 2 */
05508          return "404 Not Found";
05509       case AST_CAUSE_CONGESTION:    /* 34 */
05510       case AST_CAUSE_SWITCH_CONGESTION:   /* 42 */
05511          return "503 Service Unavailable";
05512       case AST_CAUSE_NO_USER_RESPONSE: /* 18 */
05513          return "408 Request Timeout";
05514       case AST_CAUSE_NO_ANSWER:     /* 19 */
05515       case AST_CAUSE_UNREGISTERED:        /* 20 */
05516          return "480 Temporarily unavailable";
05517       case AST_CAUSE_CALL_REJECTED:    /* 21 */
05518          return "403 Forbidden";
05519       case AST_CAUSE_NUMBER_CHANGED:      /* 22 */
05520          return "410 Gone";
05521       case AST_CAUSE_NORMAL_UNSPECIFIED:  /* 31 */
05522          return "480 Temporarily unavailable";
05523       case AST_CAUSE_INVALID_NUMBER_FORMAT:
05524          return "484 Address incomplete";
05525       case AST_CAUSE_USER_BUSY:
05526          return "486 Busy here";
05527       case AST_CAUSE_FAILURE:
05528          return "500 Server internal failure";
05529       case AST_CAUSE_FACILITY_REJECTED:   /* 29 */
05530          return "501 Not Implemented";
05531       case AST_CAUSE_CHAN_NOT_IMPLEMENTED:
05532          return "503 Service Unavailable";
05533       /* Used in chan_iax2 */
05534       case AST_CAUSE_DESTINATION_OUT_OF_ORDER:
05535          return "502 Bad Gateway";
05536       case AST_CAUSE_BEARERCAPABILITY_NOTAVAIL: /* Can't find codec to connect to host */
05537          return "488 Not Acceptable Here";
05538          
05539       case AST_CAUSE_NOTDEFINED:
05540       default:
05541          ast_debug(1, "AST hangup cause %d (no match found in SIP)\n", cause);
05542          return NULL;
05543    }
05544 
05545    /* Never reached */
05546    return 0;
05547 }

static int hangup_sip2cause ( int  cause  )  [static]

Convert SIP hangup causes to Asterisk hangup causes.

Definition at line 5390 of file chan_sip.c.

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_BUSY, AST_CAUSE_CALL_REJECTED, AST_CAUSE_CONGESTION, AST_CAUSE_DESTINATION_OUT_OF_ORDER, AST_CAUSE_FACILITY_REJECTED, AST_CAUSE_FAILURE, AST_CAUSE_INTERWORKING, AST_CAUSE_INVALID_NUMBER_FORMAT, AST_CAUSE_NO_ANSWER, AST_CAUSE_NO_ROUTE_DESTINATION, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_NORMAL, AST_CAUSE_NORMAL_TEMPORARY_FAILURE, AST_CAUSE_NUMBER_CHANGED, AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE, AST_CAUSE_UNALLOCATED, and AST_CAUSE_USER_BUSY.

Referenced by handle_response().

05391 {
05392    /* Possible values taken from causes.h */
05393 
05394    switch(cause) {
05395       case 401:   /* Unauthorized */
05396          return AST_CAUSE_CALL_REJECTED;
05397       case 403:   /* Not found */
05398          return AST_CAUSE_CALL_REJECTED;
05399       case 404:   /* Not found */
05400          return AST_CAUSE_UNALLOCATED;
05401       case 405:   /* Method not allowed */
05402          return AST_CAUSE_INTERWORKING;
05403       case 407:   /* Proxy authentication required */
05404          return AST_CAUSE_CALL_REJECTED;
05405       case 408:   /* No reaction */
05406          return AST_CAUSE_NO_USER_RESPONSE;
05407       case 409:   /* Conflict */
05408          return AST_CAUSE_NORMAL_TEMPORARY_FAILURE;
05409       case 410:   /* Gone */
05410          return AST_CAUSE_NUMBER_CHANGED;
05411       case 411:   /* Length required */
05412          return AST_CAUSE_INTERWORKING;
05413       case 413:   /* Request entity too large */
05414          return AST_CAUSE_INTERWORKING;
05415       case 414:   /* Request URI too large */
05416          return AST_CAUSE_INTERWORKING;
05417       case 415:   /* Unsupported media type */
05418          return AST_CAUSE_INTERWORKING;
05419       case 420:   /* Bad extension */
05420          return AST_CAUSE_NO_ROUTE_DESTINATION;
05421       case 480:   /* No answer */
05422          return AST_CAUSE_NO_ANSWER;
05423       case 481:   /* No answer */
05424          return AST_CAUSE_INTERWORKING;
05425       case 482:   /* Loop detected */
05426          return AST_CAUSE_INTERWORKING;
05427       case 483:   /* Too many hops */
05428          return AST_CAUSE_NO_ANSWER;
05429       case 484:   /* Address incomplete */
05430          return AST_CAUSE_INVALID_NUMBER_FORMAT;
05431       case 485:   /* Ambiguous */
05432          return AST_CAUSE_UNALLOCATED;
05433       case 486:   /* Busy everywhere */
05434          return AST_CAUSE_BUSY;
05435       case 487:   /* Request terminated */
05436          return AST_CAUSE_INTERWORKING;
05437       case 488:   /* No codecs approved */
05438          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05439       case 491:   /* Request pending */
05440          return AST_CAUSE_INTERWORKING;
05441       case 493:   /* Undecipherable */
05442          return AST_CAUSE_INTERWORKING;
05443       case 500:   /* Server internal failure */
05444          return AST_CAUSE_FAILURE;
05445       case 501:   /* Call rejected */
05446          return AST_CAUSE_FACILITY_REJECTED;
05447       case 502:   
05448          return AST_CAUSE_DESTINATION_OUT_OF_ORDER;
05449       case 503:   /* Service unavailable */
05450          return AST_CAUSE_CONGESTION;
05451       case 504:   /* Gateway timeout */
05452          return AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
05453       case 505:   /* SIP version not supported */
05454          return AST_CAUSE_INTERWORKING;
05455       case 600:   /* Busy everywhere */
05456          return AST_CAUSE_USER_BUSY;
05457       case 603:   /* Decline */
05458          return AST_CAUSE_CALL_REJECTED;
05459       case 604:   /* Does not exist anywhere */
05460          return AST_CAUSE_UNALLOCATED;
05461       case 606:   /* Not acceptable */
05462          return AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
05463       default:
05464          return AST_CAUSE_NORMAL;
05465    }
05466    /* Never reached */
05467    return 0;
05468 }

static int init_req ( struct sip_request req,
int  sipmethod,
const char *  recip 
) [static]

Initialize SIP request.

Definition at line 8650 of file chan_sip.c.

References ast_str_create(), ast_str_set(), sip_methods, SIP_MIN_PACKET, and cfsip_methods::text.

08651 {
08652    /* Initialize a request */
08653    memset(req, 0, sizeof(*req));
08654    if (!(req->data = ast_str_create(SIP_MIN_PACKET)))
08655       return -1;
08656    req->method = sipmethod;
08657    req->header[0] = 0;
08658    ast_str_set(&req->data, 0, "%s %s SIP/2.0\r\n", sip_methods[sipmethod].text, recip);
08659    req->len = req->data->used;
08660    req->headers++;
08661    return 0;
08662 }

static int init_resp ( struct sip_request resp,
const char *  msg 
) [static]

Initialize SIP response, based on SIP request.

Definition at line 8635 of file chan_sip.c.

References ast_str_create(), ast_str_set(), SIP_MIN_PACKET, and SIP_RESPONSE.

08636 {
08637    /* Initialize a response */
08638    memset(resp, 0, sizeof(*resp));
08639    resp->method = SIP_RESPONSE;
08640    if (!(resp->data = ast_str_create(SIP_MIN_PACKET)))
08641       return -1;
08642    resp->header[0] = 0;
08643    ast_str_set(&resp->data, 0, "SIP/2.0 %s\r\n", msg);
08644    resp->len = resp->data->used;
08645    resp->headers++;
08646    return 0;
08647 }

static void initialize_initreq ( struct sip_pvt p,
struct sip_request req 
) [static]

Initialize the initital request packet in the pvt structure. This packet is used for creating replies and future requests in a dialog.

Definition at line 2892 of file chan_sip.c.

References ast_debug, ast_verbose, sip_pvt::callid, copy_request(), sip_request::debug, sip_request::headers, sip_pvt::initreq, sip_request::lines, sip_request::method, parse_request(), and sip_methods.

Referenced by transmit_invite(), transmit_notify_custom(), transmit_notify_with_mwi(), transmit_notify_with_sipfrag(), transmit_register(), and transmit_reinvite_with_sdp().

02893 {
02894    if (p->initreq.headers)
02895       ast_debug(1, "Initializing already initialized SIP dialog %s (presumably reinvite)\n", p->callid);
02896    else
02897       ast_debug(1, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid);
02898    /* Use this as the basis */
02899    copy_request(&p->initreq, req);
02900    parse_request(&p->initreq);
02901    if (req->debug)
02902       ast_verbose("Initreq: %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
02903 }

static void initreqprep ( struct sip_request req,
struct sip_pvt p,
int  sipmethod 
) [static]

Initiate new SIP request to peer/user.

Todo:
Need to add back the VXML URL here at some point, possibly use build_string for all this junk

Definition at line 10023 of file chan_sip.c.

References add_header(), add_route(), AST_DIGIT_ANYNUM, ast_inet_ntoa(), AST_PRES_ALLOWED, AST_PRES_RESTRICTION, ast_str_alloca, ast_str_append(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_encode(), build_contact(), build_rpid(), CALLERID_UNKNOWN, sip_pvt::callid, sip_pvt::callingpres, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, DEFAULT_MAX_FORWARDS, exten, sip_pvt::flags, sip_pvt::fromdomain, FROMDOMAIN_INVALID, sip_pvt::fromname, sip_pvt::fromuser, sip_pvt::fullcontact, init_req(), sip_pvt::lastmsg, sip_pvt::ocseq, sip_pvt::options, sip_pvt::our_contact, sip_pvt::ourip, ourport, sip_pvt::owner, sip_pvt::portinuri, sip_pvt::route, sip_pvt::rpid, s, S_OR, sip_pvt::sa, SIP_INVITE, sip_methods, SIP_NOTIFY, SIP_SENDRPID, sip_standard_port(), SIP_USEREQPHONE, SIPBUFSIZE, sip_pvt::socket, ast_str::str, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, sip_pvt::todnid, sip_pvt::tohost, sip_socket::type, sip_pvt::uri, sip_invite_param::uri_options, sip_pvt::username, sip_pvt::via, and sip_invite_param::vxml_url.

Referenced by transmit_invite(), transmit_notify_custom(), and transmit_notify_with_mwi().

10024 {
10025    struct ast_str *invite = ast_str_alloca(256);
10026    char from[256];
10027    char to[256];
10028    char tmp_n[SIPBUFSIZE/2];  /* build a local copy of 'n' if needed */
10029    char tmp_l[SIPBUFSIZE/2];  /* build a local copy of 'l' if needed */
10030    const char *l = NULL;   /* XXX what is this, exactly ? */
10031    const char *n = NULL;   /* XXX what is this, exactly ? */
10032    const char *d = NULL;   /* domain in from header */
10033    const char *urioptions = "";
10034    int ourport;
10035 
10036    if (ast_test_flag(&p->flags[0], SIP_USEREQPHONE)) {
10037       const char *s = p->username;  /* being a string field, cannot be NULL */
10038 
10039       /* Test p->username against allowed characters in AST_DIGIT_ANY
10040          If it matches the allowed characters list, then sipuser = ";user=phone"
10041          If not, then sipuser = ""
10042       */
10043       /* + is allowed in first position in a tel: uri */
10044       if (*s == '+')
10045          s++;
10046       for (; *s; s++) {
10047          if (!strchr(AST_DIGIT_ANYNUM, *s) )
10048             break;
10049       }
10050       /* If we have only digits, add ;user=phone to the uri */
10051       if (!*s)
10052          urioptions = ";user=phone";
10053    }
10054 
10055 
10056    snprintf(p->lastmsg, sizeof(p->lastmsg), "Init: %s", sip_methods[sipmethod].text);
10057 
10058    d = S_OR(p->fromdomain, ast_inet_ntoa(p->ourip.sin_addr));
10059    if (p->owner) {
10060       l = p->owner->cid.cid_num;
10061       n = p->owner->cid.cid_name;
10062    }
10063    /* if we are not sending RPID and user wants his callerid restricted */
10064    if (!ast_test_flag(&p->flags[0], SIP_SENDRPID) &&
10065        ((p->callingpres & AST_PRES_RESTRICTION) != AST_PRES_ALLOWED)) {
10066       l = CALLERID_UNKNOWN;
10067       n = l;
10068       d = FROMDOMAIN_INVALID;
10069    }
10070    if (ast_strlen_zero(l))
10071       l = default_callerid;
10072    if (ast_strlen_zero(n))
10073       n = l;
10074    /* Allow user to be overridden */
10075    if (!ast_strlen_zero(p->fromuser))
10076       l = p->fromuser;
10077    else /* Save for any further attempts */
10078       ast_string_field_set(p, fromuser, l);
10079 
10080    /* Allow user to be overridden */
10081    if (!ast_strlen_zero(p->fromname))
10082       n = p->fromname;
10083    else /* Save for any further attempts */
10084       ast_string_field_set(p, fromname, n);
10085 
10086    if (pedanticsipchecking) {
10087       ast_uri_encode(n, tmp_n, sizeof(tmp_n), 0);
10088       n = tmp_n;
10089       ast_uri_encode(l, tmp_l, sizeof(tmp_l), 0);
10090       l = tmp_l;
10091    }
10092 
10093    ourport = ntohs(p->ourip.sin_port);
10094    if (!sip_standard_port(p->socket.type, ourport) && ast_strlen_zero(p->fromdomain))
10095       snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s:%d>;tag=%s", n, l, d, ourport, p->tag);
10096    else
10097       snprintf(from, sizeof(from), "\"%s\" <sip:%s@%s>;tag=%s", n, l, d, p->tag);
10098 
10099    /* If we're calling a registered SIP peer, use the fullcontact to dial to the peer */
10100    if (!ast_strlen_zero(p->fullcontact)) {
10101       /* If we have full contact, trust it */
10102       ast_str_append(&invite, 0, "%s", p->fullcontact);
10103    } else {
10104       /* Otherwise, use the username while waiting for registration */
10105       ast_str_append(&invite, 0, "sip:");
10106       if (!ast_strlen_zero(p->username)) {
10107          n = p->username;
10108          if (pedanticsipchecking) {
10109             ast_uri_encode(n, tmp_n, sizeof(tmp_n), 0);
10110             n = tmp_n;
10111          }
10112          ast_str_append(&invite, 0, "%s@", n);
10113       }
10114       ast_str_append(&invite, 0, "%s", p->tohost);
10115       if (p->portinuri)
10116          ast_str_append(&invite, 0, ":%d", ntohs(p->sa.sin_port));
10117       ast_str_append(&invite, 0, "%s", urioptions);
10118    }
10119 
10120    /* If custom URI options have been provided, append them */
10121    if (p->options && !ast_strlen_zero(p->options->uri_options))
10122       ast_str_append(&invite, 0, ";%s", p->options->uri_options);
10123    
10124    /* This is the request URI, which is the next hop of the call
10125       which may or may not be the destination of the call
10126    */
10127    ast_string_field_set(p, uri, invite->str);
10128   
10129    if (!ast_strlen_zero(p->todnid)) {
10130       /*! \todo Need to add back the VXML URL here at some point, possibly use build_string for all this junk */
10131       if (!strchr(p->todnid, '@')) {
10132          /* We have no domain in the dnid */
10133          snprintf(to, sizeof(to), "<sip:%s@%s>%s%s", p->todnid, p->tohost, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag);
10134       } else {
10135          snprintf(to, sizeof(to), "<sip:%s>%s%s", p->todnid, ast_strlen_zero(p->theirtag) ? "" : ";tag=", p->theirtag);
10136       }
10137    } else {
10138       if (sipmethod == SIP_NOTIFY && !ast_strlen_zero(p->theirtag)) { 
10139          /* If this is a NOTIFY, use the From: tag in the subscribe (RFC 3265) */
10140          snprintf(to, sizeof(to), "<%s%s>;tag=%s", (strncasecmp(p->uri, "sip:", 4) ? "sip:" : ""), p->uri, p->theirtag);
10141       } else if (p->options && p->options->vxml_url) {
10142          /* If there is a VXML URL append it to the SIP URL */
10143          snprintf(to, sizeof(to), "<%s>;%s", p->uri, p->options->vxml_url);
10144       } else 
10145          snprintf(to, sizeof(to), "<%s>", p->uri);
10146    }
10147 
10148    init_req(req, sipmethod, p->uri);
10149    /* now tmp_n is available so reuse it to build the CSeq */
10150    snprintf(tmp_n, sizeof(tmp_n), "%d %s", ++p->ocseq, sip_methods[sipmethod].text);
10151 
10152    add_header(req, "Via", p->via);
10153    add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
10154    /* This will be a no-op most of the time. However, under certain circumstances,
10155     * NOTIFY messages will use this function for preparing the request and should
10156     * have Route headers present.
10157     */
10158    add_route(req, p->route);
10159 
10160    /* Build Remote Party-ID and From */
10161    if (ast_test_flag(&p->flags[0], SIP_SENDRPID) && (sipmethod == SIP_INVITE)) {
10162       build_rpid(p);
10163       add_header(req, "From", p->rpid_from);
10164    } else 
10165       add_header(req, "From", from);
10166    add_header(req, "To", to);
10167    ast_string_field_set(p, exten, l);
10168    build_contact(p);
10169    add_header(req, "Contact", p->our_contact);
10170    add_header(req, "Call-ID", p->callid);
10171    add_header(req, "CSeq", tmp_n);
10172    if (!ast_strlen_zero(global_useragent))
10173       add_header(req, "User-Agent", global_useragent);
10174    if (!ast_strlen_zero(p->rpid))
10175       add_header(req, "Remote-Party-ID", p->rpid);
10176 }

static const char * insecure2str ( int  mode  )  const [static]

Convert Insecure setting to printable string.

Definition at line 14148 of file chan_sip.c.

References insecurestr, and map_x_s().

Referenced by _sip_show_peer().

14149 {
14150    return map_x_s(insecurestr, mode, "<error>");
14151 }

static void interpret_t38_parameters ( struct sip_pvt p,
const struct ast_control_t38_parameters parameters 
) [static]

Helper function which updates T.38 capability information and triggers a reinvite.

Definition at line 6016 of file chan_sip.c.

References AST_SCHED_DEL_UNREF, ast_set_flag, AST_T38_NEGOTIATED, AST_T38_REFUSED, AST_T38_REQUEST_NEGOTIATE, AST_T38_REQUEST_TERMINATE, AST_T38_TERMINATED, ast_test_flag, ast_udptl_set_local_max_ifp(), change_t38_state(), dialog_unref(), FALSE, ast_control_t38_parameters::fill_bit_removal, sip_pvt::flags, sip_pvt::initreq, ast_control_t38_parameters::max_ifp, MIN, t38properties::our_parms, sip_pvt::pendinginvite, ast_control_t38_parameters::rate_management, ast_control_t38_parameters::request_response, sched, SIP_NEEDREINVITE, SIP_PAGE2_T38SUPPORT, SIP_PENDINGBYE, t38properties::state, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_REINVITE, T38_PEER_REINVITE, sip_pvt::t38id, t38properties::their_parms, ast_control_t38_parameters::transcoding_jbig, ast_control_t38_parameters::transcoding_mmr, transmit_reinvite_with_sdp(), transmit_response_reliable(), transmit_response_with_t38_sdp(), TRUE, sip_pvt::udptl, ast_control_t38_parameters::version, and XMIT_CRITICAL.

Referenced by sip_indicate().

06017 {
06018    if (!ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) {
06019       return;
06020    }
06021    switch (parameters->request_response) {
06022    case AST_T38_NEGOTIATED:
06023    case AST_T38_REQUEST_NEGOTIATE:         /* Request T38 */
06024       /* Negotiation can not take place without a valid max_ifp value. */
06025       if (!parameters->max_ifp) {
06026             change_t38_state(p, T38_DISABLED);
06027             if (p->t38.state == T38_PEER_REINVITE) {
06028                AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr"));
06029                transmit_response_reliable(p, "488 Not acceptable here", &p->initreq);
06030             }
06031             break;
06032       } else if (p->t38.state == T38_PEER_REINVITE) {
06033          AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr"));
06034          p->t38.our_parms = *parameters;
06035          /* modify our parameters to conform to the peer's parameters,
06036           * based on the rules in the ITU T.38 recommendation
06037           */
06038          if (!p->t38.their_parms.fill_bit_removal) {
06039             p->t38.our_parms.fill_bit_removal = FALSE;
06040          }
06041          if (!p->t38.their_parms.transcoding_mmr) {
06042             p->t38.our_parms.transcoding_mmr = FALSE;
06043          }
06044          if (!p->t38.their_parms.transcoding_jbig) {
06045             p->t38.our_parms.transcoding_jbig = FALSE;
06046          }
06047          p->t38.our_parms.version = MIN(p->t38.our_parms.version, p->t38.their_parms.version);
06048          p->t38.our_parms.rate_management = p->t38.their_parms.rate_management;
06049          ast_udptl_set_local_max_ifp(p->udptl, p->t38.our_parms.max_ifp);
06050          change_t38_state(p, T38_ENABLED);
06051          transmit_response_with_t38_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL);
06052       } else if (p->t38.state != T38_ENABLED) {
06053          p->t38.our_parms = *parameters;
06054          ast_udptl_set_local_max_ifp(p->udptl, p->t38.our_parms.max_ifp);
06055          change_t38_state(p, T38_LOCAL_REINVITE);
06056          if (!p->pendinginvite) {
06057             transmit_reinvite_with_sdp(p, TRUE, FALSE);
06058          } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
06059             ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
06060          }
06061       }
06062       break;
06063    case AST_T38_TERMINATED:
06064    case AST_T38_REFUSED:
06065    case AST_T38_REQUEST_TERMINATE:         /* Shutdown T38 */
06066       if (p->t38.state == T38_PEER_REINVITE) {
06067          AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr"));
06068          change_t38_state(p, T38_DISABLED);
06069          transmit_response_reliable(p, "488 Not acceptable here", &p->initreq);
06070       } else if (p->t38.state == T38_ENABLED)
06071          transmit_reinvite_with_sdp(p, FALSE, FALSE);
06072       break;
06073    default:
06074       break;
06075    }
06076 }

static void list_route ( struct sip_route route  )  [static]

List all routes - mostly for debugging.

Definition at line 11639 of file chan_sip.c.

References ast_verbose, sip_route::hop, and sip_route::next.

Referenced by build_route().

11640 {
11641    if (!route)
11642       ast_verbose("list_route: no route\n");
11643    else {
11644       for (;route; route = route->next)
11645          ast_verbose("list_route: hop: <%s>\n", route->hop);
11646    }
11647 }

static int load_module ( void   )  [static]

PBX load module - initialization.

Todo:
Fix this XXX This must be all wrong XXXX

Definition at line 24682 of file chan_sip.c.

References ao2_t_container_alloc, ast_channel_register(), ast_check_realtime(), ast_cli_register_multiple(), ast_custom_function_register, ast_log(), ast_manager_register2(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_FAILURE, AST_MODULE_LOAD_SUCCESS, ast_realtime_require_field(), ast_register_application, ast_rtp_proto_register(), ast_udptl_proto_register(), ast_verbose, ASTOBJ_CONTAINER_INIT, CHANNEL_MODULE_LOAD, checksipdomain_function, cli_sip, dialog_cmp_cb(), dialog_hash_cb(), dialogs, EVENT_FLAG_REPORTING, EVENT_FLAG_SYSTEM, io, io_context_create(), io_context_destroy(), LOG_ERROR, manager_show_registry(), manager_sip_qualify_peer(), manager_sip_show_peer(), manager_sip_show_peers(), manager_sipnotify(), mandescr_show_peer, mandescr_show_peers, mandescr_show_registry, mandescr_sipnotify, peer_cmp_cb(), peer_hash_cb(), peer_ipcmp_cb(), peer_iphash_cb(), peers, peers_by_ip, regl, reload_config(), restart_monitor(), RQ_CHAR, RQ_INTEGER4, RQ_UINTEGER2, sched, sched_context_create(), sched_context_destroy(), ast_channel_tech::send_digit_begin, SENTINEL, sip_addheader(), sip_dtmfmode(), sip_header_function, sip_poke_all_peers(), sip_rtp, sip_send_all_registers(), sip_tech, sip_tech_info, sip_udptl, sipchaninfo_function, sippeer_function, threadt, threadt_cmp_cb(), and threadt_hash_cb().

24683 {
24684    ast_verbose("SIP channel loading...\n");
24685    /* the fact that ao2_containers can't resize automatically is a major worry! */
24686    /* if the number of objects gets above MAX_XXX_BUCKETS, things will slow down */
24687    peers = ao2_t_container_alloc(hash_peer_size, peer_hash_cb, peer_cmp_cb, "allocate peers");
24688    peers_by_ip = ao2_t_container_alloc(hash_peer_size, peer_iphash_cb, peer_ipcmp_cb, "allocate peers_by_ip");
24689    dialogs = ao2_t_container_alloc(hash_dialog_size, dialog_hash_cb, dialog_cmp_cb, "allocate dialogs");
24690    threadt = ao2_t_container_alloc(hash_dialog_size, threadt_hash_cb, threadt_cmp_cb, "allocate threadt table");
24691    
24692    ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list -- not searched for anything */
24693 
24694    if (!(sched = sched_context_create())) {
24695       ast_log(LOG_ERROR, "Unable to create scheduler context\n");
24696       return AST_MODULE_LOAD_FAILURE;
24697    }
24698 
24699    if (!(io = io_context_create())) {
24700       ast_log(LOG_ERROR, "Unable to create I/O context\n");
24701       sched_context_destroy(sched);
24702       return AST_MODULE_LOAD_FAILURE;
24703    }
24704 
24705    sip_reloadreason = CHANNEL_MODULE_LOAD;
24706 
24707    if(reload_config(sip_reloadreason)) /* Load the configuration from sip.conf */
24708       return AST_MODULE_LOAD_DECLINE;
24709 
24710    /* Prepare the version that does not require DTMF BEGIN frames.
24711     * We need to use tricks such as memcpy and casts because the variable
24712     * has const fields.
24713     */
24714    memcpy(&sip_tech_info, &sip_tech, sizeof(sip_tech));
24715    memset((void *) &sip_tech_info.send_digit_begin, 0, sizeof(sip_tech_info.send_digit_begin));
24716 
24717    /* Make sure we can register our sip channel type */
24718    if (ast_channel_register(&sip_tech)) {
24719       ast_log(LOG_ERROR, "Unable to register channel type 'SIP'\n");
24720       io_context_destroy(io);
24721       sched_context_destroy(sched);
24722       return AST_MODULE_LOAD_FAILURE;
24723    }
24724 
24725    /* Register all CLI functions for SIP */
24726    ast_cli_register_multiple(cli_sip, sizeof(cli_sip)/ sizeof(struct ast_cli_entry));
24727 
24728    /* Tell the RTP subdriver that we're here */
24729    ast_rtp_proto_register(&sip_rtp);
24730 
24731    /* Tell the UDPTL subdriver that we're here */
24732    ast_udptl_proto_register(&sip_udptl);
24733 
24734    /* Register dialplan applications */
24735    ast_register_application(app_dtmfmode, sip_dtmfmode, synopsis_dtmfmode, descrip_dtmfmode);
24736    ast_register_application(app_sipaddheader, sip_addheader, synopsis_sipaddheader, descrip_sipaddheader);
24737 
24738    /* Register dialplan functions */
24739    ast_custom_function_register(&sip_header_function);
24740    ast_custom_function_register(&sippeer_function);
24741    ast_custom_function_register(&sipchaninfo_function);
24742    ast_custom_function_register(&checksipdomain_function);
24743 
24744    /* Register manager commands */
24745    ast_manager_register2("SIPpeers", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_show_peers,
24746          "List SIP peers (text format)", mandescr_show_peers);
24747    ast_manager_register2("SIPshowpeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_show_peer,
24748          "Show SIP peer (text format)", mandescr_show_peer);
24749    ast_manager_register2("SIPqualifypeer", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_sip_qualify_peer,
24750          "Show SIP peer (text format)", mandescr_show_peer);   /*! \todo Fix this XXX This must be all wrong XXXX */
24751    ast_manager_register2("SIPshowregistry", EVENT_FLAG_SYSTEM | EVENT_FLAG_REPORTING, manager_show_registry,
24752          "Show SIP registrations (text format)", mandescr_show_registry);
24753    ast_manager_register2("SIPnotify", EVENT_FLAG_SYSTEM, manager_sipnotify,
24754          "Send a SIP notify", mandescr_sipnotify);
24755    sip_poke_all_peers();   
24756    sip_send_all_registers();
24757    
24758    /* And start the monitor for the first time */
24759    restart_monitor();
24760 
24761    ast_realtime_require_field(ast_check_realtime("sipregs") ? "sipregs" : "sippeers",
24762       "name", RQ_CHAR, 10,
24763       "ipaddr", RQ_CHAR, 15,
24764       "port", RQ_UINTEGER2, 5,
24765       "regseconds", RQ_INTEGER4, 11,
24766       "defaultuser", RQ_CHAR, 10,
24767       "fullcontact", RQ_CHAR, 35,
24768       "regserver", RQ_CHAR, 20,
24769       "useragent", RQ_CHAR, 20,
24770       "lastms", RQ_INTEGER4, 11,
24771       SENTINEL);
24772 
24773    return AST_MODULE_LOAD_SUCCESS;
24774 }

static int local_attended_transfer ( struct sip_pvt transferer,
struct sip_dual current,
struct sip_request req,
int  seqno 
) [static]

Find all call legs and bridge transferee with target called from handle_request_refer.

Definition at line 19497 of file chan_sip.c.

References ast_channel::_state, ao2_t_ref, append_history, ast_bridged_channel(), ast_channel_unlock, ast_clear_flag, ast_debug, ast_set_flag, ast_state2str(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, attempt_transfer(), sip_pvt::callid, sip_dual::chan1, sip_dual::chan2, EVENT_FLAG_CALL, sip_pvt::flags, get_sip_pvt_byid_locked(), sip_refer::localtransfer, manager_event, ast_channel::name, sip_pvt::owner, sip_pvt::refer, REFER_200OK, REFER_FAILED, sip_refer::replaces_callid, sip_refer::replaces_callid_fromtag, sip_refer::replaces_callid_totag, SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, sip_pvt_unlock, sip_refer::status, transmit_notify_with_sipfrag(), transmit_response(), TRUE, and ast_channel::uniqueid.

Referenced by handle_request_refer().

19498 {
19499    struct sip_dual target;    /* Chan 1: Call from tranferer to Asterisk */
19500                /* Chan 2: Call from Asterisk to target */
19501    int res = 0;
19502    struct sip_pvt *targetcall_pvt;
19503 
19504    /* Check if the call ID of the replaces header does exist locally */
19505    if (!(targetcall_pvt = get_sip_pvt_byid_locked(transferer->refer->replaces_callid, transferer->refer->replaces_callid_totag, 
19506       transferer->refer->replaces_callid_fromtag))) {
19507       if (transferer->refer->localtransfer) {
19508          /* We did not find the refered call. Sorry, can't accept then */
19509          transmit_response(transferer, "202 Accepted", req);
19510          /* Let's fake a response from someone else in order
19511             to follow the standard */
19512          transmit_notify_with_sipfrag(transferer, seqno, "481 Call leg/transaction does not exist", TRUE);
19513          append_history(transferer, "Xfer", "Refer failed");
19514          ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);  
19515          transferer->refer->status = REFER_FAILED;
19516          return -1;
19517       }
19518       /* Fall through for remote transfers that we did not find locally */
19519       ast_debug(3, "SIP attended transfer: Not our call - generating INVITE with replaces\n");
19520       return 0;
19521    }
19522 
19523    /* Ok, we can accept this transfer */
19524    transmit_response(transferer, "202 Accepted", req);
19525    append_history(transferer, "Xfer", "Refer accepted");
19526    if (!targetcall_pvt->owner) { /* No active channel */
19527       ast_debug(4, "SIP attended transfer: Error: No owner of target call\n");
19528       /* Cancel transfer */
19529       transmit_notify_with_sipfrag(transferer, seqno, "503 Service Unavailable", TRUE);
19530       append_history(transferer, "Xfer", "Refer failed");
19531       ast_clear_flag(&transferer->flags[0], SIP_GOTREFER);
19532       transferer->refer->status = REFER_FAILED;
19533       sip_pvt_unlock(targetcall_pvt);
19534       if (targetcall_pvt)
19535          ao2_t_ref(targetcall_pvt, -1, "Drop targetcall_pvt pointer");
19536       return -1;
19537    }
19538 
19539    /* We have a channel, find the bridge */
19540    target.chan1 = targetcall_pvt->owner;           /* Transferer to Asterisk */
19541    target.chan2 = ast_bridged_channel(targetcall_pvt->owner);  /* Asterisk to target */
19542 
19543    if (!target.chan2 || !(target.chan2->_state == AST_STATE_UP || target.chan2->_state == AST_STATE_RINGING) ) {
19544       /* Wrong state of new channel */
19545       if (target.chan2) 
19546          ast_debug(4, "SIP attended transfer: Error: Wrong state of target call: %s\n", ast_state2str(target.chan2->_state));
19547       else if (target.chan1->_state != AST_STATE_RING)
19548          ast_debug(4, "SIP attended transfer: Error: No target channel\n");
19549       else
19550          ast_debug(4, "SIP attended transfer: Attempting transfer in ringing state\n");
19551    }
19552 
19553    /* Transfer */
19554    if (sipdebug) {
19555       if (current->chan2)  /* We have two bridges */
19556          ast_debug(4, "SIP attended transfer: trying to bridge %s and %s\n", target.chan1->name, current->chan2->name);
19557       else        /* One bridge, propably transfer of IVR/voicemail etc */
19558          ast_debug(4, "SIP attended transfer: trying to make %s take over (masq) %s\n", target.chan1->name, current->chan1->name);
19559    }
19560 
19561    ast_set_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);   /* Delay hangup */
19562 
19563    /* Perform the transfer */
19564    manager_event(EVENT_FLAG_CALL, "Transfer", "TransferMethod: SIP\r\nTransferType: Attended\r\nChannel: %s\r\nUniqueid: %s\r\nSIP-Callid: %s\r\nTargetChannel: %s\r\nTargetUniqueid: %s\r\n",
19565       transferer->owner->name,
19566       transferer->owner->uniqueid,
19567       transferer->callid,
19568       target.chan1->name,
19569       target.chan1->uniqueid);
19570    res = attempt_transfer(current, &target);
19571    sip_pvt_unlock(targetcall_pvt);
19572    if (res) {
19573       /* Failed transfer */
19574       transmit_notify_with_sipfrag(transferer, seqno, "486 Busy Here", TRUE);
19575       append_history(transferer, "Xfer", "Refer failed");
19576       if (targetcall_pvt->owner)
19577          ast_channel_unlock(targetcall_pvt->owner);
19578       ast_clear_flag(&transferer->flags[0], SIP_DEFER_BYE_ON_TRANSFER);
19579    } else {
19580       /* Transfer succeeded! */
19581 
19582       /* Tell transferer that we're done. */
19583       transmit_notify_with_sipfrag(transferer, seqno, "200 OK", TRUE);
19584       append_history(transferer, "Xfer", "Refer succeeded");
19585       transferer->refer->status = REFER_200OK;
19586       if (targetcall_pvt->owner) {
19587          ast_debug(1, "SIP attended transfer: Unlocking channel %s\n", targetcall_pvt->owner->name);
19588          ast_channel_unlock(targetcall_pvt->owner);
19589       }
19590    }
19591    if (targetcall_pvt)
19592       ao2_t_ref(targetcall_pvt, -1, "drop targetcall_pvt");
19593    return 1;
19594 }

static int lws2sws ( char *  msgbuf,
int  len 
) [static]

Parse multiline SIP headers into one header This is enabled if pedanticsipchecking is enabled.

Definition at line 7152 of file chan_sip.c.

Referenced by handle_request_do().

07153 {
07154    int h = 0, t = 0; 
07155    int lws = 0; 
07156 
07157    for (; h < len;) { 
07158       /* Eliminate all CRs */ 
07159       if (msgbuf[h] == '\r') { 
07160          h++; 
07161          continue; 
07162       } 
07163       /* Check for end-of-line */ 
07164       if (msgbuf[h] == '\n') { 
07165          /* Check for end-of-message */ 
07166          if (h + 1 == len) 
07167             break; 
07168          /* Check for a continuation line */ 
07169          if (msgbuf[h + 1] == ' ' || msgbuf[h + 1] == '\t') { 
07170             /* Merge continuation line */ 
07171             h++; 
07172             continue; 
07173          } 
07174          /* Propagate LF and start new line */ 
07175          msgbuf[t++] = msgbuf[h++]; 
07176          lws = 0;
07177          continue; 
07178       } 
07179       if (msgbuf[h] == ' ' || msgbuf[h] == '\t') { 
07180          if (lws) { 
07181             h++; 
07182             continue; 
07183          } 
07184          msgbuf[t++] = msgbuf[h++]; 
07185          lws = 1; 
07186          continue; 
07187       } 
07188       msgbuf[t++] = msgbuf[h++]; 
07189       if (lws) 
07190          lws = 0; 
07191    } 
07192    msgbuf[t] = '\0'; 
07193    return t; 
07194 }

static void make_our_tag ( char *  tagbuf,
size_t  len 
) [static]

Make our SIP dialog tag.

Definition at line 6708 of file chan_sip.c.

References ast_random().

Referenced by handle_request_invite(), handle_request_subscribe(), sip_alloc(), transmit_register(), and transmit_response_using_temp().

06709 {
06710    snprintf(tagbuf, len, "as%08lx", ast_random());
06711 }

static int manager_show_registry ( struct mansession s,
const struct message m 
) [static]

Show SIP registrations in the manager API.

Definition at line 13790 of file chan_sip.c.

References ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, regl, regstate2str(), s, STANDARD_SIP_PORT, and total.

Referenced by load_module().

13791 {
13792    const char *id = astman_get_header(m, "ActionID");
13793    char idtext[256] = "";
13794    int total = 0;
13795 
13796    if (!ast_strlen_zero(id))
13797       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
13798 
13799    astman_send_listack(s, m, "Registrations will follow", "start");
13800 
13801    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
13802       ASTOBJ_RDLOCK(iterator);
13803       astman_append(s,
13804          "Event: RegistryEntry\r\n"
13805          "%s"
13806          "Host: %s\r\n"
13807          "Port: %d\r\n"
13808          "Username: %s\r\n"
13809          "Refresh: %d\r\n"
13810          "State: %s\r\n"
13811          "RegistrationTime: %ld\r\n"
13812          "\r\n", idtext, iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT,
13813                  iterator->username, iterator->refresh, regstate2str(iterator->regstate), (long) iterator->regtime.tv_sec);
13814       ASTOBJ_UNLOCK(iterator);
13815       total++;
13816    } while(0));
13817 
13818    astman_append(s,
13819       "Event: RegistrationsComplete\r\n"
13820       "EventList: Complete\r\n"
13821       "ListItems: %d\r\n"
13822       "%s"
13823       "\r\n", total, idtext);
13824    
13825    return 0;
13826 }

static int manager_sip_qualify_peer ( struct mansession s,
const struct message m 
) [static]

Qualify SIP peers in the manager API.

Definition at line 14517 of file chan_sip.c.

References _sip_qualify_peer(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), and s.

Referenced by load_module().

14518 {
14519    const char *a[4];
14520    const char *peer;
14521 
14522    peer = astman_get_header(m, "Peer");
14523    if (ast_strlen_zero(peer)) {
14524       astman_send_error(s, m, "Peer: <name> missing.");
14525       return 0;
14526    }
14527    a[0] = "sip";
14528    a[1] = "qualify";
14529    a[2] = "peer";
14530    a[3] = peer;
14531 
14532    _sip_qualify_peer(1, -1, s, m, 4, a);
14533    astman_append(s, "\r\n\r\n" );
14534    return 0;
14535 }

static int manager_sip_show_peer ( struct mansession s,
const struct message m 
) [static]

Show SIP peers in the manager API.

Definition at line 14458 of file chan_sip.c.

References _sip_show_peer(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), and s.

Referenced by load_module().

14459 {
14460    const char *a[4];
14461    const char *peer;
14462 
14463    peer = astman_get_header(m, "Peer");
14464    if (ast_strlen_zero(peer)) {
14465       astman_send_error(s, m, "Peer: <name> missing.");
14466       return 0;
14467    }
14468    a[0] = "sip";
14469    a[1] = "show";
14470    a[2] = "peer";
14471    a[3] = peer;
14472 
14473    _sip_show_peer(1, -1, s, m, 4, a);
14474    astman_append(s, "\r\n\r\n" );
14475    return 0;
14476 }

static int manager_sip_show_peers ( struct mansession s,
const struct message m 
) [static]

Show SIP peers in the manager API.

Definition at line 13837 of file chan_sip.c.

References _sip_show_peers(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_listack(), s, and total.

Referenced by load_module().

13838 {
13839    const char *id = astman_get_header(m, "ActionID");
13840    const char *a[] = {"sip", "show", "peers"};
13841    char idtext[256] = "";
13842    int total = 0;
13843 
13844    if (!ast_strlen_zero(id))
13845       snprintf(idtext, sizeof(idtext), "ActionID: %s\r\n", id);
13846 
13847    astman_send_listack(s, m, "Peer status list will follow", "start");
13848    /* List the peers in separate manager events */
13849    _sip_show_peers(-1, &total, s, m, 3, a);
13850    /* Send final confirmation */
13851    astman_append(s,
13852    "Event: PeerlistComplete\r\n"
13853    "EventList: Complete\r\n"
13854    "ListItems: %d\r\n"
13855    "%s"
13856    "\r\n", total, idtext);
13857    return 0;
13858 }

static int manager_sipnotify ( struct mansession s,
const struct message m 
) [static]

Definition at line 10594 of file chan_sip.c.

References ao2_t_link, ao2_t_unlink, ast_set_flag, ast_sip_ouraddrfor(), ast_strlen_zero(), ast_variables_destroy(), astman_get_header(), astman_get_variables(), astman_send_ack(), astman_send_error(), build_callid_pvt(), build_via(), create_addr(), dialog_ref(), dialog_unlink_all(), dialog_unref(), dialogs, sip_pvt::flags, sip_pvt::ourip, s, sip_pvt::sa, sip_alloc(), SIP_NOTIFY, SIP_OUTGOING, sip_scheddestroy(), SIP_TRANS_TIMEOUT, transmit_notify_custom(), and TRUE.

Referenced by load_module().

10595 {
10596    const char *channame = astman_get_header(m, "Channel");
10597    struct ast_variable *vars = astman_get_variables(m);
10598    struct sip_pvt *p;
10599 
10600    if (ast_strlen_zero(channame)) {
10601       astman_send_error(s, m, "SIPNotify requires a channel name");
10602       return 0;
10603    }
10604 
10605    if (!strncasecmp(channame, "sip/", 4)) {
10606       channame += 4;
10607    }
10608 
10609    if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) {
10610       astman_send_error(s, m, "Unable to build sip pvt data for notify (memory/socket error)");
10611       return 0;
10612    }
10613 
10614    if (create_addr(p, channame, NULL, 0)) {
10615       /* Maybe they're not registered, etc. */
10616       dialog_unlink_all(p, TRUE, TRUE);
10617       dialog_unref(p, "unref dialog inside for loop" );
10618       /* sip_destroy(p); */
10619       astman_send_error(s, m, "Could not create address");
10620       return 0;
10621    }
10622 
10623    /* Notify is outgoing call */
10624    ast_set_flag(&p->flags[0], SIP_OUTGOING);
10625 
10626    /* Recalculate our side, and recalculate Call ID */
10627    ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip, p);
10628    build_via(p);
10629    ao2_t_unlink(dialogs, p, "About to change the callid -- remove the old name");
10630    build_callid_pvt(p);
10631    ao2_t_link(dialogs, p, "Linking in new name");
10632    dialog_ref(p, "bump the count of p, which transmit_sip_request will decrement.");
10633    sip_scheddestroy(p, SIP_TRANS_TIMEOUT);
10634 
10635    if (!transmit_notify_custom(p, vars)) {
10636       astman_send_ack(s, m, "Notify Sent");
10637    } else {
10638       astman_send_error(s, m, "Unable to send notify");
10639    }
10640    ast_variables_destroy(vars);
10641    return 0;
10642 }

static int map_s_x ( const struct _map_x_s table,
const char *  s,
int  errorvalue 
) [static]

map from a string to an integer value, case insensitive. If no match is found, return errorvalue.

Definition at line 2390 of file chan_sip.c.

References _map_x_s::s, table, and _map_x_s::x.

Referenced by str2dtmfmode(), str2stmode(), and str2strefresher().

02391 {
02392    const struct _map_x_s *cur;
02393 
02394    for (cur = table; cur->s; cur++)
02395       if (!strcasecmp(cur->s, s))
02396          return cur->x;
02397    return errorvalue;
02398 }

static const char* map_x_s ( const struct _map_x_s table,
int  x,
const char *  errorstring 
) [static]

map from an integer value to a string. If no match is found, return errorstring

Definition at line 2377 of file chan_sip.c.

References _map_x_s::s, table, and _map_x_s::x.

Referenced by dtmfmode2str(), faxec2str(), insecure2str(), nat2str(), referstatus2str(), regstate2str(), stmode2str(), and strefresher2str().

02378 {
02379    const struct _map_x_s *cur;
02380 
02381    for (cur = table; cur->s; cur++)
02382       if (cur->x == x)
02383          return cur->s;
02384    return errorstring;
02385 }

static int method_match ( enum sipmethod  id,
const char *  name 
) [static]

returns true if 'name' (with optional trailing whitespace) matches the sip method 'id'. Strictly speaking, SIP methods are case SENSITIVE, but we do a case-insensitive comparison to be more tolerant. following Jon Postel's rule: Be gentle in what you accept, strict with what you send

Definition at line 2988 of file chan_sip.c.

References sip_methods, and text.

Referenced by __sip_autodestruct(), __sip_semi_ack(), and find_sip_method().

02989 {
02990    int len = strlen(sip_methods[id].text);
02991    int l_name = name ? strlen(name) : 0;
02992    /* true if the string is long enough, and ends with whitespace, and matches */
02993    return (l_name >= len && name[len] < 33 &&
02994       !strncasecmp(sip_methods[id].text, name, len));
02995 }

static void mwi_event_cb ( const struct ast_event ,
void *   
) [static]

Receive MWI events that we have subscribed to.

Definition at line 11970 of file chan_sip.c.

References ao2_lock(), ao2_unlock(), and sip_send_mwi_to_peer().

11971 {
11972    struct sip_peer *peer = userdata;
11973 
11974    ao2_lock(peer);
11975    sip_send_mwi_to_peer(peer, event, 0);
11976    ao2_unlock(peer);
11977 }

static const char * nat2str ( int  nat  )  const [static]

Convert NAT setting to text string.

Definition at line 13572 of file chan_sip.c.

References map_x_s(), and natmodes.

Referenced by _sip_show_peer(), sip_show_channel(), sip_show_settings(), and sip_show_users().

13573 {
13574    return map_x_s(natmodes, nat, "Unknown");
13575 }

static struct sip_proxy* obproxy_get ( struct sip_pvt dialog,
struct sip_peer peer 
) [static]

Get default outbound proxy or global proxy.

Definition at line 2963 of file chan_sip.c.

References append_history, ast_debug, global_outboundproxy, sip_proxy::name, and sip_peer::outboundproxy.

Referenced by create_addr(), create_addr_from_peer(), and transmit_register().

02964 {
02965    if (peer && peer->outboundproxy) {
02966       if (sipdebug)
02967          ast_debug(1, "OBPROXY: Applying peer OBproxy to this call\n");
02968       append_history(dialog, "OBproxy", "Using peer obproxy %s", peer->outboundproxy->name);
02969       return peer->outboundproxy;
02970    }
02971    if (global_outboundproxy.name[0]) {
02972       if (sipdebug)
02973          ast_debug(1, "OBPROXY: Applying global OBproxy to this call\n");
02974       append_history(dialog, "OBproxy", "Using global obproxy %s", global_outboundproxy.name);
02975       return &global_outboundproxy;
02976    }
02977    if (sipdebug)
02978       ast_debug(1, "OBPROXY: Not applying OBproxy to this call\n");
02979    return NULL;
02980 }

static void parse_copy ( struct sip_request dst,
const struct sip_request src 
) [static]

Copy SIP request, parse it.

Definition at line 3756 of file chan_sip.c.

References copy_request(), and parse_request().

Referenced by send_request(), and send_response().

03757 {
03758    copy_request(dst, src);
03759    parse_request(dst);
03760 }

int parse_minse ( const char *  p_hdrval,
int *const   p_interval 
) [static]

Session-Timers: Function for parsing Min-SE header.

Definition at line 21732 of file chan_sip.c.

References ast_debug, ast_log(), ast_skip_blanks(), ast_strlen_zero(), and LOG_WARNING.

Referenced by handle_request_invite(), and proc_422_rsp().

21733 {
21734    if (ast_strlen_zero(p_hdrval)) {
21735       ast_log(LOG_WARNING, "Null Min-SE header\n");
21736       return -1;
21737    }
21738 
21739    *p_interval = 0;
21740    p_hdrval = ast_skip_blanks(p_hdrval);
21741    if (!sscanf(p_hdrval, "%30d", p_interval)) {
21742       ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval);
21743       return -1;
21744    }
21745 
21746    ast_debug(2, "Received Min-SE: %d\n", *p_interval);
21747    return 0;
21748 }

static void parse_moved_contact ( struct sip_pvt p,
struct sip_request req 
) [static]

Parse 302 Moved temporalily response.

Definition at line 16697 of file chan_sip.c.

References ao2_ref, ast_copy_string(), ast_debug, ast_string_field_build, ast_string_field_set, ast_test_flag, sip_pvt::flags, get_header(), get_in_brackets(), get_transport(), sip_pvt::owner, pbx_builtin_setvar_helper(), remove_uri_parameters(), s, set_socket_transport(), SIP_PROMISCREDIR, SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, SIP_TRANSPORT_UDP, SIPBUFSIZE, sip_pvt::socket, strcasestr(), and sip_socket::tcptls_session.

Referenced by handle_response().

16698 {
16699    char tmp[SIPBUFSIZE];
16700    char *s, *e, *t, *trans;
16701    char *domain;
16702    enum sip_transport transport = SIP_TRANSPORT_UDP;
16703 
16704    ast_copy_string(tmp, get_header(req, "Contact"), sizeof(tmp));
16705    if ((t = strchr(tmp, ',')))
16706       *t = '\0';
16707 
16708    s = get_in_brackets(tmp);
16709    if ((trans = strcasestr(s, ";transport="))) do {
16710       trans += 11;
16711 
16712       if ((e = strchr(trans, ';')))
16713          *e = '\0';
16714 
16715       if (!strncasecmp(trans, "tcp", 3))
16716          transport = SIP_TRANSPORT_TCP;
16717       else if (!strncasecmp(trans, "tls", 3))
16718          transport = SIP_TRANSPORT_TLS;
16719       else {
16720          if (strncasecmp(trans, "udp", 3))
16721             ast_debug(1, "received contact with an invalid transport, '%s'\n", s);
16722          transport = SIP_TRANSPORT_UDP;
16723       }
16724    } while(0);
16725    s = remove_uri_parameters(s);
16726 
16727    if (p->socket.tcptls_session) {
16728       ao2_ref(p->socket.tcptls_session, -1);
16729       p->socket.tcptls_session = NULL;
16730    }
16731 
16732    set_socket_transport(&p->socket, transport);
16733 
16734    if (ast_test_flag(&p->flags[0], SIP_PROMISCREDIR)) {
16735       char *host = NULL;
16736       if (!strncasecmp(s, "sip:", 4))
16737          s += 4;
16738       else if (!strncasecmp(s, "sips:", 5))
16739          s += 5;
16740       e = strchr(s, '/');
16741       if (e)
16742          *e = '\0';
16743       if ((host = strchr(s, '@'))) {
16744          *host++ = '\0';
16745          ast_debug(2, "Found promiscuous redirection to 'SIP/%s::::%s@%s'\n", s, get_transport(transport), host);
16746          if (p->owner)
16747             ast_string_field_build(p->owner, call_forward, "SIP/%s::::%s@%s", s, get_transport(transport), host);
16748       } else {
16749          ast_debug(2, "Found promiscuous redirection to 'SIP/::::%s@%s'\n", get_transport(transport), s);
16750          if (p->owner)
16751             ast_string_field_build(p->owner, call_forward, "SIP/::::%s@%s", get_transport(transport), s);
16752       }
16753    } else {
16754       e = strchr(tmp, '@');
16755       if (e) {
16756          *e++ = '\0';
16757          domain = e;
16758       } else {
16759          /* No username part */
16760          domain = tmp;
16761       }
16762       e = strchr(tmp, '/');   /* WHEN do we hae a forward slash in the URI? */
16763       if (e)
16764          *e = '\0';
16765 
16766       if (!strncasecmp(s, "sip:", 4))
16767          s += 4;
16768       else if (!strncasecmp(s, "sips:", 5))
16769          s += 5;
16770       e = strchr(s, ';');  /* And username ; parameters? */
16771       if (e)
16772          *e = '\0';  
16773       ast_debug(2, "Received 302 Redirect to extension '%s' (domain %s)\n", s, domain);
16774       if (p->owner) {
16775          pbx_builtin_setvar_helper(p->owner, "SIPDOMAIN", domain);
16776          ast_string_field_set(p->owner, call_forward, s);
16777       }
16778    }
16779 }

static int parse_ok_contact ( struct sip_pvt pvt,
struct sip_request req 
) [static]

Save contact header for 200 OK on INVITE.

Definition at line 11347 of file chan_sip.c.

References ast_copy_string(), ast_string_field_set, get_header(), get_in_brackets(), SIPBUFSIZE, and TRUE.

Referenced by handle_request_invite(), handle_request_subscribe(), and handle_response_invite().

11348 {
11349    char contact[SIPBUFSIZE]; 
11350    char *c;
11351 
11352    /* Look for brackets */
11353    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
11354    c = get_in_brackets(contact);
11355 
11356    /* Save full contact to call pvt for later bye or re-invite */
11357    ast_string_field_set(pvt, fullcontact, c);
11358 
11359    /* Save URI for later ACKs, BYE or RE-invites */
11360    ast_string_field_set(pvt, okcontacturi, c);
11361 
11362    /* We should return false for URI:s we can't handle,
11363       like tel:, mailto:,ldap: etc */
11364    return TRUE;      
11365 }

static enum parse_register_result parse_register_contact ( struct sip_pvt pvt,
struct sip_peer p,
struct sip_request req 
) [static]

Parse contact header and save registration (peer registration).

Definition at line 11426 of file chan_sip.c.

References sip_peer::addr, ahp, ao2_t_link, ao2_t_unlink, ast_apply_ha(), ast_copy_string(), ast_db_put(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_sched_add(), AST_SCHED_DEL_UNREF, ast_sched_when(), AST_SENSE_ALLOW, ast_string_field_build, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_verb, ast_verbose, sip_peer::contactha, copy_socket_data(), sip_request::data, sip_peer::default_outbound_transport, destroy_association(), EVENT_FLAG_SYSTEM, sip_peer::expire, expire_register(), sip_pvt::expiry, FALSE, sip_peer::flags, sip_peer::fullcontact, get_header(), get_in_brackets(), get_transport_str2enum(), global_contact_ha, hp, inaddrcmp(), sip_peer::is_realtime, sip_peer::lastms, LOG_NOTICE, LOG_WARNING, manager_event, sip_peer::name, PARSE_REGISTER_DENIED, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, parse_uri(), peers_by_ip, port_str2int(), sip_peer::portinuri, sip_pvt::recv, ref_peer(), register_peer_exten(), sip_peer::rt_fromcontact, s, sched, set_socket_transport(), SIP_NAT_ROUTE, SIP_PAGE2_RTCACHEFRIENDS, sip_poke_peer(), SIP_TRANSPORT_TLS, SIP_TRANSPORT_UDP, SIPBUFSIZE, sip_pvt::sipoptions, sip_peer::sipoptions, sip_peer::socket, sip_request::socket, sip_pvt::socket, STANDARD_SIP_PORT, STANDARD_TLS_PORT, strcasestr(), strsep(), sip_peer::transports, TRUE, sip_socket::type, unref_peer(), sip_peer::useragent, sip_peer::username, VERBOSE_PREFIX_3, and VERBOSITY_ATLEAST.

Referenced by register_verify().

11427 {
11428    char contact[SIPBUFSIZE];
11429    char data[SIPBUFSIZE];
11430    const char *expires = get_header(req, "Expires");
11431    int expire = atoi(expires);
11432    char *curi, *host, *pt, *transport;
11433    int port;
11434    int transport_type;
11435    const char *useragent;
11436    struct hostent *hp;
11437    struct ast_hostent ahp;
11438    struct sockaddr_in oldsin, testsin;
11439 
11440 
11441    ast_copy_string(contact, get_header(req, "Contact"), sizeof(contact));
11442 
11443    if (ast_strlen_zero(expires)) {  /* No expires header, try look in Contact: */
11444       char *s = strcasestr(contact, ";expires=");
11445       if (s) {
11446          expires = strsep(&s, ";"); /* trim ; and beyond */
11447          if (sscanf(expires + 9, "%30d", &expire) != 1)
11448             expire = default_expiry;
11449       } else {
11450          /* Nothing has been specified */
11451          expire = default_expiry;
11452       }
11453    }
11454 
11455    copy_socket_data(&pvt->socket, &req->socket);
11456 
11457    /* Look for brackets */
11458    curi = contact;
11459    if (strchr(contact, '<') == NULL)   /* No <, check for ; and strip it */
11460       strsep(&curi, ";");  /* This is Header options, not URI options */
11461    curi = get_in_brackets(contact);
11462 
11463    /* if they did not specify Contact: or Expires:, they are querying
11464       what we currently have stored as their contact address, so return
11465       it
11466    */
11467    if (ast_strlen_zero(curi) && ast_strlen_zero(expires)) {
11468       /* If we have an active registration, tell them when the registration is going to expire */
11469       if (peer->expire > -1 && !ast_strlen_zero(peer->fullcontact))
11470          pvt->expiry = ast_sched_when(sched, peer->expire);
11471       return PARSE_REGISTER_QUERY;
11472    } else if (!strcasecmp(curi, "*") || !expire) { /* Unregister this peer */
11473       /* This means remove all registrations and return OK */
11474       memset(&peer->addr, 0, sizeof(peer->addr));
11475       set_socket_transport(&peer->socket, peer->default_outbound_transport);
11476 
11477       AST_SCHED_DEL_UNREF(sched, peer->expire,
11478             unref_peer(peer, "remove register expire ref"));
11479 
11480       destroy_association(peer);
11481 
11482       register_peer_exten(peer, FALSE);   /* Remove extension from regexten= setting in sip.conf */
11483       peer->fullcontact[0] = '\0';
11484       peer->useragent[0] = '\0';
11485       peer->sipoptions = 0;
11486       peer->lastms = 0;
11487       peer->portinuri = 0;
11488       pvt->expiry = 0;
11489 
11490       ast_verb(3, "Unregistered SIP '%s'\n", peer->name);
11491 
11492       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unregistered\r\n", peer->name);
11493       return PARSE_REGISTER_UPDATE;
11494    }
11495 
11496    /* Store whatever we got as a contact from the client */
11497    ast_copy_string(peer->fullcontact, curi, sizeof(peer->fullcontact));
11498 
11499    /* For the 200 OK, we should use the received contact */
11500    ast_string_field_build(pvt, our_contact, "<%s>", curi);
11501 
11502    /* Make sure it's a SIP URL */
11503    if (parse_uri(curi, "sip:,sips:", &curi, NULL, &host, &pt, NULL, &transport)) {
11504       ast_log(LOG_NOTICE, "Not a valid SIP contact (missing sip:) trying to use anyway\n");
11505    }
11506 
11507    /* If we have a port number in the given URI, make sure we do remember to not check for NAPTR/SRV records. 
11508       The domain part is actually a host. */
11509    peer->portinuri = !ast_strlen_zero(pt) ? TRUE : FALSE;
11510 
11511    /* handle the transport type specified in Contact header. */
11512    if ((transport_type = get_transport_str2enum(transport))) {
11513       /* if the port is not specified but the transport is, make sure to set the
11514        * default port to match the specified transport.  This may or may not be the
11515        * same transport used by the pvt struct for the Register dialog. */
11516       
11517       port = port_str2int(pt, (transport_type == SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT);
11518    } else {
11519       port = port_str2int(pt, STANDARD_SIP_PORT);
11520       transport_type = pvt->socket.type;
11521    }
11522 
11523    /* if the peer's socket type is different than the Registration
11524     * transport type, change it.  If it got this far, it is a
11525     * supported type, but check just in case */
11526    if ((peer->socket.type != transport_type) && (peer->transports & transport_type)) {
11527       set_socket_transport(&peer->socket, transport_type);
11528    }
11529 
11530    oldsin = peer->addr;
11531 
11532    /* If we were already linked into the peers_by_ip container unlink ourselves so nobody can find us */
11533    if (peer->addr.sin_addr.s_addr) {
11534       ao2_t_unlink(peers_by_ip, peer, "ao2_unlink of peer from peers_by_ip table");
11535    }
11536 
11537    /* Check that they're allowed to register at this IP */
11538    /* XXX This could block for a long time XXX */
11539    hp = ast_gethostbyname(host, &ahp);
11540    if (!hp)  {
11541       ast_log(LOG_WARNING, "Invalid host '%s'\n", host);
11542       *peer->fullcontact = '\0';
11543       ast_string_field_set(pvt, our_contact, "");
11544       return PARSE_REGISTER_FAILED;
11545    }
11546    memcpy(&testsin.sin_addr, hp->h_addr, sizeof(testsin.sin_addr));
11547    if (  ast_apply_ha(global_contact_ha, &testsin) != AST_SENSE_ALLOW ||
11548          ast_apply_ha(peer->contactha, &testsin) != AST_SENSE_ALLOW) {
11549       ast_log(LOG_WARNING, "Host '%s' disallowed by contact ACL (violating IP %s)\n", host, ast_inet_ntoa(testsin.sin_addr));
11550       *peer->fullcontact = '\0';
11551       ast_string_field_set(pvt, our_contact, "");
11552       return PARSE_REGISTER_DENIED;
11553    }
11554 
11555    if (!ast_test_flag(&peer->flags[0], SIP_NAT_ROUTE)) {
11556       peer->addr.sin_family = AF_INET;
11557       memcpy(&peer->addr.sin_addr, hp->h_addr, sizeof(peer->addr.sin_addr));
11558       peer->addr.sin_port = htons(port);
11559    } else {
11560       /* Don't trust the contact field.  Just use what they came to us
11561          with */
11562       peer->addr = pvt->recv;
11563    }
11564 
11565    /* if the Contact header information copied into peer->addr matches the
11566     * received address, and the transport types are the same, then copy socket
11567     * data into the peer struct */
11568    if ((peer->socket.type == pvt->socket.type) &&
11569       (peer->addr.sin_addr.s_addr == pvt->recv.sin_addr.s_addr) &&
11570       (peer->addr.sin_port == pvt->recv.sin_port)){
11571 
11572       copy_socket_data(&peer->socket, &pvt->socket);
11573    }
11574 
11575    /* Now that our address has been updated put ourselves back into the container for lookups */
11576    ao2_t_link(peers_by_ip, peer, "ao2_link into peers_by_ip table");
11577 
11578    /* Save SIP options profile */
11579    peer->sipoptions = pvt->sipoptions;
11580 
11581    if (!ast_strlen_zero(curi) && ast_strlen_zero(peer->username))
11582       ast_copy_string(peer->username, curi, sizeof(peer->username));
11583 
11584    AST_SCHED_DEL_UNREF(sched, peer->expire,
11585          unref_peer(peer, "remove register expire ref"));
11586 
11587    if (expire > max_expiry)
11588       expire = max_expiry;
11589    if (expire < min_expiry)
11590       expire = min_expiry;
11591    if (peer->is_realtime && !ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
11592       peer->expire = -1;
11593    } else {
11594       peer->expire = ast_sched_add(sched, (expire + 10) * 1000, expire_register,
11595             ref_peer(peer, "add registration ref"));
11596       if (peer->expire == -1) {
11597          unref_peer(peer, "remote registration ref");
11598       }
11599    }
11600    pvt->expiry = expire;
11601    snprintf(data, sizeof(data), "%s:%d:%d:%s:%s", ast_inet_ntoa(peer->addr.sin_addr), ntohs(peer->addr.sin_port), expire, peer->username, peer->fullcontact);
11602    /* Saving TCP connections is useless, we won't be able to reconnect 
11603       XXX WHY???? XXX
11604       \todo check this
11605    */
11606    if (!peer->rt_fromcontact && (peer->socket.type & SIP_TRANSPORT_UDP))
11607       ast_db_put("SIP/Registry", peer->name, data);
11608    manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\nPort: %d\r\n", peer->name,  ast_inet_ntoa(peer->addr.sin_addr), ntohs(peer->addr.sin_port));
11609 
11610    /* Is this a new IP address for us? */
11611    if (VERBOSITY_ATLEAST(2) && inaddrcmp(&peer->addr, &oldsin)) {
11612       ast_verbose(VERBOSE_PREFIX_3 "Registered SIP '%s' at %s port %d\n", peer->name, ast_inet_ntoa(peer->addr.sin_addr), ntohs(peer->addr.sin_port));
11613    }
11614    sip_poke_peer(peer, 0);
11615    register_peer_exten(peer, 1);
11616    
11617    /* Save User agent */
11618    useragent = get_header(req, "User-Agent");
11619    if (strcasecmp(useragent, peer->useragent)) {   /* XXX copy if they are different ? */
11620       ast_copy_string(peer->useragent, useragent, sizeof(peer->useragent));
11621       ast_verb(4, "Saved useragent \"%s\" for peer %s\n", peer->useragent, peer->name);
11622    }
11623    return PARSE_REGISTER_UPDATE;
11624 }

static int parse_request ( struct sip_request req  )  [static]

Parse a SIP message.

Note:
this function is used both on incoming and outgoing packets

Definition at line 7199 of file chan_sip.c.

References ast_debug, ast_strlen_zero(), sip_request::data, sip_request::header, sip_request::headers, sip_request::line, SIP_MAX_HEADERS, SIP_MAX_LINES, and ast_str::str.

Referenced by _sip_tcp_helper_thread(), handle_request_do(), initialize_initreq(), and parse_copy().

07200 {
07201    char *c = req->data->str;
07202    ptrdiff_t *dst = req->header;
07203    int i = 0, lim = SIP_MAX_HEADERS - 1;
07204    unsigned int skipping_headers = 0;
07205    ptrdiff_t current_header_offset = 0;
07206    char *previous_header = "";
07207 
07208    req->header[0] = 0;
07209    req->headers = -1;   /* mark that we are working on the header */
07210    for (; *c; c++) {
07211       if (*c == '\r') {    /* remove \r */
07212          *c = '\0';
07213       } else if (*c == '\n') {   /* end of this line */
07214          *c = '\0';
07215          current_header_offset = (c + 1) - req->data->str;
07216          previous_header = req->data->str + dst[i];
07217          if (skipping_headers) {
07218             /* check to see if this line is blank; if so, turn off
07219                the skipping flag, so the next line will be processed
07220                as a body line */
07221             if (ast_strlen_zero(previous_header)) {
07222                skipping_headers = 0;
07223             }
07224             dst[i] = current_header_offset; /* record start of next line */
07225             continue;
07226          }
07227          if (sipdebug) {
07228             ast_debug(4, "%7s %2d [%3d]: %s\n",
07229                  req->headers < 0 ? "Header" : "Body",
07230                  i, (int) strlen(previous_header), previous_header);
07231          }
07232          if (ast_strlen_zero(previous_header) && req->headers < 0) {
07233             req->headers = i; /* record number of header lines */
07234             dst = req->line;  /* start working on the body */
07235             i = 0;
07236             lim = SIP_MAX_LINES - 1;
07237          } else { /* move to next line, check for overflows */
07238             if (i++ == lim) {
07239                /* if we're processing headers, then skip any remaining
07240                   headers and move on to processing the body, otherwise
07241                   we're done */
07242                if (req->headers != -1) {
07243                   break;
07244                } else {
07245                   req->headers = i;
07246                   dst = req->line;
07247                   i = 0;
07248                   lim = SIP_MAX_LINES - 1;
07249                   skipping_headers = 1;
07250                }
07251             }
07252          }
07253          dst[i] = current_header_offset; /* record start of next line */
07254       }
07255    }
07256 
07257    /* Check for last header or body line without CRLF. The RFC for SDP requires CRLF,
07258       but since some devices send without, we'll be generous in what we accept. However,
07259       if we've already reached the maximum number of lines for portion of the message
07260       we were parsing, we can't accept any more, so just ignore it.
07261    */
07262    previous_header = req->data->str + dst[i];
07263    if ((i < lim) && !ast_strlen_zero(previous_header)) {
07264       if (sipdebug) {
07265          ast_debug(4, "%7s %2d [%3d]: %s\n",
07266               req->headers < 0 ? "Header" : "Body",
07267               i, (int) strlen(previous_header), previous_header );
07268       }
07269       i++;
07270    }
07271 
07272    /* update count of header or body lines */
07273    if (req->headers >= 0) {   /* we are in the body */
07274       req->lines = i;
07275    } else {       /* no body */
07276       req->headers = i;
07277       req->lines = 0;
07278       /* req->data->used will be a NULL byte */
07279       req->line[0] = req->data->used;
07280    }
07281 
07282    if (*c) {
07283       ast_log(LOG_WARNING, "Too many lines, skipping <%s>\n", c);
07284    }
07285 
07286    /* Split up the first line parts */
07287    return determine_firstline_parts(req);
07288 }

int parse_session_expires ( const char *  p_hdrval,
int *const   p_interval,
enum st_refresher *const   p_ref 
) [static]

Session-Timers: Function for parsing Session-Expires header.

Definition at line 21752 of file chan_sip.c.

References ast_debug, ast_log(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), LOG_WARNING, SESSION_TIMER_REFRESHER_AUTO, SESSION_TIMER_REFRESHER_UAC, SESSION_TIMER_REFRESHER_UAS, and strsep().

Referenced by handle_request_invite(), and handle_response_invite().

21753 {
21754    char *p_token;
21755    int  ref_idx;
21756    char *p_se_hdr;
21757 
21758    if (ast_strlen_zero(p_hdrval)) {
21759       ast_log(LOG_WARNING, "Null Session-Expires header\n");
21760       return -1;
21761    }
21762 
21763    *p_ref = SESSION_TIMER_REFRESHER_AUTO;
21764    *p_interval = 0;
21765 
21766    p_se_hdr = ast_strdupa(p_hdrval);
21767    p_se_hdr = ast_skip_blanks(p_se_hdr);
21768 
21769    while ((p_token = strsep(&p_se_hdr, ";"))) {
21770       p_token = ast_skip_blanks(p_token);
21771       if (!sscanf(p_token, "%30d", p_interval)) {
21772          ast_log(LOG_WARNING, "Parsing of Session-Expires failed\n");
21773          return -1;
21774       }
21775 
21776       ast_debug(2, "Session-Expires: %d\n", *p_interval);
21777 
21778       if (!p_se_hdr)
21779          continue;
21780 
21781       p_se_hdr = ast_skip_blanks(p_se_hdr);
21782       ref_idx = strlen("refresher=");
21783       if (!strncasecmp(p_se_hdr, "refresher=", ref_idx)) {
21784          p_se_hdr += ref_idx;
21785          p_se_hdr = ast_skip_blanks(p_se_hdr);
21786 
21787          if (!strncasecmp(p_se_hdr, "uac", strlen("uac"))) {
21788             *p_ref = SESSION_TIMER_REFRESHER_UAC;
21789             ast_debug(2, "Refresher: UAC\n");
21790          } else if (!strncasecmp(p_se_hdr, "uas", strlen("uas"))) {
21791             *p_ref = SESSION_TIMER_REFRESHER_UAS;
21792             ast_debug(2, "Refresher: UAS\n");
21793          } else {
21794             ast_log(LOG_WARNING, "Invalid refresher value %s\n", p_se_hdr);
21795             return -1;
21796          }
21797          break;
21798       }
21799    }
21800    return 0;
21801 }

static unsigned int parse_sip_options ( struct sip_pvt pvt,
const char *  supported 
) [static]

Parse supported header in incoming packet.

Definition at line 3012 of file chan_sip.c.

References ARRAY_LEN, ast_debug, ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), FALSE, cfsip_options::id, sip_request::next, SIP_OPT_UNKNOWN, sip_options, sip_pvt::sipoptions, text, and TRUE.

Referenced by handle_request_invite().

03013 {
03014    char *next, *sep;
03015    char *temp;
03016    unsigned int profile = 0;
03017    int i, found;
03018 
03019    if (ast_strlen_zero(supported) )
03020       return 0;
03021    temp = ast_strdupa(supported);
03022 
03023    if (sipdebug)
03024       ast_debug(3, "Begin: parsing SIP \"Supported: %s\"\n", supported);
03025 
03026    for (next = temp; next; next = sep) {
03027       found = FALSE;
03028       if ( (sep = strchr(next, ',')) != NULL)
03029          *sep++ = '\0';
03030       next = ast_skip_blanks(next);
03031       if (sipdebug)
03032          ast_debug(3, "Found SIP option: -%s-\n", next);
03033       for (i = 0; i < ARRAY_LEN(sip_options); i++) {
03034          if (!strcasecmp(next, sip_options[i].text)) {
03035             profile |= sip_options[i].id;
03036             found = TRUE;
03037             if (sipdebug)
03038                ast_debug(3, "Matched SIP option: %s\n", next);
03039             break;
03040          }
03041       }
03042 
03043       /* This function is used to parse both Suported: and Require: headers.
03044       Let the caller of this function know that an unknown option tag was 
03045       encountered, so that if the UAC requires it then the request can be 
03046       rejected with a 420 response. */
03047       if (!found)
03048          profile |= SIP_OPT_UNKNOWN;
03049 
03050       if (!found && sipdebug) {
03051          if (!strncasecmp(next, "x-", 2))
03052             ast_debug(3, "Found private SIP option, not supported: %s\n", next);
03053          else
03054             ast_debug(3, "Found no match for SIP option: %s (Please file bug report!)\n", next);
03055       }
03056    }
03057 
03058    if (pvt)
03059       pvt->sipoptions = profile;
03060    return profile;
03061 }

static int parse_uri ( char *  uri,
const char *  scheme,
char **  ret_name,
char **  pass,
char **  domain,
char **  port,
char **  options,
char **  transport 
) [static]

* parses a URI in its components.

Note:
  • If scheme is specified, drop it from the top.
  • If a component is not requested, do not split around it.
  • Multiple scheme's can be specified ',' delimited. ex: "sip:,sips:"
This means that if we don't have domain, we cannot split name:pass and domain:port. It is safe to call with ret_name, pass, domain, port pointing all to the same place. Init pointers to empty string so we never get NULL dereferencing. Overwrites the string. return 0 on success, other values on error.
 * general form we are expecting is sip[s]:username[:password][;parameter]@host[:port][;...] 
 * 

Definition at line 4010 of file chan_sip.c.

References ast_debug, ast_strdupa, ast_strlen_zero(), name, and strsep().

Referenced by __set_address_from_contact(), check_user_full(), and parse_register_contact().

04012 {
04013    char *name = NULL;
04014    int error = 0;
04015 
04016    /* init field as required */
04017    if (pass)
04018       *pass = "";
04019    if (port)
04020       *port = "";
04021    if (scheme) {
04022       int l;
04023       char *scheme2 = ast_strdupa(scheme);
04024       char *cur = strsep(&scheme2, ",");
04025       for (; !ast_strlen_zero(cur); cur = strsep(&scheme2, ",")) {
04026          l = strlen(cur);
04027          if (!strncasecmp(uri, cur, l)) {
04028             uri += l;
04029             break;
04030          }
04031       }
04032       if (ast_strlen_zero(cur)) {
04033          ast_debug(1, "No supported scheme found in '%s' using the scheme[s] %s\n", uri, scheme);
04034          error = -1;
04035       }
04036    }
04037    if (transport) {
04038       char *t, *type = "";
04039       *transport = "";
04040       if ((t = strstr(uri, "transport="))) {
04041          strsep(&t, "=");
04042          if ((type = strsep(&t, ";"))) {
04043             *transport = type;
04044          }
04045       }
04046    }
04047 
04048    if (!domain) {
04049       /* if we don't want to split around domain, keep everything as a name,
04050        * so we need to do nothing here, except remember why.
04051        */
04052    } else {
04053       /* store the result in a temp. variable to avoid it being
04054        * overwritten if arguments point to the same place.
04055        */
04056       char *c, *dom = "";
04057 
04058       if ((c = strchr(uri, '@')) == NULL) {
04059          /* domain-only URI, according to the SIP RFC. */
04060          dom = uri;
04061          name = "";
04062       } else {
04063          *c++ = '\0';
04064          dom = c;
04065          name = uri;
04066       }
04067 
04068       /* Remove options in domain and name */
04069       dom = strsep(&dom, ";");
04070       name = strsep(&name, ";");
04071 
04072       if (port && (c = strchr(dom, ':'))) { /* Remove :port */
04073          *c++ = '\0';
04074          *port = c;
04075       }
04076       if (pass && (c = strchr(name, ':'))) { /* user:password */
04077          *c++ = '\0';
04078          *pass = c;
04079       }
04080       *domain = dom;
04081    }
04082    if (ret_name)  /* same as for domain, store the result only at the end */
04083       *ret_name = name;
04084    if (options)
04085       *options = uri ? uri : "";
04086 
04087    return error;
04088 }

static int peer_cmp_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Note:
The only member of the peer used here is the name field

Definition at line 1703 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, and sip_peer::name.

01704 {
01705    struct sip_peer *peer = obj, *peer2 = arg;
01706 
01707    return !strcasecmp(peer->name, peer2->name) ? CMP_MATCH | CMP_STOP : 0;
01708 }

static int peer_dump_func ( void *  userobj,
void *  arg,
int  flags 
) [static]

Definition at line 14061 of file chan_sip.c.

References ao2_t_ref, ast_cli(), and sip_peer::name.

Referenced by sip_show_objects().

14062 {
14063    struct sip_peer *peer = userobj;
14064    int refc = ao2_t_ref(userobj, 0, "");
14065    int *fd = arg;
14066    
14067    ast_cli(*fd, "name: %s\ntype: peer\nobjflags: %d\nrefcount: %d\n\n", 
14068           peer->name, 0, refc);
14069    return 0;
14070 }

static int peer_hash_cb ( const void *  obj,
const int  flags 
) [static]

Note:
The only member of the peer used here is the name field

Definition at line 1693 of file chan_sip.c.

References ast_str_case_hash(), and sip_peer::name.

01694 {
01695    const struct sip_peer *peer = obj;
01696 
01697    return ast_str_case_hash(peer->name);
01698 }

static int peer_ipcmp_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Match Peers by IP and Port number.

This function has two modes.

This callback will be used twice when doing peer matching. There is a first pass for full IP+port matching, and a second pass in case there is a match that meets the insecure=port criteria.

Note:
Connections coming in over TCP or TLS should never be matched by port.

the peer's addr struct provides to fields combined to make a key: the sin_addr.s_addr and sin_port fields.

Definition at line 1741 of file chan_sip.c.

References sip_peer::addr, ast_test_flag, CMP_MATCH, CMP_STOP, sip_peer::flags, SIP_INSECURE_PORT, SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, and sip_peer::transports.

Referenced by load_module().

01742 {
01743    struct sip_peer *peer = obj, *peer2 = arg;
01744 
01745    if (peer->addr.sin_addr.s_addr != peer2->addr.sin_addr.s_addr) {
01746       /* IP doesn't match */
01747       return 0;
01748    }
01749 
01750    /* We matched the IP, check to see if we need to match by port as well. */
01751    if ((peer->transports & peer2->transports) & (SIP_TRANSPORT_TLS | SIP_TRANSPORT_TCP)) {
01752       /* peer matching on port is not possible with TCP/TLS */
01753       return CMP_MATCH | CMP_STOP;
01754    } else if (ast_test_flag(&peer2->flags[0], SIP_INSECURE_PORT)) {
01755       /* We are allowing match without port for peers configured that
01756        * way in this pass through the peers. */
01757       return ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT) ?
01758             (CMP_MATCH | CMP_STOP) : 0;
01759    }
01760 
01761    /* Now only return a match if the port matches, as well. */
01762    return peer->addr.sin_port == peer2->addr.sin_port ? (CMP_MATCH | CMP_STOP) : 0;
01763 }

static int peer_iphash_cb ( const void *  obj,
const int  flags 
) [static]

Note:
the peer's ip address field is used to create key.

Definition at line 1713 of file chan_sip.c.

References sip_peer::addr.

Referenced by load_module().

01714 {
01715    const struct sip_peer *peer = obj;
01716    int ret1 = peer->addr.sin_addr.s_addr;
01717    if (ret1 < 0)
01718       ret1 = -ret1;
01719 
01720    return ret1;
01721 }

static int peer_is_marked ( void *  peerobj,
void *  arg,
int  flags 
) [static]

Definition at line 14251 of file chan_sip.c.

References CMP_MATCH, and sip_peer::the_mark.

Referenced by sip_do_reload(), and sip_prune_realtime().

14252 {
14253    struct sip_peer *peer = peerobj;
14254    return peer->the_mark ? CMP_MATCH : 0;
14255 }

static void peer_mailboxes_to_str ( struct ast_str **  mailbox_str,
struct sip_peer peer 
) [static]

list peer mailboxes to CLI

Definition at line 14555 of file chan_sip.c.

References AST_LIST_NEXT, AST_LIST_TRAVERSE, ast_str_append(), ast_strlen_zero(), sip_mailbox::entry, mailbox, sip_peer::mailboxes, and S_OR.

Referenced by _sip_show_peer(), function_sippeer(), show_channels_cb(), and sip_send_mwi_to_peer().

14556 {
14557    struct sip_mailbox *mailbox;
14558 
14559    AST_LIST_TRAVERSE(&peer->mailboxes, mailbox, entry) {
14560       ast_str_append(mailbox_str, 0, "%s%s%s%s",
14561          mailbox->mailbox,
14562          ast_strlen_zero(mailbox->context) ? "" : "@",
14563          S_OR(mailbox->context, ""),
14564          AST_LIST_NEXT(mailbox, entry) ? "," : "");
14565    }
14566 }

static int peer_markall_func ( void *  device,
void *  arg,
int  flags 
) [static]

Definition at line 23300 of file chan_sip.c.

References sip_peer::the_mark.

23301 {
23302    struct sip_peer *peer = device;
23303    peer->the_mark = 1;
23304    return 0;
23305 }

static int peer_status ( struct sip_peer peer,
char *  status,
int  statuslen 
) [static]

Definition at line 13639 of file chan_sip.c.

References ast_copy_string(), sip_peer::lastms, and sip_peer::maxms.

13640 {
13641    int res = 0;
13642    if (peer->maxms) {
13643       if (peer->lastms < 0) {
13644          ast_copy_string(status, "UNREACHABLE", statuslen);
13645       } else if (peer->lastms > peer->maxms) {
13646          snprintf(status, statuslen, "LAGGED (%d ms)", peer->lastms);
13647          res = 1;
13648       } else if (peer->lastms) {
13649          snprintf(status, statuslen, "OK (%d ms)", peer->lastms);
13650          res = 1;
13651       } else {
13652          ast_copy_string(status, "UNKNOWN", statuslen);
13653       }
13654    } else { 
13655       ast_copy_string(status, "Unmonitored", statuslen);
13656       /* Checking if port is 0 */
13657       res = -1;
13658    }
13659    return res;
13660 }

int peercomparefunc ( const void *  a,
const void *  b 
)

Definition at line 13880 of file chan_sip.c.

Referenced by _sip_show_peers().

13881 {
13882    struct sip_peer **ap = (struct sip_peer **)a;
13883    struct sip_peer **bp = (struct sip_peer **)b;
13884    return strcmp((*ap)->name, (*bp)->name);
13885 }

static int port_str2int ( const char *  pt,
unsigned int  standard 
) [static]

converts ascii port to int representation. If no pt buffer is provided or the pt has errors when being converted to an int value, the port provided as the standard is used.

Definition at line 2933 of file chan_sip.c.

References ast_strlen_zero().

Referenced by __set_address_from_contact(), build_peer(), check_via(), create_addr(), parse_register_contact(), and proxy_allocate().

02934 {
02935    int port = standard;
02936    if (ast_strlen_zero(pt) || (sscanf(pt, "%30d", &port) != 1) || (port < 1) || (port > 65535)) {
02937       port = standard;
02938    }
02939 
02940    return port;
02941 }

static void print_codec_to_cli ( int  fd,
struct ast_codec_pref pref 
) [static]

Print codec list from preference to CLI/manager.

Definition at line 14387 of file chan_sip.c.

References ast_cli(), ast_codec_pref_index(), ast_getformatname(), and ast_codec_pref::framing.

Referenced by _sip_show_peer(), handle_skinny_show_line(), sip_show_settings(), and sip_show_user().

14388 {
14389    int x, codec;
14390 
14391    for(x = 0; x < 32 ; x++) {
14392       codec = ast_codec_pref_index(pref, x);
14393       if (!codec)
14394          break;
14395       ast_cli(fd, "%s", ast_getformatname(codec));
14396       ast_cli(fd, ":%d", pref->framing[x]);
14397       if (x < 31 && ast_codec_pref_index(pref, x + 1))
14398          ast_cli(fd, ",");
14399    }
14400    if (!x)
14401       ast_cli(fd, "none");
14402 }

static void print_group ( int  fd,
ast_group_t  group,
int  crlf 
) [static]

Print call group and pickup group.

Definition at line 14111 of file chan_sip.c.

References ast_cli(), ast_print_group(), and buf.

Referenced by _sip_show_peer(), and sip_show_user().

14112 {
14113    char buf[256];
14114    ast_cli(fd, crlf ? "%s\r\n" : "%s\n", ast_print_group(buf, sizeof(buf), group) );
14115 }

static void proc_422_rsp ( struct sip_pvt p,
struct sip_request rsp 
) [static]

Handle 422 response to INVITE with session-timer requested.

Session-Timers: An INVITE originated by Asterisk that asks for session-timers support from the UAS can result into a 422 response. This is how a UAS or an intermediary proxy server tells Asterisk that the session refresh interval offered by Asterisk is too low for them. The proc_422_rsp() function handles a 422 response. It extracts the Min-SE header that comes back in 422 and sends a new INVITE accordingly.

Definition at line 21811 of file chan_sip.c.

References ast_log(), ast_strlen_zero(), get_header(), LOG_WARNING, parse_minse(), SIP_INVITE, sip_st_dlg::st_interval, sip_pvt::stimer, and transmit_invite().

Referenced by handle_response_invite().

21812 {
21813    int rtn;
21814    const char *p_hdrval;
21815    int minse;
21816 
21817    p_hdrval = get_header(rsp, "Min-SE");
21818    if (ast_strlen_zero(p_hdrval)) {
21819       ast_log(LOG_WARNING, "422 response without a Min-SE header %s\n", p_hdrval);
21820       return;
21821    }
21822    rtn = parse_minse(p_hdrval, &minse);
21823    if (rtn != 0) {
21824       ast_log(LOG_WARNING, "Parsing of Min-SE header failed %s\n", p_hdrval);
21825       return;
21826    }
21827    p->stimer->st_interval = minse;
21828    transmit_invite(p, SIP_INVITE, 1, 2); 
21829 }

static int proc_session_timer ( const void *  vp  )  [static]

Session-Timers: Process session refresh timeout event.

Definition at line 21651 of file chan_sip.c.

References ast_channel::_state, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_log(), AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_UP, sip_pvt::callid, dialog_unref(), FALSE, LOG_ERROR, LOG_WARNING, sip_pvt::outgoing_call, sip_pvt::owner, sip_st_dlg::quit_flag, SESSION_TIMER_REFRESHER_UAC, SESSION_TIMER_REFRESHER_UAS, sip_pvt_lock, sip_pvt_unlock, sip_st_dlg::st_active, sip_st_dlg::st_expirys, sip_st_dlg::st_ref, sip_st_dlg::st_schedid, sip_pvt::stimer, stop_session_timer(), transmit_reinvite_with_sdp(), and TRUE.

Referenced by start_session_timer().

21652 {
21653    struct sip_pvt *p = (struct sip_pvt *) vp;
21654    int sendreinv = FALSE;
21655    int res = 0;
21656 
21657    if (!p->stimer) {
21658       ast_log(LOG_WARNING, "Null stimer in proc_session_timer - %s\n", p->callid);
21659       goto return_unref;
21660    }
21661 
21662    ast_debug(2, "Session timer expired: %d - %s\n", p->stimer->st_schedid, p->callid);
21663 
21664    if (!p->owner) {
21665       goto return_unref;
21666    }
21667 
21668    if ((p->stimer->st_active != TRUE) || (p->owner->_state != AST_STATE_UP)) {
21669       goto return_unref;
21670    }
21671 
21672    switch (p->stimer->st_ref) {
21673    case SESSION_TIMER_REFRESHER_UAC:
21674       if (p->outgoing_call == TRUE) {
21675          sendreinv = TRUE;
21676       }
21677       break;
21678    case SESSION_TIMER_REFRESHER_UAS:
21679       if (p->outgoing_call != TRUE) {
21680          sendreinv = TRUE;
21681       }
21682       break;
21683    default:
21684       ast_log(LOG_ERROR, "Unknown session refresher %d\n", p->stimer->st_ref);
21685       goto return_unref;
21686    }
21687 
21688    if (sendreinv == TRUE) {
21689       res = 1;
21690       transmit_reinvite_with_sdp(p, FALSE, TRUE);
21691    } else {
21692       p->stimer->st_expirys++;
21693       if (p->stimer->st_expirys >= 2) {
21694          if (p->stimer->quit_flag) {
21695             goto return_unref;
21696          }
21697          ast_log(LOG_WARNING, "Session-Timer expired - %s\n", p->callid);
21698          sip_pvt_lock(p);
21699          while (p->owner && ast_channel_trylock(p->owner)) {
21700             sip_pvt_unlock(p);
21701             usleep(1);
21702             if (p->stimer && p->stimer->quit_flag) {
21703                goto return_unref;
21704             }
21705             sip_pvt_lock(p);
21706          }
21707 
21708          ast_softhangup_nolock(p->owner, AST_SOFTHANGUP_DEV);
21709          ast_channel_unlock(p->owner);
21710          sip_pvt_unlock(p);
21711       }
21712    }
21713 
21714 return_unref:
21715    if (!res) {
21716       /* An error occurred.  Stop session timer processing */
21717       if (p->stimer) {
21718          p->stimer->st_schedid = -1;
21719          stop_session_timer(p);
21720       }
21721 
21722       /* If we are not asking to be rescheduled, then we need to release our
21723        * reference to the dialog. */
21724       dialog_unref(p, "removing session timer ref");
21725    }
21726 
21727    return res;
21728 }

static void process_request_queue ( struct sip_pvt p,
int *  recount,
int *  nounlock 
) [static]

Definition at line 20868 of file chan_sip.c.

References ast_free, AST_LIST_REMOVE_HEAD, ast_log(), handle_incoming(), LOG_DEBUG, sip_request::next, option_debug, and sip_pvt::request_queue.

Referenced by handle_request_do().

20869 {
20870    struct sip_request *req;
20871 
20872    while ((req = AST_LIST_REMOVE_HEAD(&p->request_queue, next))) {
20873       if (handle_incoming(p, req, &p->recv, recount, nounlock) == -1) {
20874          /* Request failed */
20875          if (option_debug) {
20876             ast_log(LOG_DEBUG, "SIP message could not be handled, bad request: %-70.70s\n", p->callid[0] ? p->callid : "<no callid>");
20877          }
20878       }
20879       ast_free(req);
20880    }
20881 }

static int process_sdp ( struct sip_pvt p,
struct sip_request req,
int  t38action 
) [static]

Process SIP SDP offer, select formats and activate RTP channels If offer is rejected, we will not change any properties of the call Return 0 on success, a negative value on errors. Must be called after find_sdp().

< RTP Audio host IP

< RTP video host IP

< RTP text host IP

< UDPTL host ip

< RTP Audio port number

< RTP Video port number

< RTP Text port number

< UDPTL Image port number

< media socket address

< video socket address

< image socket address

< text socket address

Definition at line 7454 of file chan_sip.c.

References append_history, ast_clear_flag, ast_codec_choose(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, ast_copy_string(), ast_debug, AST_FORMAT_AUDIO_MASK, AST_FORMAT_T140RED, ast_getformatname_multiple(), ast_inet_ntoa(), ast_log(), ast_null_frame, ast_queue_control(), ast_queue_control_data(), ast_queue_frame(), ast_rtp_alloc_size(), AST_RTP_DTMF, ast_rtp_get_current_formats(), ast_rtp_get_peer(), ast_rtp_lookup_mime_multiple(), ast_rtp_new_init(), ast_rtp_pt_clear(), ast_rtp_pt_copy(), ast_rtp_set_m_type(), ast_rtp_set_peer(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_stop(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), ast_skip_blanks(), ast_strlen_zero(), ast_test_flag, ast_threadstorage_get(), ast_udptl_get_far_max_datagram(), ast_udptl_set_far_max_datagram(), ast_udptl_set_peer(), ast_udptl_stop(), ast_verbose, buf, sip_pvt::callid, sip_pvt::capability, change_t38_state(), sip_request::data, sip_request::debug, EVENT_FLAG_CALL, FALSE, sip_pvt::flags, get_sdp_iterate(), get_sdp_line(), ast_hostent::hp, hp, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, sip_pvt::lastinvite, sip_pvt::lastrtprx, sip_pvt::lastrtptx, LOG_DEBUG, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event, sip_pvt::mohsuggest, ast_channel::name, ast_channel::nativeformats, sip_request::next, sip_pvt::noncodeccapability, sip_pvt::notext, sip_pvt::novideo, offered_media::offered, sip_pvt::offered_media, option_debug, sip_pvt::owner, sip_pvt::peercapability, sip_pvt::prefs, process_sdp_a_audio(), process_sdp_a_image(), process_sdp_a_sendonly(), process_sdp_a_text(), process_sdp_a_video(), process_sdp_c(), process_sdp_o(), ast_channel::readformat, sip_pvt::red, sip_pvt::rtp, rtp_red_init(), S_OR, SDP_AUDIO, SDP_IMAGE, sip_request::sdp_start, SDP_T38_ACCEPT, SDP_T38_INITIATE, SDP_TEXT, SDP_VIDEO, sip_pvt::session_modify, sip_debug_test_pvt(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_NAT, SIP_PAGE2_CALL_ONHOLD, SIP_PAGE2_CALL_ONHOLD_ACTIVE, SIP_PAGE2_CALL_ONHOLD_INACTIVE, SIP_PAGE2_CALL_ONHOLD_ONEDIR, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_UDPTL_DESTINATION, sip_peer_hold(), SIPBUFSIZE, t38properties::state, ast_str::str, sip_pvt::t38, T38_DISABLED, T38_ENABLED, T38_LOCAL_REINVITE, T38_PEER_REINVITE, text, t38properties::their_parms, sip_pvt::trtp, TRUE, sip_pvt::udptl, ast_channel::uniqueid, sip_pvt::vrtp, and ast_channel::writeformat.

07455 {
07456    /* Iterators for SDP parsing */
07457    int start = req->sdp_start;
07458    int next = start;
07459    int iterator = start;
07460 
07461    /* Temporary vars for SDP parsing */
07462    char type = '\0';
07463    const char *value = NULL;
07464    const char *m = NULL;           /* SDP media offer */
07465    const char *nextm = NULL;
07466    int len = -1;
07467 
07468    /* Host information */
07469    struct ast_hostent sessionhp;
07470    struct ast_hostent audiohp;
07471    struct ast_hostent videohp;
07472    struct ast_hostent texthp;
07473    struct ast_hostent imagehp;
07474    struct hostent *hp = NULL; /*!< RTP Audio host IP */
07475    struct hostent *vhp = NULL;   /*!< RTP video host IP */
07476    struct hostent *thp = NULL;   /*!< RTP text host IP */
07477    struct hostent *ihp = NULL;     /*!< UDPTL host ip */
07478    int portno = -1;     /*!< RTP Audio port number */
07479    int vportno = -1;    /*!< RTP Video port number */
07480    int tportno = -1;    /*!< RTP Text port number */
07481    int udptlportno = -1;      /*!< UDPTL Image port number */
07482    struct sockaddr_in sin;    /*!< media socket address */
07483    struct sockaddr_in vsin;   /*!< video socket address */
07484    struct sockaddr_in isin;   /*!< image socket address */
07485    struct sockaddr_in tsin;   /*!< text socket address */
07486 
07487    /* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */ 
07488    int peercapability = 0, peernoncodeccapability = 0;
07489    int vpeercapability = 0, vpeernoncodeccapability = 0;
07490    int tpeercapability = 0, tpeernoncodeccapability = 0;
07491 
07492    struct ast_rtp *newaudiortp, *newvideortp, *newtextrtp;
07493    int newjointcapability;          /* Negotiated capability */
07494    int newpeercapability;
07495    int newnoncodeccapability;
07496 
07497    const char *codecs;
07498    int codec;
07499 
07500    /* Others */
07501    int sendonly = -1;
07502    int vsendonly = -1;
07503    int numberofports;
07504    int numberofmediastreams = 0;
07505    int last_rtpmap_codec = 0;
07506    int red_data_pt[10];    /* For T.140 red */
07507    int red_num_gen = 0;    /* For T.140 red */
07508    char red_fmtp[100] = "empty"; /* For T.140 red */
07509    int debug = sip_debug_test_pvt(p);
07510 
07511    /* START UNKNOWN */
07512    char buf[SIPBUFSIZE];
07513    /* END UNKNOWN */
07514 
07515    /* Initial check */
07516    if (!p->rtp) {
07517       ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n");
07518       return -1;
07519    }
07520 
07521    /* Initialize the temporary RTP structures we use to evaluate the offer from the peer */
07522 #ifdef LOW_MEMORY
07523    newaudiortp = ast_threadstorage_get(&ts_audio_rtp, ast_rtp_alloc_size());
07524 #else
07525    newaudiortp = alloca(ast_rtp_alloc_size());
07526 #endif
07527    memset(newaudiortp, 0, ast_rtp_alloc_size());
07528    ast_rtp_new_init(newaudiortp);
07529    ast_rtp_pt_clear(newaudiortp);
07530 
07531 #ifdef LOW_MEMORY
07532    newvideortp = ast_threadstorage_get(&ts_video_rtp, ast_rtp_alloc_size());
07533 #else
07534    newvideortp = alloca(ast_rtp_alloc_size());
07535 #endif
07536    memset(newvideortp, 0, ast_rtp_alloc_size());
07537    ast_rtp_new_init(newvideortp);
07538    ast_rtp_pt_clear(newvideortp);
07539 
07540 #ifdef LOW_MEMORY
07541    newtextrtp = ast_threadstorage_get(&ts_text_rtp, ast_rtp_alloc_size());
07542 #else
07543    newtextrtp = alloca(ast_rtp_alloc_size());
07544 #endif
07545    memset(newtextrtp, 0, ast_rtp_alloc_size());
07546    ast_rtp_new_init(newtextrtp);
07547    ast_rtp_pt_clear(newtextrtp);
07548 
07549    /* Update our last rtprx when we receive an SDP, too */
07550    p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
07551 
07552    memset(p->offered_media, 0, sizeof(p->offered_media));
07553 
07554 
07555    /* default: novideo and notext set */
07556    p->novideo = TRUE;
07557    p->notext = TRUE;
07558 
07559    if (p->vrtp)
07560       ast_rtp_pt_clear(newvideortp);  /* Must be cleared in case no m=video line exists */
07561  
07562    if (p->trtp)
07563       ast_rtp_pt_clear(newtextrtp);  /* Must be cleared in case no m=text line exists */
07564    
07565    /* Scan for the first media stream (m=) line to limit scanning of globals */
07566    nextm = get_sdp_iterate(&next, req, "m");
07567    if (ast_strlen_zero(nextm)) {
07568       ast_log(LOG_WARNING, "Insufficient information for SDP (m= not found)\n");
07569       return -1;
07570    }
07571 
07572    /* Scan session level SDP parameters (lines before first media stream) */
07573    while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') {
07574       int processed = FALSE;
07575       switch (type) {
07576       case 'o':
07577          /* If we end up receiving SDP that doesn't actually modify the session we don't want to treat this as a fatal
07578           * error. We just want to ignore the SDP and let the rest of the packet be handled as normal.
07579           */
07580          if (!process_sdp_o(value, p))
07581             return (p->session_modify == FALSE) ? 0 : -1;
07582          break;
07583       case 'c':
07584          if (process_sdp_c(value, &sessionhp)) {
07585             processed = TRUE;
07586             hp = &sessionhp.hp;
07587             vhp = hp;
07588             thp = hp;
07589             ihp = hp;
07590          }
07591          break;
07592       case 'a':
07593          if (process_sdp_a_sendonly(value, &sendonly)) {
07594             processed = TRUE;
07595             vsendonly = sendonly;
07596          }
07597          else if (process_sdp_a_audio(value, p, newaudiortp, &last_rtpmap_codec))
07598             processed = TRUE;
07599          else if (process_sdp_a_video(value, p, newvideortp, &last_rtpmap_codec))
07600             processed = TRUE;
07601          else if (process_sdp_a_text(value, p, newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec))
07602             processed = TRUE;
07603          else if (process_sdp_a_image(value, p))
07604             processed = TRUE;
07605          break;
07606       }
07607 
07608       if (option_debug > 2)
07609          ast_log(LOG_DEBUG, "Processing session-level SDP %c=%s... %s\n", type, value, (processed == TRUE)? "OK." : "UNSUPPORTED.");
07610    }
07611 
07612 
07613 
07614    /* Scan media stream (m=) specific parameters loop */
07615    while (!ast_strlen_zero(nextm)) {
07616       int audio = FALSE;
07617       int video = FALSE;
07618       int image = FALSE;
07619       int text = FALSE;
07620       int x;
07621 
07622       numberofports = 1;
07623       len = -1;
07624       start = next;
07625       m = nextm;
07626       iterator = next;
07627       nextm = get_sdp_iterate(&next, req, "m");
07628 
07629       /* Search for audio media definition */
07630       if ((sscanf(m, "audio %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
07631           (sscanf(m, "audio %30u RTP/AVP %n", &x, &len) == 1 && len > 0)) {
07632          audio = TRUE;
07633          p->offered_media[SDP_AUDIO].offered = TRUE;
07634          numberofmediastreams++;
07635          portno = x;
07636 
07637          /* Scan through the RTP payload types specified in a "m=" line: */
07638          codecs = m + len;
07639          ast_copy_string(p->offered_media[SDP_AUDIO].text, codecs, sizeof(p->offered_media[SDP_AUDIO].text));
07640          for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
07641             if (sscanf(codecs, "%30u%n", &codec, &len) != 1) {
07642                ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
07643                return -1;
07644             }
07645             if (debug)
07646                ast_verbose("Found RTP audio format %d\n", codec);
07647 
07648             ast_rtp_set_m_type(newaudiortp, codec);
07649          }
07650       /* Search for video media definition */
07651       } else if ((sscanf(m, "video %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
07652             (sscanf(m, "video %30u RTP/AVP %n", &x, &len) == 1 && len >= 0)) {
07653          video = TRUE;
07654          p->novideo = FALSE;
07655          p->offered_media[SDP_VIDEO].offered = TRUE;
07656          numberofmediastreams++;
07657          vportno = x;
07658 
07659          /* Scan through the RTP payload types specified in a "m=" line: */
07660          codecs = m + len;
07661          ast_copy_string(p->offered_media[SDP_VIDEO].text, codecs, sizeof(p->offered_media[SDP_VIDEO].text));
07662          for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
07663             if (sscanf(codecs, "%30u%n", &codec, &len) != 1) {
07664                ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
07665                return -1;
07666             }
07667             if (debug)
07668                ast_verbose("Found RTP video format %d\n", codec);
07669             ast_rtp_set_m_type(newvideortp, codec);
07670          }
07671       /* Search for text media definition */
07672       } else if ((sscanf(m, "text %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
07673             (sscanf(m, "text %30u RTP/AVP %n", &x, &len) == 1 && len > 0)) {
07674          text = TRUE;
07675          p->notext = FALSE;
07676          p->offered_media[SDP_TEXT].offered = TRUE;
07677          numberofmediastreams++;
07678          tportno = x;
07679 
07680          /* Scan through the RTP payload types specified in a "m=" line: */
07681          codecs = m + len;
07682          ast_copy_string(p->offered_media[SDP_TEXT].text, codecs, sizeof(p->offered_media[SDP_TEXT].text));
07683          for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
07684             if (sscanf(codecs, "%30u%n", &codec, &len) != 1) {
07685                ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
07686                return -1;
07687             }
07688             if (debug)
07689                ast_verbose("Found RTP text format %d\n", codec);
07690             ast_rtp_set_m_type(newtextrtp, codec);
07691          }
07692       /* Search for image media definition */
07693       } else if (p->udptl && ((sscanf(m, "image %30u udptl t38%n", &x, &len) == 1 && len > 0) ||
07694                (sscanf(m, "image %30u UDPTL t38%n", &x, &len) == 1 && len > 0) )) {
07695          image = TRUE;
07696          if (debug)
07697             ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid);
07698          p->offered_media[SDP_IMAGE].offered = TRUE;
07699          udptlportno = x;
07700          numberofmediastreams++;
07701 
07702          if (p->t38.state != T38_ENABLED) {
07703             memset(&p->t38.their_parms, 0, sizeof(p->t38.their_parms));
07704          }
07705       } else {
07706          ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m);
07707          continue;
07708       }
07709 
07710       /* Check for number of ports */
07711       if (numberofports > 1)
07712          ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports);
07713       
07714 
07715 
07716       /* Media stream specific parameters */
07717       while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') {
07718          int processed = FALSE;
07719 
07720          switch (type) {
07721          case 'c':
07722             if (audio) {
07723                if (process_sdp_c(value, &audiohp)) {
07724                   processed = TRUE;
07725                   hp = &audiohp.hp;
07726                }
07727             } else if (video) {
07728                if (process_sdp_c(value, &videohp)) {
07729                   processed = TRUE;
07730                   vhp = &videohp.hp;
07731                }
07732             } else if (text) {
07733                if (process_sdp_c(value, &texthp)) {
07734                   processed = TRUE;
07735                   thp = &texthp.hp;
07736                }
07737             } else if (image) {
07738                if (process_sdp_c(value, &imagehp)) {
07739                   processed = TRUE;
07740                   ihp = &imagehp.hp;
07741                }
07742             }
07743             break;
07744          case 'a':
07745             /* Audio specific scanning */
07746             if (audio) {
07747                if (process_sdp_a_sendonly(value, &sendonly))
07748                   processed = TRUE;
07749                else if (process_sdp_a_audio(value, p, newaudiortp, &last_rtpmap_codec))
07750                   processed = TRUE;
07751             }
07752             /* Video specific scanning */
07753             else if (video) {
07754                if (process_sdp_a_sendonly(value, &vsendonly))
07755                   processed = TRUE;
07756                else if (process_sdp_a_video(value, p, newvideortp, &last_rtpmap_codec))
07757                   processed = TRUE;
07758             }
07759             /* Text (T.140) specific scanning */
07760             else if (text) {
07761                if (process_sdp_a_text(value, p, newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec))
07762                   processed = TRUE;
07763             }
07764             /* Image (T.38 FAX) specific scanning */
07765             else if (image) {
07766                if (process_sdp_a_image(value, p))
07767                   processed = TRUE;
07768             }
07769             break;
07770          }
07771 
07772          if (option_debug > 2)
07773             ast_log(LOG_DEBUG, "Processing media-level (%s) SDP %c=%s... %s\n",
07774                   (audio == TRUE)? "audio" : (video == TRUE)? "video" : "image",
07775                   type, value,
07776                   (processed == TRUE)? "OK." : "UNSUPPORTED.");
07777       }
07778    }
07779 
07780 
07781    /* Sanity checks */
07782    if (!hp && !vhp && !thp && !ihp) {
07783       ast_log(LOG_WARNING, "Insufficient information in SDP (c=)...\n");
07784       return -1;
07785    }
07786 
07787    if (portno == -1 && vportno == -1 && udptlportno == -1  && tportno == -1)
07788       /* No acceptable offer found in SDP  - we have no ports */
07789       /* Do not change RTP or VRTP if this is a re-invite */
07790       return -2;
07791 
07792    if (numberofmediastreams > 3)
07793       /* We have too many fax, audio and/or video and/or text media streams, fail this offer */
07794       return -3;
07795 
07796    if (udptlportno == -1) {
07797       change_t38_state(p, T38_DISABLED);
07798    }
07799 
07800    /* Now gather all of the codecs that we are asked for: */
07801    ast_rtp_get_current_formats(newaudiortp, &peercapability, &peernoncodeccapability);
07802    ast_rtp_get_current_formats(newvideortp, &vpeercapability, &vpeernoncodeccapability);
07803    ast_rtp_get_current_formats(newtextrtp, &tpeercapability, &tpeernoncodeccapability);
07804  
07805    newjointcapability = p->capability & (peercapability | vpeercapability | tpeercapability);
07806    newpeercapability = (peercapability | vpeercapability | tpeercapability);
07807    newnoncodeccapability = p->noncodeccapability & peernoncodeccapability;
07808       
07809       
07810    if (debug) {
07811       /* shame on whoever coded this.... */
07812       char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE], s5[SIPBUFSIZE];
07813 
07814       ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s/text=%s, combined - %s\n",
07815              ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability),
07816              ast_getformatname_multiple(s2, SIPBUFSIZE, peercapability),
07817              ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability),
07818              ast_getformatname_multiple(s4, SIPBUFSIZE, tpeercapability),
07819              ast_getformatname_multiple(s5, SIPBUFSIZE, newjointcapability));
07820 
07821       ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n",
07822              ast_rtp_lookup_mime_multiple(s1, SIPBUFSIZE, p->noncodeccapability, 0, 0),
07823              ast_rtp_lookup_mime_multiple(s2, SIPBUFSIZE, peernoncodeccapability, 0, 0),
07824              ast_rtp_lookup_mime_multiple(s3, SIPBUFSIZE, newnoncodeccapability, 0, 0));
07825    }
07826    if (!newjointcapability && (portno != -1)) {
07827       ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n");
07828       /* Do NOT Change current setting */
07829       return -1;
07830    }
07831 
07832    /* Setup audio address and port */
07833    if (p->rtp) {
07834       if (portno > 0) {
07835          sin.sin_family = AF_INET;
07836          sin.sin_port = htons(portno);
07837          memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
07838          ast_rtp_set_peer(p->rtp, &sin);
07839          if (debug)
07840             ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
07841          /* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since                                                                                                    
07842             they are acceptable */
07843          p->jointcapability = newjointcapability;                /* Our joint codec profile for this call */
07844          p->peercapability = newpeercapability;                  /* The other sides capability in latest offer */
07845          p->jointnoncodeccapability = newnoncodeccapability;     /* DTMF capabilities */
07846 
07847          ast_rtp_pt_copy(p->rtp, newaudiortp);
07848 
07849          if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) {
07850             ast_clear_flag(&p->flags[0], SIP_DTMF);
07851             if (newnoncodeccapability & AST_RTP_DTMF) {
07852                /* XXX Would it be reasonable to drop the DSP at this point? XXX */
07853                ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
07854                /* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */
07855                ast_rtp_setdtmf(p->rtp, 1);
07856                ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
07857             } else {
07858                ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
07859             }
07860          }
07861       } else if (udptlportno > 0) {
07862          if (debug)
07863             ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session.\n");
07864       } else {
07865          ast_rtp_stop(p->rtp);
07866          if (debug)
07867             ast_verbose("Peer doesn't provide audio\n");
07868       }
07869    }
07870 
07871    /* Setup video address and port */
07872    if (p->vrtp) {
07873       if (vportno > 0) {
07874          vsin.sin_family = AF_INET;
07875          vsin.sin_port = htons(vportno);
07876          memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr));
07877          ast_rtp_set_peer(p->vrtp, &vsin);
07878          if (debug) 
07879             ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port));
07880          ast_rtp_pt_copy(p->vrtp, newvideortp);
07881       } else {
07882          ast_rtp_stop(p->vrtp);
07883          if (debug)
07884             ast_verbose("Peer doesn't provide video\n");
07885       }
07886    }
07887 
07888    /* Setup text address and port */
07889    if (p->trtp) {
07890       if (tportno > 0) {
07891          tsin.sin_family = AF_INET;
07892          tsin.sin_port = htons(tportno);
07893          memcpy(&tsin.sin_addr, thp->h_addr, sizeof(tsin.sin_addr));
07894          ast_rtp_set_peer(p->trtp, &tsin);
07895          if (debug) 
07896             ast_verbose("Peer T.140 RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port));
07897          if ((p->jointcapability & AST_FORMAT_T140RED)) {
07898             p->red = 1;
07899             rtp_red_init(p->trtp, 300, red_data_pt, 2);
07900          } else {
07901             p->red = 0;
07902          }
07903          ast_rtp_pt_copy(p->trtp, newtextrtp);
07904       } else {
07905          ast_rtp_stop(p->trtp);
07906          if (debug)
07907             ast_verbose("Peer doesn't provide T.140\n");
07908       }
07909    }
07910    /* Setup image address and port */
07911    if (p->udptl) {
07912       if (udptlportno > 0) {
07913          isin.sin_family = AF_INET;
07914          isin.sin_port = htons(udptlportno);
07915          if (ast_test_flag(&p->flags[0], SIP_NAT) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) {
07916             struct sockaddr_in remote_address = { 0, };
07917             ast_rtp_get_peer(p->rtp, &remote_address);
07918             if (remote_address.sin_addr.s_addr) {
07919                memcpy(&isin, &remote_address, sizeof(isin));
07920                if (debug) {
07921                   ast_log(LOG_DEBUG, "Peer T.38 UDPTL is set behind NAT and with destination, destination address now %s\n", ast_inet_ntoa(isin.sin_addr));
07922                }
07923             }
07924          } else {
07925             memcpy(&isin.sin_addr, ihp->h_addr, sizeof(sin.sin_addr));
07926          }
07927          ast_udptl_set_peer(p->udptl, &isin);
07928          if (debug)
07929             ast_debug(1,"Peer T.38 UDPTL is at port %s:%d\n", ast_inet_ntoa(isin.sin_addr), ntohs(isin.sin_port));
07930 
07931          /* verify the far max ifp can be calculated. this requires far max datagram to be set. */
07932          if (!ast_udptl_get_far_max_datagram(p->udptl)) {
07933             /* setting to zero will force a default if none was provided by the SDP */
07934             ast_udptl_set_far_max_datagram(p->udptl, 0);
07935          }
07936 
07937          /* Remote party offers T38, we need to update state */
07938          if ((t38action == SDP_T38_ACCEPT) &&
07939              (p->t38.state == T38_LOCAL_REINVITE)) {
07940             change_t38_state(p, T38_ENABLED);
07941          } else if ((t38action == SDP_T38_INITIATE) &&
07942                p->owner && p->lastinvite) {
07943             change_t38_state(p, T38_PEER_REINVITE); /* T38 Offered in re-invite from remote party */
07944          }
07945       } else {
07946          ast_udptl_stop(p->udptl);
07947          if (debug)
07948             ast_debug(1, "Peer doesn't provide T.38 UDPTL\n");
07949       }
07950    }
07951 
07952    if ((portno == -1) && (p->t38.state != T38_DISABLED)) {
07953       ast_debug(3, "Have T.38 but no audio, accepting offer anyway\n");
07954                 return 0;
07955         }
07956 
07957    /* Ok, we're going with this offer */
07958    ast_debug(2, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability));
07959 
07960    if (!p->owner)    /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */
07961       return 0;
07962 
07963    ast_debug(4, "We have an owner, now see if we need to change this call\n");
07964 
07965    if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
07966       if (debug) {
07967          char s1[SIPBUFSIZE], s2[SIPBUFSIZE];
07968          ast_debug(1, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n", 
07969             ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability),
07970             ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats));
07971       }
07972       p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability) | (p->capability & tpeercapability);
07973       ast_set_read_format(p->owner, p->owner->readformat);
07974       ast_set_write_format(p->owner, p->owner->writeformat);
07975    }
07976    
07977    if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) {
07978       ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
07979       /* Activate a re-invite */
07980       ast_queue_frame(p->owner, &ast_null_frame);
07981       /* Queue Manager Unhold event */
07982       append_history(p, "Unhold", "%s", req->data->str);
07983       if (global_callevents)
07984          manager_event(EVENT_FLAG_CALL, "Hold",
07985                   "Status: Off\r\n"
07986                   "Channel: %s\r\n"
07987                   "Uniqueid: %s\r\n",
07988                   p->owner->name,
07989                   p->owner->uniqueid);
07990       if (global_notifyhold)
07991          sip_peer_hold(p, FALSE);
07992       ast_clear_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */
07993    } else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) {
07994       int already_on_hold = ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD);
07995       ast_queue_control_data(p->owner, AST_CONTROL_HOLD, 
07996                    S_OR(p->mohsuggest, NULL),
07997                    !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
07998       if (sendonly)
07999          ast_rtp_stop(p->rtp);
08000       /* RTCP needs to go ahead, even if we're on hold!!! */
08001       /* Activate a re-invite */
08002       ast_queue_frame(p->owner, &ast_null_frame);
08003       /* Queue Manager Hold event */
08004       append_history(p, "Hold", "%s", req->data->str);
08005       if (global_callevents && !ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
08006          manager_event(EVENT_FLAG_CALL, "Hold",
08007                   "Status: On\r\n"
08008                   "Channel: %s\r\n"
08009                   "Uniqueid: %s\r\n",
08010                   p->owner->name, 
08011                   p->owner->uniqueid);
08012       }
08013       if (sendonly == 1)   /* One directional hold (sendonly/recvonly) */
08014          ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR);
08015       else if (sendonly == 2) /* Inactive stream */
08016          ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE);
08017       else
08018          ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE);
08019       if (global_notifyhold && !already_on_hold)
08020          sip_peer_hold(p, TRUE);
08021    }
08022    
08023    return 0;
08024 }

static int process_sdp_a_audio ( const char *  a,
struct sip_pvt p,
struct ast_rtp newaudiortp,
int *  last_rtpmap_codec 
) [static]

Definition at line 8144 of file chan_sip.c.

References ast_codec_pref_setsize(), ast_debug, ast_log(), ast_rtp_codec_getformat(), ast_rtp_codec_getpref(), ast_rtp_codec_setpref(), AST_RTP_OPT_G726_NONSTANDARD, ast_rtp_set_rtpmap_type(), ast_rtp_unset_m_type(), ast_test_flag, ast_verbose, sip_pvt::autoframing, sip_request::debug, FALSE, sip_pvt::flags, format, LOG_DEBUG, MAX_RTP_PT, option_debug, sip_pvt::rtp, SDP_MAX_RTPMAP_CODECS, sip_debug_test_pvt(), SIP_G726_NONSTANDARD, and TRUE.

Referenced by process_sdp().

08145 {
08146    int found = FALSE;
08147    int codec;
08148    char mimeSubtype[128];
08149    int debug = sip_debug_test_pvt(p);
08150 
08151    if (!strncasecmp(a, "ptime", 5)) {
08152       char *tmp = strrchr(a, ':');
08153       long int framing = 0;
08154       if (tmp) {
08155          tmp++;
08156          framing = strtol(tmp, NULL, 10);
08157          if (framing == LONG_MIN || framing == LONG_MAX) {
08158             framing = 0;
08159             ast_debug(1, "Can't read framing from SDP: %s\n", a);
08160          }
08161       }
08162       if (framing && p->autoframing) {
08163          struct ast_codec_pref *pref = ast_rtp_codec_getpref(p->rtp);
08164          int codec_n;
08165          int format = 0;
08166          for (codec_n = 0; codec_n < MAX_RTP_PT; codec_n++) {
08167             format = ast_rtp_codec_getformat(codec_n);
08168             if (!format)   /* non-codec or not found */
08169                continue;
08170             if (option_debug)
08171                ast_log(LOG_DEBUG, "Setting framing for %d to %ld\n", format, framing);
08172             ast_codec_pref_setsize(pref, format, framing);
08173          }
08174          ast_rtp_codec_setpref(p->rtp, pref);
08175       }
08176       found = TRUE;
08177    } else if (sscanf(a, "rtpmap: %30u %127[^/]/", &codec, mimeSubtype) == 2) {
08178       /* We have a rtpmap to handle */
08179       if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
08180          if (ast_rtp_set_rtpmap_type(newaudiortp, codec, "audio", mimeSubtype,
08181              ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0) != -1) {
08182             if (debug)
08183                ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec);
08184             //found_rtpmap_codecs[last_rtpmap_codec] = codec;
08185             (*last_rtpmap_codec)++;
08186             found = TRUE;
08187          } else {
08188             ast_rtp_unset_m_type(newaudiortp, codec);
08189             if (debug)
08190                ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec);
08191          }
08192       } else {
08193          if (debug)
08194             ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec);
08195       }
08196    }
08197 
08198    return found;
08199 }

static int process_sdp_a_image ( const char *  a,
struct sip_pvt p 
) [static]

Definition at line 8282 of file chan_sip.c.

References ast_debug, AST_T38_RATE_12000, AST_T38_RATE_14400, AST_T38_RATE_2400, AST_T38_RATE_4800, AST_T38_RATE_7200, AST_T38_RATE_9600, AST_T38_RATE_MANAGEMENT_LOCAL_TCF, AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF, ast_udptl_set_error_correction_scheme(), ast_udptl_set_far_max_datagram(), FALSE, ast_control_t38_parameters::fill_bit_removal, ast_control_t38_parameters::rate, ast_control_t38_parameters::rate_management, s, sip_pvt::t38, sip_pvt::t38_maxdatagram, t38properties::their_parms, ast_control_t38_parameters::transcoding_jbig, ast_control_t38_parameters::transcoding_mmr, TRUE, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, UDPTL_ERROR_CORRECTION_REDUNDANCY, and ast_control_t38_parameters::version.

Referenced by process_sdp().

08283 {
08284    int found = FALSE;
08285    char s[256];
08286    unsigned int x;
08287 
08288    if ((sscanf(a, "T38FaxMaxBuffer:%30u", &x) == 1)) {
08289       ast_debug(3, "MaxBufferSize:%d\n", x);
08290       found = TRUE;
08291    } else if ((sscanf(a, "T38MaxBitRate:%30u", &x) == 1) || (sscanf(a, "T38FaxMaxRate:%30u", &x) == 1)) {
08292       ast_debug(3, "T38MaxBitRate: %d\n", x);
08293       switch (x) {
08294       case 14400:
08295          p->t38.their_parms.rate = AST_T38_RATE_14400;
08296          break;
08297       case 12000:
08298          p->t38.their_parms.rate = AST_T38_RATE_12000;
08299          break;
08300       case 9600:
08301          p->t38.their_parms.rate = AST_T38_RATE_9600;
08302          break;
08303       case 7200:
08304          p->t38.their_parms.rate = AST_T38_RATE_7200;
08305          break;
08306       case 4800:
08307          p->t38.their_parms.rate = AST_T38_RATE_4800;
08308          break;
08309       case 2400:
08310          p->t38.their_parms.rate = AST_T38_RATE_2400;
08311          break;
08312       }
08313       found = TRUE;
08314    } else if ((sscanf(a, "T38FaxVersion:%30u", &x) == 1)) {
08315       ast_debug(3, "FaxVersion: %u\n", x);
08316       p->t38.their_parms.version = x;
08317       found = TRUE;
08318    } else if ((sscanf(a, "T38FaxMaxDatagram:%30u", &x) == 1) || (sscanf(a, "T38MaxDatagram:%30u", &x) == 1)) {
08319       /* override the supplied value if the configuration requests it */
08320       if (((signed int) p->t38_maxdatagram >= 0) && ((unsigned int) p->t38_maxdatagram > x)) {
08321          ast_debug(1, "Overriding T38FaxMaxDatagram '%d' with '%d'\n", x, p->t38_maxdatagram);
08322          x = p->t38_maxdatagram;
08323       }
08324       ast_debug(3, "FaxMaxDatagram: %u\n", x);
08325       ast_udptl_set_far_max_datagram(p->udptl, x);
08326       found = TRUE;
08327    } else if ((strncmp(a, "T38FaxFillBitRemoval", 20) == 0)) {
08328       if (sscanf(a, "T38FaxFillBitRemoval:%30u", &x) == 1) {
08329          ast_debug(3, "FillBitRemoval: %d\n", x);
08330          if (x == 1) {
08331             p->t38.their_parms.fill_bit_removal = TRUE;
08332          }
08333       } else {
08334          ast_debug(3, "FillBitRemoval\n");
08335          p->t38.their_parms.fill_bit_removal = TRUE;
08336       }
08337       found = TRUE;
08338    } else if ((strncmp(a, "T38FaxTranscodingMMR", 20) == 0)) {
08339       if (sscanf(a, "T38FaxTranscodingMMR:%30u", &x) == 1) {
08340          ast_debug(3, "Transcoding MMR: %d\n", x);
08341          if (x == 1) {
08342             p->t38.their_parms.transcoding_mmr = TRUE;
08343          }
08344       } else {
08345          ast_debug(3, "Transcoding MMR\n");
08346          p->t38.their_parms.transcoding_mmr = TRUE;
08347       }
08348       found = TRUE;
08349    } else if ((strncmp(a, "T38FaxTranscodingJBIG", 21) == 0)) {
08350       if (sscanf(a, "T38FaxTranscodingJBIG:%30u", &x) == 1) {
08351          ast_debug(3, "Transcoding JBIG: %d\n", x);
08352          if (x == 1) {
08353             p->t38.their_parms.transcoding_jbig = TRUE;
08354          }
08355       } else {
08356          ast_debug(3, "Transcoding JBIG\n");
08357          p->t38.their_parms.transcoding_jbig = TRUE;
08358       }
08359       found = TRUE;
08360    } else if ((sscanf(a, "T38FaxRateManagement:%255s", s) == 1)) {
08361       ast_debug(3, "RateManagement: %s\n", s);
08362       if (!strcasecmp(s, "localTCF"))
08363          p->t38.their_parms.rate_management = AST_T38_RATE_MANAGEMENT_LOCAL_TCF;
08364       else if (!strcasecmp(s, "transferredTCF"))
08365          p->t38.their_parms.rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF;
08366       found = TRUE;
08367    } else if ((sscanf(a, "T38FaxUdpEC:%255s", s) == 1)) {
08368       ast_debug(3, "UDP EC: %s\n", s);
08369       if (!strcasecmp(s, "t38UDPRedundancy")) {
08370          ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_REDUNDANCY);
08371       } else if (!strcasecmp(s, "t38UDPFEC")) {
08372          ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_FEC);
08373       } else {
08374          ast_udptl_set_error_correction_scheme(p->udptl, UDPTL_ERROR_CORRECTION_NONE);
08375       }
08376       found = TRUE;
08377    }
08378 
08379    return found;
08380 }

static int process_sdp_a_sendonly ( const char *  a,
int *  sendonly 
) [static]

Definition at line 8124 of file chan_sip.c.

References FALSE, and TRUE.

Referenced by process_sdp().

08125 {
08126    int found = FALSE;
08127 
08128    if (!strcasecmp(a, "sendonly")) {
08129       if (*sendonly == -1)
08130          *sendonly = 1;
08131       found = TRUE;
08132    } else if (!strcasecmp(a, "inactive")) {
08133       if (*sendonly == -1)
08134          *sendonly = 2;
08135       found = TRUE;
08136    }  else if (!strcasecmp(a, "sendrecv")) {
08137       if (*sendonly == -1)
08138          *sendonly = 0;
08139       found = TRUE;
08140    }
08141    return found;
08142 }

static int process_sdp_a_text ( const char *  a,
struct sip_pvt p,
struct ast_rtp newtextrtp,
char *  red_fmtp,
int *  red_num_gen,
int *  red_data_pt,
int *  last_rtpmap_codec 
) [static]

Definition at line 8234 of file chan_sip.c.

References ast_rtp_set_rtpmap_type(), ast_verbose, sip_request::debug, FALSE, RED_MAX_GENERATION, SDP_MAX_RTPMAP_CODECS, sip_debug_test_pvt(), sip_pvt::trtp, and TRUE.

Referenced by process_sdp().

08235 {
08236    int found = FALSE;
08237    int codec;
08238    char mimeSubtype[128];
08239    char *red_cp;
08240    int debug = sip_debug_test_pvt(p);
08241 
08242    if (sscanf(a, "rtpmap: %30u %127[^/]/", &codec, mimeSubtype) == 2) {
08243       /* We have a rtpmap to handle */
08244       if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
08245          if (!strncasecmp(mimeSubtype, "T140", 4)) { /* Text */
08246             if (p->trtp) {
08247                /* ast_verbose("Adding t140 mimeSubtype to textrtp struct\n"); */
08248                ast_rtp_set_rtpmap_type(newtextrtp, codec, "text", mimeSubtype, 0);
08249                found = TRUE;
08250             }
08251          } else if (!strncasecmp(mimeSubtype, "RED", 3)) { /* Text with Redudancy */
08252             if (p->trtp) {
08253                ast_rtp_set_rtpmap_type(newtextrtp, codec, "text", mimeSubtype, 0);
08254                sprintf(red_fmtp, "fmtp:%d ", codec); 
08255                if (debug)
08256                   ast_verbose("RED submimetype has payload type: %d\n", codec);
08257                found = TRUE;
08258             }
08259          }
08260       } else {
08261          if (debug)
08262             ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec);
08263       }
08264    } else if (!strncmp(a, red_fmtp, strlen(red_fmtp))) {
08265       /* count numbers of generations in fmtp */
08266       red_cp = &red_fmtp[strlen(red_fmtp)];
08267       strncpy(red_fmtp, a, 100);
08268 
08269       sscanf(red_cp, "%30u", &red_data_pt[*red_num_gen]);
08270       red_cp = strtok(red_cp, "/");
08271       while (red_cp && (*red_num_gen)++ < RED_MAX_GENERATION) {
08272          sscanf(red_cp, "%30u", &red_data_pt[*red_num_gen]);
08273          red_cp = strtok(NULL, "/");
08274       }
08275       red_cp = red_fmtp;
08276       found = TRUE;
08277    }
08278 
08279    return found;
08280 }

static int process_sdp_a_video ( const char *  a,
struct sip_pvt p,
struct ast_rtp newvideortp,
int *  last_rtpmap_codec 
) [static]

Definition at line 8201 of file chan_sip.c.

References ast_rtp_set_rtpmap_type(), ast_rtp_unset_m_type(), ast_verbose, sip_request::debug, FALSE, SDP_MAX_RTPMAP_CODECS, sip_debug_test_pvt(), and TRUE.

Referenced by process_sdp().

08202 {
08203    int found = FALSE;
08204    int codec;
08205    char mimeSubtype[128];
08206    int debug = sip_debug_test_pvt(p);
08207 
08208    if (sscanf(a, "rtpmap: %30u %127[^/]/", &codec, mimeSubtype) == 2) {
08209       /* We have a rtpmap to handle */
08210       if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
08211          /* Note: should really look at the '#chans' params too */
08212          if (!strncasecmp(mimeSubtype, "H26", 3) || !strncasecmp(mimeSubtype, "MP4", 3)) {
08213             if (ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0) != -1) {
08214                if (debug)
08215                   ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec);
08216                //found_rtpmap_codecs[last_rtpmap_codec] = codec;
08217                (*last_rtpmap_codec)++;
08218                found = TRUE;
08219             } else {
08220                ast_rtp_unset_m_type(newvideortp, codec);
08221                if (debug) 
08222                   ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec);
08223             }
08224          }
08225       } else {
08226          if (debug)
08227             ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec);
08228       }
08229    }
08230 
08231    return found;
08232 }

static int process_sdp_c ( const char *  c,
struct ast_hostent hp 
) [static]

Definition at line 8105 of file chan_sip.c.

References ast_gethostbyname(), ast_log(), FALSE, hp, LOG_WARNING, and TRUE.

Referenced by process_sdp().

08106 {
08107    char host[258];
08108    struct hostent *hp;
08109 
08110    /* Check for Media-description-level-address */
08111    if (sscanf(c, "IN IP4 %255s", host) != 1) {
08112       ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
08113       return FALSE;
08114    } else {
08115       if (!(hp = ast_gethostbyname(host, ast_hp))) {
08116          ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in c= line, '%s'\n", c);
08117          return FALSE;
08118       }
08119       return TRUE;
08120    }
08121    return FALSE;
08122 }

static int process_sdp_o ( const char *  o,
struct sip_pvt p 
) [static]

Definition at line 8026 of file chan_sip.c.

References ast_debug, ast_log(), ast_strdupa, ast_strlen_zero(), ast_test_flag, sip_pvt::callid, FALSE, sip_pvt::flags, LOG_WARNING, sip_pvt::session_modify, sip_pvt::sessionversion_remote, SIP_PAGE2_IGNORESDPVERSION, t38properties::state, strsep(), sip_pvt::t38, T38_LOCAL_REINVITE, and TRUE.

Referenced by process_sdp().

08027 {
08028    char *o_copy;
08029    char *token;
08030    int64_t rua_version;
08031 
08032    /* Store the SDP version number of remote UA. This will allow us to
08033    distinguish between session modifications and session refreshes. If
08034    the remote UA does not send an incremented SDP version number in a
08035    subsequent RE-INVITE then that means its not changing media session.
08036    The RE-INVITE may have been sent to update connected party, remote
08037    target or to refresh the session (Session-Timers).  Asterisk must not
08038    change media session and increment its own version number in answer
08039    SDP in this case. */
08040 
08041    p->session_modify = TRUE;
08042 
08043    if (ast_strlen_zero(o)) {
08044       ast_log(LOG_WARNING, "SDP syntax error. SDP without an o= line\n");
08045       return FALSE;
08046    }
08047 
08048    o_copy = ast_strdupa(o);
08049    token = strsep(&o_copy, " ");  /* Skip username   */
08050    if (!o_copy) {
08051       ast_log(LOG_WARNING, "SDP syntax error in o= line username\n");
08052       return FALSE;
08053    }
08054    token = strsep(&o_copy, " ");  /* Skip session-id */
08055    if (!o_copy) {
08056       ast_log(LOG_WARNING, "SDP syntax error in o= line session-id\n");
08057       return FALSE;
08058    }
08059    token = strsep(&o_copy, " ");  /* Version         */
08060    if (!o_copy) {
08061       ast_log(LOG_WARNING, "SDP syntax error in o= line\n");
08062       return FALSE;
08063    }
08064    if (!sscanf(token, "%30" SCNd64, &rua_version)) {
08065       ast_log(LOG_WARNING, "SDP syntax error in o= line version\n");
08066       return FALSE;
08067    }
08068 
08069    /* we need to check the SDP version number the other end sent us;
08070     * our rules for deciding what to accept are a bit complex.
08071     *
08072     * 1) if 'ignoresdpversion' has been set for this dialog, then
08073     *    we will just accept whatever they sent and assume it is
08074     *    a modification of the session, even if it is not
08075     * 2) otherwise, if this is the first SDP we've seen from them
08076     *    we accept it
08077     * 3) otherwise, if the new SDP version number is higher than the
08078     *    old one, we accept it
08079     * 4) otherwise, if this SDP is in response to us requesting a switch
08080     *    to T.38, we accept the SDP, but also generate a warning message
08081     *    that this peer should have the 'ignoresdpversion' option set,
08082     *    because it is not following the SDP offer/answer RFC; if we did
08083     *    not request a switch to T.38, then we stop parsing the SDP, as it
08084     *    has not changed from the previous version
08085     */
08086 
08087    if (ast_test_flag(&p->flags[1], SIP_PAGE2_IGNORESDPVERSION) ||
08088        (p->sessionversion_remote < 0) ||
08089        (p->sessionversion_remote < rua_version)) {
08090       p->sessionversion_remote = rua_version;
08091    } else {
08092       if (p->t38.state == T38_LOCAL_REINVITE) {
08093          p->sessionversion_remote = rua_version;
08094          ast_log(LOG_WARNING, "Call %s responded to our T.38 reinvite without changing SDP version; 'ignoresdpversion' should be set for this peer.\n", p->callid);
08095       } else {
08096          p->session_modify = FALSE;
08097          ast_debug(2, "Call %s responded to our reinvite without changing SDP version; ignoring SDP.\n", p->callid);
08098          return FALSE;
08099       }
08100    }
08101 
08102    return TRUE;
08103 }

static struct sip_proxy* proxy_allocate ( char *  name,
char *  port,
int  force 
) [static]

Allocate and initialize sip proxy.

Definition at line 2944 of file chan_sip.c.

References ao2_alloc, ast_copy_string(), ast_strlen_zero(), port_str2int(), proxy_update(), and STANDARD_SIP_PORT.

Referenced by build_peer().

02945 {
02946    struct sip_proxy *proxy;
02947 
02948    if (ast_strlen_zero(name)) {
02949       return NULL;
02950    }
02951 
02952    proxy = ao2_alloc(sizeof(*proxy), NULL);
02953    if (!proxy)
02954       return NULL;
02955    proxy->force = force;
02956    ast_copy_string(proxy->name, name, sizeof(proxy->name));
02957    proxy->ip.sin_port = htons(port_str2int(port, STANDARD_SIP_PORT));
02958    proxy_update(proxy);
02959    return proxy;
02960 }

static int proxy_update ( struct sip_proxy proxy  )  [static]

Resolve DNS srv name or host name in a sip_proxy structure

Definition at line 2913 of file chan_sip.c.

References ast_get_ip_or_srv(), ast_log(), FALSE, inet_aton(), sip_proxy::ip, sip_proxy::last_dnsupdate, LOG_WARNING, sip_proxy::name, and TRUE.

Referenced by proxy_allocate().

02914 {
02915    /* if it's actually an IP address and not a name,
02916            there's no need for a managed lookup */
02917    if (!inet_aton(proxy->name, &proxy->ip.sin_addr)) {
02918       /* Ok, not an IP address, then let's check if it's a domain or host */
02919       /* XXX Todo - if we have proxy port, don't do SRV */
02920       if (ast_get_ip_or_srv(&proxy->ip, proxy->name, global_srvlookup ? "_sip._udp" : NULL) < 0) {
02921          ast_log(LOG_WARNING, "Unable to locate host '%s'\n", proxy->name);
02922          return FALSE;
02923       }
02924    }
02925    proxy->last_dnsupdate = time(NULL);
02926    return TRUE;
02927 }

static int queue_request ( struct sip_pvt p,
const struct sip_request req 
) [static]

Definition at line 20938 of file chan_sip.c.

References ast_calloc, AST_LIST_INSERT_TAIL, ast_sched_add(), copy_request(), dialog_ref(), dialog_unref(), sip_request::next, sip_pvt::request_queue, sip_pvt::request_queue_sched_id, sched, and scheduler_process_request_queue().

Referenced by handle_request_do().

20939 {
20940    struct sip_request *newreq;
20941 
20942    if (!(newreq = ast_calloc(1, sizeof(*newreq)))) {
20943       return -1;
20944    }
20945 
20946    copy_request(newreq, req);
20947    AST_LIST_INSERT_TAIL(&p->request_queue, newreq, next);
20948    if (p->request_queue_sched_id == -1) {
20949       if ((p->request_queue_sched_id = ast_sched_add(sched, 10, scheduler_process_request_queue, dialog_ref(p, "Increment refcount to pass dialog pointer to sched callback"))) == -1) {
20950          dialog_unref(p, "Decrement refcount due to sched_add failure");
20951       }
20952    }
20953 
20954    return 0;
20955 }

static struct sip_peer * realtime_peer ( const char *  peername,
struct sockaddr_in *  sin,
int  devstate_only 
) [static]

realtime_peer: Get peer from realtime storage Checks the "sippeers" realtime family from extconfig.conf Checks the "sipregs" realtime family from extconfig.conf if it's configured. This returns a pointer to a peer and because we use build_peer, we can rest assured that the refcount is bumped.

Note:
If this one loaded something, then we need to ensure that the host field matched. The only reason why we can't have this as a criteria is because we only have the IP address and the host field might be set as a name (and the reverse PTR might not match).

Definition at line 4352 of file chan_sip.c.

References ahp, ast_check_realtime(), ast_gethostbyname(), ast_inet_ntoa(), ast_load_realtime(), ast_variables_destroy(), hp, ipaddr, ast_variable::name, ast_variable::next, SENTINEL, ast_variable::value, and var.

04353 {
04354    struct sip_peer *peer;
04355    struct ast_variable *var = NULL;
04356    struct ast_variable *varregs = NULL;
04357    struct ast_variable *tmp;
04358    struct ast_config *peerlist = NULL;
04359    char ipaddr[INET_ADDRSTRLEN];
04360    char portstring[6]; /*up to 5 digits plus null terminator*/
04361    char *cat = NULL;
04362    unsigned short portnum;
04363    int realtimeregs = ast_check_realtime("sipregs");
04364 
04365    /* First check on peer name */
04366    if (newpeername) {
04367       if (realtimeregs)
04368          varregs = ast_load_realtime("sipregs", "name", newpeername, SENTINEL);
04369 
04370       var = ast_load_realtime("sippeers", "name", newpeername, "host", "dynamic", SENTINEL);
04371       if (!var && sin)
04372          var = ast_load_realtime("sippeers", "name", newpeername, "host", ast_inet_ntoa(sin->sin_addr), SENTINEL);
04373       if (!var) {
04374          var = ast_load_realtime("sippeers", "name", newpeername, SENTINEL);
04375          /*!\note
04376           * If this one loaded something, then we need to ensure that the host
04377           * field matched.  The only reason why we can't have this as a criteria
04378           * is because we only have the IP address and the host field might be
04379           * set as a name (and the reverse PTR might not match).
04380           */
04381          if (var && sin) {
04382             for (tmp = var; tmp; tmp = tmp->next) {
04383                if (!strcasecmp(tmp->name, "host")) {
04384                   struct hostent *hp;
04385                   struct ast_hostent ahp;
04386                   if (!(hp = ast_gethostbyname(tmp->value, &ahp)) || (memcmp(hp->h_addr, &sin->sin_addr, sizeof(hp->h_addr)))) {
04387                      /* No match */
04388                      ast_variables_destroy(var);
04389                      var = NULL;
04390                   }
04391                   break;
04392                }
04393             }
04394          }
04395       }
04396    }
04397 
04398    if (!var && sin) {   /* Then check on IP address for dynamic peers */
04399       ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr));
04400       portnum = ntohs(sin->sin_port);
04401       sprintf(portstring, "%u", portnum);
04402       var = ast_load_realtime("sippeers", "host", ipaddr, "port", portstring, SENTINEL);  /* First check for fixed IP hosts */
04403       if (var) {
04404          if (realtimeregs) {
04405             newpeername = get_name_from_variable(var, newpeername);
04406             varregs = ast_load_realtime("sipregs", "name", newpeername, SENTINEL);
04407          }
04408       } else {
04409          if (realtimeregs)
04410             varregs = ast_load_realtime("sipregs", "ipaddr", ipaddr, "port", portstring, SENTINEL); /* Then check for registered hosts */
04411          else
04412             var = ast_load_realtime("sippeers", "ipaddr", ipaddr, "port", portstring, SENTINEL); /* Then check for registered hosts */
04413          if (varregs) {
04414             newpeername = get_name_from_variable(varregs, newpeername);
04415             var = ast_load_realtime("sippeers", "name", newpeername, SENTINEL);
04416          }
04417       }
04418       if (!var) { /*We couldn't match on ipaddress and port, so we need to check if port is insecure*/
04419          peerlist = ast_load_realtime_multientry("sippeers", "host", ipaddr, SENTINEL);
04420          if (peerlist) {
04421             var = get_insecure_variable_from_config(peerlist);
04422             if(var) {
04423                if (realtimeregs) {
04424                   newpeername = get_name_from_variable(var, newpeername);
04425                   varregs = ast_load_realtime("sipregs", "name", newpeername, SENTINEL);
04426                }
04427             } else { /*var wasn't found in the list of "hosts", so try "ipaddr"*/
04428                peerlist = NULL;
04429                cat = NULL;
04430                peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", ipaddr, SENTINEL);
04431                if(peerlist) {
04432                   var = get_insecure_variable_from_config(peerlist);
04433                   if(var) {
04434                      if (realtimeregs) {
04435                         newpeername = get_name_from_variable(var, newpeername);
04436                         varregs = ast_load_realtime("sipregs", "name", newpeername, SENTINEL);
04437                      }
04438                   }
04439                }
04440             }
04441          } else {
04442             if (realtimeregs) {
04443                peerlist = ast_load_realtime_multientry("sipregs", "ipaddr", ipaddr, SENTINEL);
04444                if (peerlist) {
04445                   varregs = get_insecure_variable_from_config(peerlist);
04446                   if (varregs) {
04447                      newpeername = get_name_from_variable(varregs, newpeername);
04448                      var = ast_load_realtime("sippeers", "name", newpeername, SENTINEL);
04449                   }
04450                }
04451             } else {
04452                peerlist = ast_load_realtime_multientry("sippeers", "ipaddr", ipaddr, SENTINEL);
04453                if (peerlist) {
04454                   var = get_insecure_variable_from_config(peerlist);
04455                   if (var) {
04456                      newpeername = get_name_from_variable(var, newpeername);
04457                      varregs = ast_load_realtime("sipregs", "name", newpeername, SENTINEL);
04458                   }
04459                }
04460             }
04461          }
04462       }
04463    }
04464 
04465    if (!var) {
04466       if (peerlist)
04467          ast_config_destroy(peerlist);
04468       return NULL;
04469    }
04470 
04471    for (tmp = var; tmp; tmp = tmp->next) {
04472       /* If this is type=user, then skip this object. */
04473       if (!strcasecmp(tmp->name, "type") &&
04474           !strcasecmp(tmp->value, "user")) {
04475          if(peerlist)
04476             ast_config_destroy(peerlist);
04477          else {
04478             ast_variables_destroy(var);
04479             ast_variables_destroy(varregs);
04480          }
04481          return NULL;
04482       } else if (!newpeername && !strcasecmp(tmp->name, "name")) {
04483          newpeername = tmp->value;
04484       }
04485    }
04486    
04487    if (!newpeername) {  /* Did not find peer in realtime */
04488       ast_log(LOG_WARNING, "Cannot Determine peer name ip=%s\n", ipaddr);
04489       if(peerlist)
04490          ast_config_destroy(peerlist);
04491       else
04492          ast_variables_destroy(var);
04493       return NULL;
04494    }
04495 
04496 
04497    /* Peer found in realtime, now build it in memory */
04498    peer = build_peer(newpeername, var, varregs, TRUE, devstate_only);
04499    if (!peer) {
04500       if(peerlist)
04501          ast_config_destroy(peerlist);
04502       else {
04503          ast_variables_destroy(var);
04504          ast_variables_destroy(varregs);
04505       }
04506       return NULL;
04507    }
04508 
04509    ast_debug(3, "-REALTIME- loading peer from database to memory. Name: %s. Peer objects: %d\n", peer->name, rpeerobjs);
04510 
04511    if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && !devstate_only) {
04512       /* Cache peer */
04513       ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS);
04514       if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
04515          AST_SCHED_REPLACE_UNREF(peer->expire, sched, global_rtautoclear * 1000, expire_register, peer,
04516                unref_peer(_data, "remove registration ref"),
04517                unref_peer(peer, "remove registration ref"),
04518                ref_peer(peer, "add registration ref"));
04519       }
04520       ao2_t_link(peers, peer, "link peer into peers table");
04521       if (peer->addr.sin_addr.s_addr) {
04522          ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
04523       }
04524    }
04525    peer->is_realtime = 1;
04526    if (peerlist)
04527       ast_config_destroy(peerlist);
04528    else {
04529       ast_variables_destroy(var);
04530       ast_variables_destroy(varregs);
04531    }
04532 
04533    return peer;
04534 }

static void realtime_update_peer ( const char *  peername,
struct sockaddr_in *  sin,
const char *  username,
const char *  fullcontact,
const char *  useragent,
int  expirey,
int  deprecated_username,
int  lastms 
) [static]

Update peer object in realtime storage If the Asterisk system name is set in asterisk.conf, we will use that name and store that in the "regserver" field in the sippeers table to facilitate multi-server setups.

Definition at line 4156 of file chan_sip.c.

References ast_check_realtime(), ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_inet_ntoa(), ast_strlen_zero(), ast_update_realtime(), ipaddr, sip_settings::rtsave_sysname, SENTINEL, and sip_cfg.

04157 {
04158    char port[10];
04159    char ipaddr[INET_ADDRSTRLEN];
04160    char regseconds[20];
04161    char *tablename = NULL;
04162    char str_lastms[20];
04163 
04164    const char *sysname = ast_config_AST_SYSTEM_NAME;
04165    char *syslabel = NULL;
04166 
04167    time_t nowtime = time(NULL) + expirey;
04168    const char *fc = fullcontact ? "fullcontact" : NULL;
04169 
04170    int realtimeregs = ast_check_realtime("sipregs");
04171 
04172    tablename = realtimeregs ? "sipregs" : "sippeers";
04173    
04174 
04175    snprintf(str_lastms, sizeof(str_lastms), "%d", lastms);
04176    snprintf(regseconds, sizeof(regseconds), "%d", (int)nowtime);  /* Expiration time */
04177    ast_copy_string(ipaddr, ast_inet_ntoa(sin->sin_addr), sizeof(ipaddr));
04178    snprintf(port, sizeof(port), "%d", ntohs(sin->sin_port));
04179    
04180    if (ast_strlen_zero(sysname)) /* No system name, disable this */
04181       sysname = NULL;
04182    else if (sip_cfg.rtsave_sysname)
04183       syslabel = "regserver";
04184 
04185    if (fc) {
04186       ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr,
04187          "port", port, "regseconds", regseconds,
04188          deprecated_username ? "username" : "defaultuser", defaultuser,
04189          "useragent", useragent, "lastms", str_lastms,
04190          fc, fullcontact, syslabel, sysname, SENTINEL); /* note fc and syslabel _can_ be NULL */
04191    } else {
04192       ast_update_realtime(tablename, "name", peername, "ipaddr", ipaddr,
04193          "port", port, "regseconds", regseconds,
04194          "useragent", useragent, "lastms", str_lastms,
04195          deprecated_username ? "username" : "defaultuser", defaultuser,
04196          syslabel, sysname, SENTINEL); /* note syslabel _can_ be NULL */
04197    }
04198 }

static void receive_message ( struct sip_pvt p,
struct sip_request req 
) [static]

Receive SIP MESSAGE method messages.

Note:
We only handle messages within current calls currently Reference: RFC 3428

Definition at line 13459 of file chan_sip.c.

References AST_FRAME_TEXT, ast_log(), ast_queue_frame(), ast_verbose, buf, sip_pvt::callid, DEFAULT_TRANS_TIMEOUT, f, FALSE, get_header(), get_msg_text(), LOG_WARNING, sip_pvt::owner, sip_debug_test_pvt(), sip_scheddestroy(), and transmit_response().

Referenced by handle_request_message().

13460 {
13461    char buf[1400];   
13462    struct ast_frame f;
13463    const char *content_type = get_header(req, "Content-Type");
13464 
13465    if (strncmp(content_type, "text/plain", strlen("text/plain"))) { /* No text/plain attachment */
13466       transmit_response(p, "415 Unsupported Media Type", req); /* Good enough, or? */
13467       if (!p->owner)
13468          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13469       return;
13470    }
13471 
13472    if (get_msg_text(buf, sizeof(buf), req, FALSE)) {
13473       ast_log(LOG_WARNING, "Unable to retrieve text from %s\n", p->callid);
13474       transmit_response(p, "202 Accepted", req);
13475       if (!p->owner)
13476          sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13477       return;
13478    }
13479 
13480    if (p->owner) {
13481       if (sip_debug_test_pvt(p))
13482          ast_verbose("SIP Text message received: '%s'\n", buf);
13483       memset(&f, 0, sizeof(f));
13484       f.frametype = AST_FRAME_TEXT;
13485       f.subclass = 0;
13486       f.offset = 0;
13487       f.data.ptr = buf;
13488       f.datalen = strlen(buf);
13489       ast_queue_frame(p->owner, &f);
13490       transmit_response(p, "202 Accepted", req); /* We respond 202 accepted, since we relay the message */
13491       return;
13492    }
13493 
13494    /* Message outside of a call, we do not support that */
13495    ast_log(LOG_WARNING, "Received message to %s from %s, dropped it...\n  Content-Type:%s\n  Message: %s\n", get_header(req, "To"), get_header(req, "From"), content_type, buf);
13496    transmit_response(p, "405 Method Not Allowed", req);
13497    sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
13498    return;
13499 }

static struct sip_peer* ref_peer ( struct sip_peer peer,
char *  tag 
) [static]

Definition at line 2755 of file chan_sip.c.

References ao2_t_ref.

Referenced by build_peer(), handle_request_subscribe(), handle_response_peerpoke(), parse_register_contact(), reg_source_db(), sip_poke_all_peers(), sip_poke_noanswer(), sip_poke_peer(), and sip_unregister().

02756 {
02757    ao2_t_ref(peer, 1, tag);
02758    return peer;
02759 }

static struct sip_proxy* ref_proxy ( struct sip_pvt pvt,
struct sip_proxy proxy 
) [static]

maintain proper refcounts for a sip_pvt's outboundproxy

This function sets pvt's outboundproxy pointer to the one referenced by the proxy parameter. Because proxy may be a refcounted object, and because pvt's old outboundproxy may also be a refcounted object, we need to maintain the proper refcounts.

Parameters:
pvt The sip_pvt for which we wish to set the outboundproxy
proxy The sip_proxy which we will point pvt towards.
Returns:
Returns void

Definition at line 2772 of file chan_sip.c.

References ao2_ref, global_outboundproxy, and sip_pvt::outboundproxy.

Referenced by __sip_ack(), create_addr(), create_addr_from_peer(), and transmit_register().

02773 {
02774    struct sip_proxy *old_obproxy = pvt->outboundproxy;
02775    /* Cool, now get the refs correct */
02776    if (proxy && proxy != &global_outboundproxy) {
02777       ao2_ref(proxy, +1);
02778    }
02779    pvt->outboundproxy = proxy;
02780    if (old_obproxy && old_obproxy != &global_outboundproxy) {
02781       ao2_ref(old_obproxy, -1);
02782    }
02783    return proxy;
02784 }

static const char * referstatus2str ( enum referstatus  rstatus  )  [static]

Convert transfer status to string.

Definition at line 2884 of file chan_sip.c.

References map_x_s(), and referstatusstrings.

Referenced by show_channels_cb().

02885 {
02886    return map_x_s(referstatusstrings, rstatus, "");
02887 }

static void reg_source_db ( struct sip_peer peer  )  [static]

Get registration details from Asterisk DB.

Definition at line 11285 of file chan_sip.c.

References sip_peer::addr, ast_copy_string(), ast_db_get(), ast_debug, ast_inet_ntoa(), ast_random(), AST_SCHED_REPLACE_UNREF, sip_request::data, sip_peer::expire, expire_register(), sip_peer::fullcontact, inet_aton(), sip_peer::name, sip_peer::pokeexpire, ref_peer(), register_peer_exten(), sip_peer::rt_fromcontact, sched, sip_poke_peer(), sip_poke_peer_s(), strsep(), TRUE, unref_peer(), and sip_peer::username.

11286 {
11287    char data[256];
11288    struct in_addr in;
11289    int expire;
11290    int port;
11291    char *scan, *addr, *port_str, *expiry_str, *username, *contact;
11292 
11293    if (peer->rt_fromcontact) 
11294       return;
11295    if (ast_db_get("SIP/Registry", peer->name, data, sizeof(data)))
11296       return;
11297 
11298    scan = data;
11299    addr = strsep(&scan, ":");
11300    port_str = strsep(&scan, ":");
11301    expiry_str = strsep(&scan, ":");
11302    username = strsep(&scan, ":");
11303    contact = scan;   /* Contact include sip: and has to be the last part of the database entry as long as we use : as a separator */
11304 
11305    if (!inet_aton(addr, &in))
11306       return;
11307 
11308    if (port_str)
11309       port = atoi(port_str);
11310    else
11311       return;
11312 
11313    if (expiry_str)
11314       expire = atoi(expiry_str);
11315    else
11316       return;
11317 
11318    if (username)
11319       ast_copy_string(peer->username, username, sizeof(peer->username));
11320    if (contact)
11321       ast_copy_string(peer->fullcontact, contact, sizeof(peer->fullcontact));
11322 
11323    ast_debug(2, "SIP Seeding peer from astdb: '%s' at %s@%s:%d for %d\n",
11324        peer->name, peer->username, ast_inet_ntoa(in), port, expire);
11325 
11326    memset(&peer->addr, 0, sizeof(peer->addr));
11327    peer->addr.sin_family = AF_INET;
11328    peer->addr.sin_addr = in;
11329    peer->addr.sin_port = htons(port);
11330    if (sipsock < 0) {
11331       /* SIP isn't up yet, so schedule a poke only, pretty soon */
11332       AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, ast_random() % 5000 + 1, sip_poke_peer_s, peer,
11333             unref_peer(_data, "removing poke peer ref"),
11334             unref_peer(peer, "removing poke peer ref"),
11335             ref_peer(peer, "adding poke peer ref"));
11336    } else {
11337       sip_poke_peer(peer, 0);
11338    }
11339    AST_SCHED_REPLACE_UNREF(peer->expire, sched, (expire + 10) * 1000, expire_register, peer,
11340          unref_peer(_data, "remove registration ref"),
11341          unref_peer(peer, "remove registration ref"),
11342          ref_peer(peer, "add registration ref"));
11343    register_peer_exten(peer, TRUE);
11344 }

static void register_peer_exten ( struct sip_peer peer,
int  onoff 
) [static]

Automatically add peer extension to dial plan.

Definition at line 4201 of file chan_sip.c.

References ast_add_extension(), ast_context_find(), ast_context_remove_extension(), ast_copy_string(), ast_exists_extension(), ast_free_ptr, ast_log(), ast_strdup, ast_strlen_zero(), context, E_MATCH, ext, LOG_WARNING, sip_peer::name, pbx_find_extension(), sip_peer::regexten, S_OR, pbx_find_info::stacklen, and strsep().

04202 {
04203    char multi[256];
04204    char *stringp, *ext, *context;
04205    struct pbx_find_info q = { .stacklen = 0 };
04206 
04207    /* XXX note that global_regcontext is both a global 'enable' flag and
04208     * the name of the global regexten context, if not specified
04209     * individually.
04210     */
04211    if (ast_strlen_zero(global_regcontext))
04212       return;
04213 
04214    ast_copy_string(multi, S_OR(peer->regexten, peer->name), sizeof(multi));
04215    stringp = multi;
04216    while ((ext = strsep(&stringp, "&"))) {
04217       if ((context = strchr(ext, '@'))) {
04218          *context++ = '\0';   /* split ext@context */
04219          if (!ast_context_find(context)) {
04220             ast_log(LOG_WARNING, "Context %s must exist in regcontext= in sip.conf!\n", context);
04221             continue;
04222          }
04223       } else {
04224          context = global_regcontext;
04225       }
04226       if (onoff) {
04227          if (!ast_exists_extension(NULL, context, ext, 1, NULL)) {
04228             ast_add_extension(context, 1, ext, 1, NULL, NULL, "Noop",
04229                 ast_strdup(peer->name), ast_free_ptr, "SIP");
04230          }
04231       } else if (pbx_find_extension(NULL, NULL, &q, context, ext, 1, NULL, "", E_MATCH)) {
04232          ast_context_remove_extension(context, ext, 1, NULL);
04233       }
04234    }
04235 }

static enum check_auth_result register_verify ( struct sip_pvt p,
struct sockaddr_in *  sin,
struct sip_request req,
char *  uri 
) [static]

Verify registration of user

Definition at line 12140 of file chan_sip.c.

References sip_peer::addr, ao2_t_link, ast_apply_ha(), ast_copy_flags, ast_copy_string(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_inet_ntoa(), AST_LIST_EMPTY, ast_log(), ast_rtp_codec_setpref(), ast_set_flag, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_uri_decode(), AUTH_ACL_FAILED, AUTH_BAD_TRANSPORT, AUTH_NOT_FOUND, AUTH_PEER_NOT_DYNAMIC, AUTH_SECRET_FAILED, AUTH_UNKNOWN_DOMAIN, AUTH_USERNAME_MISMATCH, sip_peer::autoframing, sip_pvt::autoframing, build_contact(), check_auth(), check_request_transport, check_sip_domain(), EVENT_FLAG_SYSTEM, exten, FALSE, find_peer(), FINDPEERS, sip_peer::flags, sip_pvt::flags, sip_peer::fullcontact, get_header(), get_in_brackets(), sip_peer::ha, sip_peer::host_dynamic, sip_request::ignore, sip_pvt::initreq, sip_peer::lastmsgssent, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event, sip_peer::md5secret, sip_peer::name, name, parse_register_contact(), PARSE_REGISTER_DENIED, PARSE_REGISTER_FAILED, PARSE_REGISTER_QUERY, PARSE_REGISTER_UPDATE, peers, peers_by_ip, sip_peer::prefs, remove_uri_parameters(), sip_pvt::rtp, sip_peer::secret, sip_cancel_destroy(), SIP_NAT, SIP_PAGE2_REGISTERTRYING, SIP_PAGE2_SUBSCRIBEMWIONLY, SIP_PENDINGBYE, SIP_REGISTER, strcasestr(), temp_peer(), terminate_uri(), transmit_fake_auth_response(), transmit_response(), transmit_response_with_date(), TRUE, unref_peer(), update_peer(), and XMIT_UNRELIABLE.

12142 {
12143    enum check_auth_result res = AUTH_NOT_FOUND;
12144    struct sip_peer *peer;
12145    char tmp[256];
12146    char *name, *c;
12147    char *domain;
12148 
12149    terminate_uri(uri);  /* warning, overwrite the string */
12150 
12151    ast_copy_string(tmp, get_header(req, "To"), sizeof(tmp));
12152    if (pedanticsipchecking)
12153       ast_uri_decode(tmp);
12154 
12155    c = get_in_brackets(tmp);
12156    c = remove_uri_parameters(c);
12157 
12158    if (!strncasecmp(c, "sip:", 4)) {
12159       name = c + 4;
12160    } else if (!strncasecmp(c, "sips:", 5)) {
12161       name = c + 5;
12162    } else {
12163       name = c;
12164       ast_log(LOG_NOTICE, "Invalid to address: '%s' from %s (missing sip:) trying to use anyway...\n", c, ast_inet_ntoa(sin->sin_addr));
12165    }
12166 
12167    /* XXX here too we interpret a missing @domain as a name-only
12168     * URI, whereas the RFC says this is a domain-only uri.
12169     */
12170    /* Strip off the domain name */
12171    if ((c = strchr(name, '@'))) {
12172       *c++ = '\0';
12173       domain = c;
12174       if ((c = strchr(domain, ':')))   /* Remove :port */
12175          *c = '\0';
12176       if (!AST_LIST_EMPTY(&domain_list)) {
12177          if (!check_sip_domain(domain, NULL, 0)) {
12178             transmit_response(p, "404 Not found (unknown domain)", &p->initreq);
12179             return AUTH_UNKNOWN_DOMAIN;
12180          }
12181       }
12182    }
12183    c = strchr(name, ';');  /* Remove any Username parameters */
12184    if (c)
12185       *c = '\0';
12186 
12187    ast_string_field_set(p, exten, name);
12188    build_contact(p);
12189    if (req->ignore) {
12190       /* Expires is a special case, where we only want to load the peer if this isn't a deregistration attempt */
12191       const char *expires = get_header(req, "Expires");
12192       int expire = atoi(expires);
12193 
12194       if (ast_strlen_zero(expires)) { /* No expires header; look in Contact */
12195          if ((expires = strcasestr(get_header(req, "Contact"), ";expires="))) {
12196             expire = atoi(expires + 9);
12197          }
12198       }
12199       if (!ast_strlen_zero(expires) && expire == 0) {
12200          transmit_response_with_date(p, "200 OK", req);
12201          return 0;
12202       }
12203    }
12204    peer = find_peer(name, NULL, TRUE, FINDPEERS, FALSE, 0);
12205    if (!(peer && ast_apply_ha(peer->ha, sin))) {
12206       /* Peer fails ACL check */
12207       if (peer) {
12208          unref_peer(peer, "register_verify: unref_peer: from find_peer operation");
12209          peer = NULL;
12210          res = AUTH_ACL_FAILED;
12211       } else
12212          res = AUTH_NOT_FOUND;
12213    }
12214 
12215    if (peer) {
12216       /* Set Frame packetization */
12217       if (p->rtp) {
12218          ast_rtp_codec_setpref(p->rtp, &peer->prefs);
12219          p->autoframing = peer->autoframing;
12220       }
12221       if (!peer->host_dynamic) {
12222          ast_log(LOG_ERROR, "Peer '%s' is trying to register, but not configured as host=dynamic\n", peer->name);
12223          res = AUTH_PEER_NOT_DYNAMIC;
12224       } else {
12225          ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_NAT);
12226          if (ast_test_flag(&p->flags[1], SIP_PAGE2_REGISTERTRYING))
12227             transmit_response(p, "100 Trying", req);
12228          if (!(res = check_auth(p, req, peer->name, peer->secret, peer->md5secret, SIP_REGISTER, uri, XMIT_UNRELIABLE, req->ignore))) {
12229             if (sip_cancel_destroy(p))
12230                ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
12231 
12232             if (check_request_transport(peer, req)) {
12233                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
12234                transmit_response_with_date(p, "403 Forbidden", req);
12235                res = AUTH_BAD_TRANSPORT;
12236             } else {
12237 
12238                /* We have a successful registration attempt with proper authentication,
12239                   now, update the peer */
12240                switch (parse_register_contact(p, peer, req)) {
12241                case PARSE_REGISTER_DENIED:
12242                   transmit_response_with_date(p, "603 Denied", req);
12243                   peer->lastmsgssent = -1;
12244                   res = 0;
12245                   break;
12246                case PARSE_REGISTER_FAILED:
12247                   ast_log(LOG_WARNING, "Failed to parse contact info\n");
12248                   transmit_response_with_date(p, "400 Bad Request", req);
12249                   peer->lastmsgssent = -1;
12250                   res = 0;
12251                   break;
12252                case PARSE_REGISTER_QUERY:
12253                   ast_string_field_set(p, fullcontact, peer->fullcontact);
12254                   transmit_response_with_date(p, "200 OK", req);
12255                   peer->lastmsgssent = -1;
12256                   res = 0;
12257                   break;
12258                case PARSE_REGISTER_UPDATE:
12259                   ast_string_field_set(p, fullcontact, peer->fullcontact);
12260                   update_peer(peer, p->expiry);
12261                   /* Say OK and ask subsystem to retransmit msg counter */
12262                   transmit_response_with_date(p, "200 OK", req);
12263                   if (!ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY))
12264                      peer->lastmsgssent = -1;
12265                   res = 0;
12266                   break;
12267                }
12268             }
12269 
12270          } 
12271       }
12272    }
12273    if (!peer && autocreatepeer) {
12274       /* Create peer if we have autocreate mode enabled */
12275       peer = temp_peer(name);
12276       if (peer) {
12277          ao2_t_link(peers, peer, "link peer into peer table");
12278          if (peer->addr.sin_addr.s_addr) {
12279             ao2_t_link(peers_by_ip, peer, "link peer into peers-by-ip table");
12280          }
12281          
12282          if (sip_cancel_destroy(p))
12283             ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
12284          switch (parse_register_contact(p, peer, req)) {
12285          case PARSE_REGISTER_DENIED:
12286             transmit_response_with_date(p, "403 Forbidden (ACL)", req);
12287             peer->lastmsgssent = -1;
12288             res = 0;
12289             break;
12290          case PARSE_REGISTER_FAILED:
12291             ast_log(LOG_WARNING, "Failed to parse contact info\n");
12292             transmit_response_with_date(p, "400 Bad Request", req);
12293             peer->lastmsgssent = -1;
12294             res = 0;
12295             break;
12296          case PARSE_REGISTER_QUERY:
12297             ast_string_field_set(p, fullcontact, peer->fullcontact);
12298             transmit_response_with_date(p, "200 OK", req);
12299             peer->lastmsgssent = -1;
12300             res = 0;
12301             break;
12302          case PARSE_REGISTER_UPDATE:
12303             ast_string_field_set(p, fullcontact, peer->fullcontact);
12304             /* Say OK and ask subsystem to retransmit msg counter */
12305             transmit_response_with_date(p, "200 OK", req);
12306             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Registered\r\nAddress: %s\r\nPort: %d\r\n", peer->name, ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
12307             peer->lastmsgssent = -1;
12308             res = 0;
12309             break;
12310          }
12311       }
12312    }
12313    if (!peer && global_alwaysauthreject) {
12314       /* If we found a peer, we transmit a 100 Trying.  Therefore, if we're
12315        * trying to avoid leaking information, we MUST also transmit the same
12316        * response when we DON'T find a peer. */
12317       transmit_response(p, "100 Trying", req);
12318       /* Insert a fake delay between the 100 and the subsequent failure. */
12319       sched_yield();
12320    }
12321    if (!res) {
12322       ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
12323    }
12324    if (res < 0) {
12325       switch (res) {
12326       case AUTH_SECRET_FAILED:
12327          /* Wrong password in authentication. Go away, don't try again until you fixed it */
12328          transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
12329          if (global_authfailureevents)
12330             manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Rejected\r\nCause: AUTH_SECRET_FAILED\r\nAddress: %s\r\nPort: %d\r\n", 
12331                name, ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
12332          break;
12333       case AUTH_USERNAME_MISMATCH:
12334          /* Username and digest username does not match.
12335             Asterisk uses the From: username for authentication. We need the
12336             devices to use the same authentication user name until we support
12337             proper authentication by digest auth name */
12338       case AUTH_NOT_FOUND:
12339       case AUTH_PEER_NOT_DYNAMIC:
12340       case AUTH_ACL_FAILED:
12341          if (global_alwaysauthreject) {
12342             transmit_fake_auth_response(p, SIP_REGISTER, &p->initreq, XMIT_UNRELIABLE);
12343          } else {
12344             /* URI not found */
12345             if (res == AUTH_PEER_NOT_DYNAMIC) {
12346                transmit_response(p, "403 Forbidden", &p->initreq);
12347                if (global_authfailureevents) {
12348                   manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
12349                      "ChannelType: SIP\r\n"
12350                      "Peer: SIP/%s\r\n"
12351                      "PeerStatus: Rejected\r\n"
12352                      "Cause: AUTH_PEER_NOT_DYNAMIC\r\n"
12353                      "Address: %s\r\n"
12354                      "Port: %d\r\n",
12355                      name, ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
12356                }
12357             } else {
12358                transmit_response(p, "404 Not found", &p->initreq);
12359                if (global_authfailureevents) {
12360                   manager_event(EVENT_FLAG_SYSTEM, "PeerStatus",
12361                      "ChannelType: SIP\r\n"
12362                      "Peer: SIP/%s\r\n"
12363                      "PeerStatus: Rejected\r\n"
12364                      "Cause: %s\r\n"
12365                      "Address: %s\r\n"
12366                      "Port: %d\r\n",
12367                      name,
12368                      (res == AUTH_USERNAME_MISMATCH) ? "AUTH_USERNAME_MISMATCH" : "URI_NOT_FOUND",
12369                      ast_inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
12370                }
12371             }
12372          }
12373          break;
12374       case AUTH_BAD_TRANSPORT:
12375       default:
12376          break;
12377       }
12378    }
12379    if (peer)
12380       unref_peer(peer, "register_verify: unref_peer: tossing stack peer pointer at end of func");
12381 
12382    return res;
12383 }

static struct sip_registry* registry_addref ( struct sip_registry reg,
char *  tag 
) [static]

Add object reference to SIP registry.

Definition at line 2866 of file chan_sip.c.

References ast_debug, ASTOBJ_REF, sip_registry::hostname, and sip_registry::refcount.

Referenced by handle_response_register(), sip_send_all_registers(), and transmit_register().

02867 {
02868    ast_debug(3, "SIP Registry %s: refcount now %d\n", reg->hostname, reg->refcount + 1);
02869    return ASTOBJ_REF(reg); /* Add pointer to registry in packet */
02870 }

static void * registry_unref ( struct sip_registry reg,
char *  tag 
) [static]

Definition at line 2858 of file chan_sip.c.

References ast_debug, ASTOBJ_UNREF, sip_registry::hostname, sip_registry::refcount, and sip_registry_destroy().

Referenced by __sip_destroy(), dialog_unlink_all(), handle_response_register(), reload_config(), sip_reg_timeout(), sip_register(), sip_registry_destroy(), sip_reregister(), sip_send_all_registers(), and transmit_register().

02859 {
02860    ast_debug(3, "SIP Registry %s: refcount now %d\n", reg->hostname, reg->refcount - 1);
02861    ASTOBJ_UNREF(reg, sip_registry_destroy);
02862    return NULL;
02863 }

static const char * regstate2str ( enum sipregistrystate  regstate  )  const [static]

Convert registration state status to string.

Definition at line 10666 of file chan_sip.c.

References map_x_s(), and regstatestrings.

10667 {
10668    return map_x_s(regstatestrings, regstate, "Unknown");
10669 }

static int reload ( void   )  [static]

Part of Asterisk module interface.

Definition at line 24647 of file chan_sip.c.

References sip_reload().

24648 {
24649    if (sip_reload(0, 0, NULL))
24650       return 0;
24651    return 1;
24652 }

static int reload_config ( enum channelreloadreason  reason  )  [static]

Re-read SIP.conf config file.

Note:
This function reloads all config data, except for active peers (with registrations). They will only change configuration data at restart, not at reload. SIP debug and recordhistory state will not change

< Type of address: IPv4

< Don't force proxy usage, use route: headers

< Keep track of hold status for a peer

< Match auth username if available instead of From: Default off.

< Default DTMF setting: RFC2833

< NAT support if requested by device with rport

< Allow re-invites

Definition at line 23313 of file chan_sip.c.

References ast_clear_flag, ast_config_load, ast_debug, ast_free_ha(), ast_log(), AST_MAX_CONTEXT, AST_SCHED_DEL_UNREF, ast_test_flag, ast_unload_realtime(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, authl, CHANNEL_MODULE_LOAD, clear_realm_authentication(), clear_sip_domains(), CONFIG_FLAG_FILEUNCHANGED, config_flags, CONFIG_STATUS_FILEUNCHANGED, context, default_tls_cfg, dialog_unlink_all(), dialog_unref(), dummy(), ast_tls_config::enabled, FALSE, global_contact_ha, global_flags, ast_tcptls_session_args::local_address, LOG_NOTICE, registry_unref(), regl, sched, SIP_PAGE2_RTCACHEFRIENDS, sip_tcp_desc, sip_tls_desc, STANDARD_SIP_PORT, STANDARD_TLS_PORT, and TRUE.

23314 {
23315    struct ast_config *cfg, *ucfg;
23316    struct ast_variable *v;
23317    struct sip_peer *peer;
23318    char *cat, *stringp, *context, *oldregcontext;
23319    char newcontexts[AST_MAX_CONTEXT], oldcontexts[AST_MAX_CONTEXT];
23320    struct ast_flags dummy[2];
23321    struct ast_flags config_flags = { reason == CHANNEL_MODULE_LOAD ? 0 : ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) ? 0 : CONFIG_FLAG_FILEUNCHANGED };
23322    int auto_sip_domains = FALSE;
23323    struct sockaddr_in old_bindaddr = bindaddr;
23324    int registry_count = 0, peer_count = 0;
23325    time_t run_start, run_end;
23326    
23327    run_start = time(0);
23328    ast_unload_realtime("sipregs");     
23329    ast_unload_realtime("sippeers");
23330    cfg = ast_config_load(config, config_flags);
23331 
23332    /* We *must* have a config file otherwise stop immediately */
23333    if (!cfg) {
23334       ast_log(LOG_NOTICE, "Unable to load config %s\n", config);
23335       return -1;
23336    } else if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
23337       ucfg = ast_config_load("users.conf", config_flags);
23338       if (ucfg == CONFIG_STATUS_FILEUNCHANGED)
23339          return 1;
23340       /* Must reread both files, because one changed */
23341       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
23342       cfg = ast_config_load(config, config_flags);
23343    } else {
23344       ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
23345       ucfg = ast_config_load("users.conf", config_flags);
23346    }
23347 
23348    /* Initialize tcp sockets */
23349    memset(&sip_tcp_desc.local_address, 0, sizeof(sip_tcp_desc.local_address));
23350    memset(&sip_tls_desc.local_address, 0, sizeof(sip_tls_desc.local_address));
23351 
23352    ast_free_ha(global_contact_ha);
23353    global_contact_ha = NULL;
23354 
23355    default_tls_cfg.enabled = FALSE;    /* Default: Disable TLS */
23356 
23357    sip_tcp_desc.local_address.sin_port = htons(STANDARD_SIP_PORT);
23358    sip_tls_desc.local_address.sin_port = htons(STANDARD_TLS_PORT);
23359 
23360    if (reason != CHANNEL_MODULE_LOAD) {
23361       ast_debug(4, "--------------- SIP reload started\n");
23362 
23363       clear_realm_authentication(authl);
23364       clear_sip_domains();
23365       authl = NULL;
23366 
23367       /* First, destroy all outstanding registry calls */
23368       /* This is needed, since otherwise active registry entries will not be destroyed */
23369       ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {  /* regl is locked */
23370 
23371             ASTOBJ_RDLOCK(iterator); /* now regl is locked, and the object is also locked */
23372             if (iterator->call) {
23373                ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", iterator->username, iterator->hostname);
23374                /* This will also remove references to the registry */
23375                dialog_unlink_all(iterator->call, TRUE, TRUE);
23376                iterator->call = dialog_unref(iterator->call, "remove iterator->call from registry traversal");
23377             }
23378             if (iterator->expire > -1) {
23379                AST_SCHED_DEL_UNREF(sched, iterator->expire, registry_unref(iterator, "reg ptr unref from reload config"));
23380             }
23381             if (iterator->timeout > -1) {
23382                AST_SCHED_DEL_UNREF(sched, iterator->timeout, registry_unref(iterator, "reg ptr unref from reload config"));
23383             }
23384             ASTOBJ_UNLOCK(iterator);
23385             
23386       } while(0));
23387 
23388       /* Then, actually destroy users and registry */
23389       ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
23390       ast_debug(4, "--------------- Done destroying registry list\n");
23391       ao2_t_callback(peers, OBJ_NODATA, peer_markall_func, 0, "callback to mark all peers");
23392    }
23393    
23394    /* Reset certificate handling for TLS sessions */
23395    if (reason != CHANNEL_MODULE_LOAD) {
23396       ast_free(default_tls_cfg.certfile);
23397       ast_free(default_tls_cfg.cipher);
23398       ast_free(default_tls_cfg.cafile);
23399       ast_free(default_tls_cfg.capath);
23400    }
23401    default_tls_cfg.certfile = ast_strdup(AST_CERTFILE); /*XXX Not sure if this is useful */
23402    default_tls_cfg.cipher = ast_strdup("");
23403    default_tls_cfg.cafile = ast_strdup("");
23404    default_tls_cfg.capath = ast_strdup("");
23405    
23406    /* Initialize copy of current global_regcontext for later use in removing stale contexts */
23407    ast_copy_string(oldcontexts, global_regcontext, sizeof(oldcontexts));
23408    oldregcontext = oldcontexts;
23409 
23410    /* Clear all flags before setting default values */
23411    /* Preserve debugging settings for console */
23412    sipdebug &= sip_debug_console;
23413    ast_clear_flag(&global_flags[0], AST_FLAGS_ALL);
23414    ast_clear_flag(&global_flags[1], AST_FLAGS_ALL);
23415 
23416    /* Reset IP addresses  */
23417    memset(&bindaddr, 0, sizeof(bindaddr));
23418    memset(&stunaddr, 0, sizeof(stunaddr));
23419    memset(&internip, 0, sizeof(internip));
23420 
23421    /* Free memory for local network address mask */
23422    ast_free_ha(localaddr);
23423    memset(&localaddr, 0, sizeof(localaddr));
23424    memset(&externip, 0, sizeof(externip));
23425    memset(&default_prefs, 0 , sizeof(default_prefs));
23426    memset(&global_outboundproxy, 0, sizeof(struct sip_proxy));
23427    global_outboundproxy.ip.sin_port = htons(STANDARD_SIP_PORT);
23428    global_outboundproxy.ip.sin_family = AF_INET;   /*!< Type of address: IPv4 */
23429    global_outboundproxy.force = FALSE;    /*!< Don't force proxy usage, use route: headers */
23430    ourport_tcp = STANDARD_SIP_PORT;
23431    ourport_tls = STANDARD_TLS_PORT;
23432    bindaddr.sin_port = htons(STANDARD_SIP_PORT);
23433    global_srvlookup = DEFAULT_SRVLOOKUP;
23434    global_tos_sip = DEFAULT_TOS_SIP;
23435    global_tos_audio = DEFAULT_TOS_AUDIO;
23436    global_tos_video = DEFAULT_TOS_VIDEO;
23437    global_tos_text = DEFAULT_TOS_TEXT;
23438    global_cos_sip = DEFAULT_COS_SIP;
23439    global_cos_audio = DEFAULT_COS_AUDIO;
23440    global_cos_video = DEFAULT_COS_VIDEO;
23441    global_cos_text = DEFAULT_COS_TEXT;
23442 
23443    externhost[0] = '\0';         /* External host name (for behind NAT DynDNS support) */
23444    externexpire = 0;       /* Expiration for DNS re-issuing */
23445    externrefresh = 10;
23446 
23447    /* Reset channel settings to default before re-configuring */
23448    allow_external_domains = DEFAULT_ALLOW_EXT_DOM;          /* Allow external invites */
23449    global_regcontext[0] = '\0';
23450    global_regextenonqualify = DEFAULT_REGEXTENONQUALIFY;
23451    global_notifyringing = DEFAULT_NOTIFYRINGING;
23452    global_notifyhold = FALSE;    /*!< Keep track of hold status for a peer */
23453    global_directrtpsetup = FALSE;      /* Experimental feature, disabled by default */
23454    global_alwaysauthreject = 0;
23455    global_allowsubscribe = FALSE;
23456    snprintf(global_useragent, sizeof(global_useragent), "%s %s", DEFAULT_USERAGENT, ast_get_version());
23457    snprintf(global_sdpsession, sizeof(global_sdpsession), "%s %s", DEFAULT_SDPSESSION, ast_get_version());
23458    snprintf(global_sdpowner, sizeof(global_sdpowner), "%s", DEFAULT_SDPOWNER);
23459    global_prematuremediafilter = FALSE;
23460    ast_copy_string(default_notifymime, DEFAULT_NOTIFYMIME, sizeof(default_notifymime));
23461    ast_copy_string(global_realm, S_OR(ast_config_AST_SYSTEM_NAME, DEFAULT_REALM), sizeof(global_realm));
23462    ast_copy_string(default_callerid, DEFAULT_CALLERID, sizeof(default_callerid));
23463    compactheaders = DEFAULT_COMPACTHEADERS;
23464    global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
23465    global_regattempts_max = 0;
23466    pedanticsipchecking = DEFAULT_PEDANTIC;
23467    autocreatepeer = DEFAULT_AUTOCREATEPEER;
23468    global_autoframing = 0;
23469    global_allowguest = DEFAULT_ALLOWGUEST;
23470    global_callcounter = DEFAULT_CALLCOUNTER;
23471    global_match_auth_username = FALSE;    /*!< Match auth username if available instead of From: Default off. */
23472    global_rtptimeout = 0;
23473    global_rtpholdtimeout = 0;
23474    global_rtpkeepalive = 0;
23475    global_allowtransfer = TRANSFER_OPENFORALL;  /* Merrily accept all transfers by default */
23476    global_rtautoclear = 120;
23477    ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE);   /* Default for all devices: TRUE */
23478    ast_set_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP);     /* Default for all devices: TRUE */
23479    sip_cfg.peer_rtupdate = TRUE;
23480    global_dynamic_exclude_static = 0;  /* Exclude static peers */
23481 
23482    /* Session-Timers */
23483    global_st_mode = SESSION_TIMER_MODE_ACCEPT;    
23484    global_st_refresher = SESSION_TIMER_REFRESHER_UAS;
23485    global_min_se  = DEFAULT_MIN_SE;
23486    global_max_se  = DEFAULT_MAX_SE;
23487 
23488    /* Initialize some reasonable defaults at SIP reload (used both for channel and as default for devices */
23489    ast_copy_string(default_context, DEFAULT_CONTEXT, sizeof(default_context));
23490    default_subscribecontext[0] = '\0';
23491    default_language[0] = '\0';
23492    default_fromdomain[0] = '\0';
23493    default_qualify = DEFAULT_QUALIFY;
23494    default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
23495    ast_copy_string(default_mohinterpret, DEFAULT_MOHINTERPRET, sizeof(default_mohinterpret));
23496    ast_copy_string(default_mohsuggest, DEFAULT_MOHSUGGEST, sizeof(default_mohsuggest));
23497    ast_copy_string(default_vmexten, DEFAULT_VMEXTEN, sizeof(default_vmexten));
23498    ast_set_flag(&global_flags[0], SIP_DTMF_RFC2833);        /*!< Default DTMF setting: RFC2833 */
23499    ast_set_flag(&global_flags[0], SIP_NAT_RFC3581);         /*!< NAT support if requested by device with rport */
23500    ast_set_flag(&global_flags[0], SIP_CAN_REINVITE);        /*!< Allow re-invites */
23501 
23502    /* Debugging settings, always default to off */
23503    dumphistory = FALSE;
23504    recordhistory = FALSE;
23505    sipdebug &= ~sip_debug_config;
23506 
23507    /* Misc settings for the channel */
23508    global_relaxdtmf = FALSE;
23509    global_callevents = FALSE;
23510    global_authfailureevents = FALSE;
23511    global_t1 = SIP_TIMER_T1;
23512    global_timer_b = 64 * SIP_TIMER_T1;
23513    global_t1min = DEFAULT_T1MIN;
23514    global_qualifyfreq = DEFAULT_QUALIFYFREQ;
23515    global_t38_maxdatagram = -1;
23516    global_shrinkcallerid = 1;
23517 
23518    global_matchexterniplocally = FALSE;
23519 
23520    /* Copy the default jb config over global_jbconf */
23521    memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
23522 
23523    ast_clear_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT | SIP_PAGE2_VIDEOSUPPORT_ALWAYS);
23524    ast_clear_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT);
23525    ast_clear_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION);
23526    ast_clear_flag(&global_flags[1], SIP_PAGE2_FAX_DETECT);
23527 
23528 
23529    /* Read the [general] config section of sip.conf (or from realtime config) */
23530    for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
23531       if (handle_common_options(&global_flags[0], &dummy[0], v))
23532          continue;
23533       if (handle_t38_options(&global_flags[0], &dummy[0], v, &global_t38_maxdatagram)) {
23534          continue;
23535       }
23536       /* handle jb conf */
23537       if (!ast_jb_read_conf(&global_jbconf, v->name, v->value))
23538          continue;
23539 
23540       if (!strcasecmp(v->name, "context")) {
23541          ast_copy_string(default_context, v->value, sizeof(default_context));
23542       } else if (!strcasecmp(v->name, "subscribecontext")) {
23543          ast_copy_string(default_subscribecontext, v->value, sizeof(default_subscribecontext));
23544       } else if (!strcasecmp(v->name, "callcounter")) {
23545          global_callcounter = ast_true(v->value) ? 1 : 0;
23546       } else if (!strcasecmp(v->name, "allowguest")) {
23547          global_allowguest = ast_true(v->value) ? 1 : 0;
23548       } else if (!strcasecmp(v->name, "realm")) {
23549          ast_copy_string(global_realm, v->value, sizeof(global_realm));
23550       } else if (!strcasecmp(v->name, "useragent")) {
23551          ast_copy_string(global_useragent, v->value, sizeof(global_useragent));
23552          ast_debug(1, "Setting SIP channel User-Agent Name to %s\n", global_useragent);
23553       } else if (!strcasecmp(v->name, "sdpsession")) {
23554          ast_copy_string(global_sdpsession, v->value, sizeof(global_sdpsession));
23555       } else if (!strcasecmp(v->name, "sdpowner")) {
23556          /* Field cannot contain spaces */
23557          if (!strstr(v->value, " "))
23558             ast_copy_string(global_sdpowner, v->value, sizeof(global_sdpowner));
23559          else
23560             ast_log(LOG_WARNING, "'%s' must not contain spaces at line %d.  Using default.\n", v->value, v->lineno);
23561       } else if (!strcasecmp(v->name, "allowtransfer")) {
23562          global_allowtransfer = ast_true(v->value) ? TRANSFER_OPENFORALL : TRANSFER_CLOSED;
23563       } else if (!strcasecmp(v->name, "rtcachefriends")) {
23564          ast_set2_flag(&global_flags[1], ast_true(v->value), SIP_PAGE2_RTCACHEFRIENDS);   
23565       } else if (!strcasecmp(v->name, "rtsavesysname")) {
23566          sip_cfg.rtsave_sysname = ast_true(v->value);
23567       } else if (!strcasecmp(v->name, "rtupdate")) {
23568          sip_cfg.peer_rtupdate = ast_true(v->value);
23569       } else if (!strcasecmp(v->name, "ignoreregexpire")) {
23570          sip_cfg.ignore_regexpire = ast_true(v->value);
23571       } else if (!strcasecmp(v->name, "timert1")) {
23572          /* Defaults to 500ms, but RFC 3261 states that it is recommended
23573           * for the value to be set higher, though a lower value is only
23574           * allowed on private networks unconnected to the Internet. */
23575          global_t1 = atoi(v->value);
23576          /* Note that timer B is dependent on the value of T1 */
23577          global_timer_b = global_t1 * 64;
23578       } else if (!strcasecmp(v->name, "t1min")) {
23579          global_t1min = atoi(v->value);
23580       } else if (!strcasecmp(v->name, "tcpenable")) {
23581          sip_tcp_desc.local_address.sin_family = ast_false(v->value) ? 0 : AF_INET;
23582          ast_debug(2, "Enabling TCP socket for listening\n");
23583       } else if (!strcasecmp(v->name, "tcpbindaddr")) {
23584          int family = sip_tcp_desc.local_address.sin_family;
23585          if (ast_parse_arg(v->value, PARSE_INADDR, &sip_tcp_desc.local_address))
23586             ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n", v->name, v->value, v->lineno, config);
23587          sip_tcp_desc.local_address.sin_family = family;
23588          ast_debug(2, "Setting TCP socket address to %s\n", v->value);
23589       } else if (!strcasecmp(v->name, "tlsenable")) {
23590          default_tls_cfg.enabled = ast_true(v->value) ? TRUE : FALSE;
23591          sip_tls_desc.local_address.sin_family = AF_INET;
23592       } else if (!strcasecmp(v->name, "tlscertfile")) {
23593          ast_free(default_tls_cfg.certfile);
23594          default_tls_cfg.certfile = ast_strdup(v->value);
23595       } else if (!strcasecmp(v->name, "tlscipher")) {
23596          ast_free(default_tls_cfg.cipher);
23597          default_tls_cfg.cipher = ast_strdup(v->value);
23598       } else if (!strcasecmp(v->name, "tlscafile")) {
23599          ast_free(default_tls_cfg.cafile);
23600          default_tls_cfg.cafile = ast_strdup(v->value);
23601       } else if (!strcasecmp(v->name, "tlscapath")) {
23602          ast_free(default_tls_cfg.capath);
23603          default_tls_cfg.capath = ast_strdup(v->value);
23604       } else if (!strcasecmp(v->name, "tlsverifyclient")) {
23605          ast_set2_flag(&default_tls_cfg.flags, ast_true(v->value), AST_SSL_VERIFY_CLIENT);   
23606       } else if (!strcasecmp(v->name, "tlsdontverifyserver")) {
23607          ast_set2_flag(&default_tls_cfg.flags, ast_true(v->value), AST_SSL_DONT_VERIFY_SERVER); 
23608       } else if (!strcasecmp(v->name, "tlsbindaddr")) {
23609          if (ast_parse_arg(v->value, PARSE_INADDR, &sip_tls_desc.local_address))
23610             ast_log(LOG_WARNING, "Invalid %s '%s' at line %d of %s\n", v->name, v->value, v->lineno, config);
23611       } else if (!strcasecmp(v->name, "dynamic_exclude_static") || !strcasecmp(v->name, "dynamic_excludes_static")) {
23612          global_dynamic_exclude_static = ast_true(v->value);
23613       } else if (!strcasecmp(v->name, "contactpermit") || !strcasecmp(v->name, "contactdeny")) {
23614          int ha_error = 0;
23615          global_contact_ha = ast_append_ha(v->name + 7, v->value, global_contact_ha, &ha_error);
23616          if (ha_error) {
23617             ast_log(LOG_ERROR, "Bad ACL entry in configuration line %d : %s\n", v->lineno, v->value);
23618          }
23619       } else if (!strcasecmp(v->name, "rtautoclear")) {
23620          int i = atoi(v->value);
23621          if (i > 0)
23622             global_rtautoclear = i;
23623          else
23624             i = 0;
23625          ast_set2_flag(&global_flags[1], i || ast_true(v->value), SIP_PAGE2_RTAUTOCLEAR);
23626       } else if (!strcasecmp(v->name, "usereqphone")) {
23627          ast_set2_flag(&global_flags[0], ast_true(v->value), SIP_USEREQPHONE);   
23628       } else if (!strcasecmp(v->name, "prematuremedia")) {
23629          global_prematuremediafilter = ast_true(v->value);
23630       } else if (!strcasecmp(v->name, "relaxdtmf")) {
23631          global_relaxdtmf = ast_true(v->value);
23632       } else if (!strcasecmp(v->name, "vmexten")) {
23633          ast_copy_string(default_vmexten, v->value, sizeof(default_vmexten));
23634       } else if (!strcasecmp(v->name, "rtptimeout")) {
23635          if ((sscanf(v->value, "%30d", &global_rtptimeout) != 1) || (global_rtptimeout < 0)) {
23636             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
23637             global_rtptimeout = 0;
23638          }
23639       } else if (!strcasecmp(v->name, "rtpholdtimeout")) {
23640          if ((sscanf(v->value, "%30d", &global_rtpholdtimeout) != 1) || (global_rtpholdtimeout < 0)) {
23641             ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
23642             global_rtpholdtimeout = 0;
23643          }
23644       } else if (!strcasecmp(v->name, "rtpkeepalive")) {
23645          if ((sscanf(v->value, "%30d", &global_rtpkeepalive) != 1) || (global_rtpkeepalive < 0)) {
23646             ast_log(LOG_WARNING, "'%s' is not a valid RTP keepalive time at line %d.  Using default.\n", v->value, v->lineno);
23647             global_rtpkeepalive = 0;
23648          }
23649       } else if (!strcasecmp(v->name, "compactheaders")) {
23650          compactheaders = ast_true(v->value);
23651       } else if (!strcasecmp(v->name, "notifymimetype")) {
23652          ast_copy_string(default_notifymime, v->value, sizeof(default_notifymime));
23653       } else if (!strcasecmp(v->name, "directrtpsetup")) {
23654          global_directrtpsetup = ast_true(v->value);
23655       } else if (!strcasecmp(v->name, "notifyringing")) {
23656          global_notifyringing = ast_true(v->value);
23657       } else if (!strcasecmp(v->name, "notifyhold")) {
23658          global_notifyhold = ast_true(v->value);
23659       } else if (!strcasecmp(v->name, "alwaysauthreject")) {
23660          global_alwaysauthreject = ast_true(v->value);
23661       } else if (!strcasecmp(v->name, "mohinterpret")) {
23662          ast_copy_string(default_mohinterpret, v->value, sizeof(default_mohinterpret));
23663       } else if (!strcasecmp(v->name, "mohsuggest")) {
23664          ast_copy_string(default_mohsuggest, v->value, sizeof(default_mohsuggest));
23665       } else if (!strcasecmp(v->name, "language")) {
23666          ast_copy_string(default_language, v->value, sizeof(default_language));
23667       } else if (!strcasecmp(v->name, "regcontext")) {
23668          ast_copy_string(newcontexts, v->value, sizeof(newcontexts));
23669          stringp = newcontexts;
23670          /* Let's remove any contexts that are no longer defined in regcontext */
23671          cleanup_stale_contexts(stringp, oldregcontext);
23672          /* Create contexts if they don't exist already */
23673          while ((context = strsep(&stringp, "&"))) {
23674             ast_copy_string(used_context, context, sizeof(used_context));
23675             ast_context_find_or_create(NULL, NULL, context, "SIP");
23676          }
23677          ast_copy_string(global_regcontext, v->value, sizeof(global_regcontext));
23678       } else if (!strcasecmp(v->name, "regextenonqualify")) {
23679          global_regextenonqualify = ast_true(v->value);
23680       } else if (!strcasecmp(v->name, "callerid")) {
23681          ast_copy_string(default_callerid, v->value, sizeof(default_callerid));
23682       } else if (!strcasecmp(v->name, "fromdomain")) {
23683          ast_copy_string(default_fromdomain, v->value, sizeof(default_fromdomain));
23684       } else if (!strcasecmp(v->name, "outboundproxy")) {
23685          int portnum;
23686          char *tok, *proxyname;
23687 
23688          if (ast_strlen_zero(v->value)) {
23689             ast_log(LOG_WARNING, "no value given for outbound proxy on line %d of sip.conf.", v->lineno);
23690             continue;
23691          }
23692 
23693          tok = ast_skip_blanks(strtok(ast_strdupa(v->value), ","));
23694 
23695          sip_parse_host(tok, v->lineno, &proxyname, &portnum, &global_outboundproxy.transport);
23696 
23697          global_outboundproxy.ip.sin_port = htons(portnum);
23698    
23699          if ((tok = strtok(NULL, ","))) {
23700             global_outboundproxy.force = !strncasecmp(ast_skip_blanks(tok), "force", 5);
23701          } else {
23702             global_outboundproxy.force = FALSE;
23703          }
23704 
23705          if (ast_strlen_zero(proxyname)) {
23706             ast_log(LOG_WARNING, "you must specify a name for the outboundproxy on line %d of sip.conf.", v->lineno);
23707             global_outboundproxy.name[0] = '\0';
23708             continue;
23709          }
23710 
23711          ast_copy_string(global_outboundproxy.name, proxyname, sizeof(global_outboundproxy.name));
23712 
23713          proxy_update(&global_outboundproxy);
23714       } else if (!strcasecmp(v->name, "autocreatepeer")) {
23715          autocreatepeer = ast_true(v->value);
23716       } else if (!strcasecmp(v->name, "match_auth_username")) {
23717          global_match_auth_username = ast_true(v->value);
23718       } else if (!strcasecmp(v->name, "srvlookup")) {
23719          global_srvlookup = ast_true(v->value);
23720       } else if (!strcasecmp(v->name, "pedantic")) {
23721          pedanticsipchecking = ast_true(v->value);
23722       } else if (!strcasecmp(v->name, "maxexpirey") || !strcasecmp(v->name, "maxexpiry")) {
23723          max_expiry = atoi(v->value);
23724          if (max_expiry < 1)
23725             max_expiry = DEFAULT_MAX_EXPIRY;
23726       } else if (!strcasecmp(v->name, "minexpirey") || !strcasecmp(v->name, "minexpiry")) {
23727          min_expiry = atoi(v->value);
23728          if (min_expiry < 1)
23729             min_expiry = DEFAULT_MIN_EXPIRY;
23730       } else if (!strcasecmp(v->name, "defaultexpiry") || !strcasecmp(v->name, "defaultexpirey")) {
23731          default_expiry = atoi(v->value);
23732          if (default_expiry < 1)
23733             default_expiry = DEFAULT_DEFAULT_EXPIRY;
23734       } else if (!strcasecmp(v->name, "sipdebug")) {
23735          if (ast_true(v->value))
23736             sipdebug |= sip_debug_config;
23737       } else if (!strcasecmp(v->name, "dumphistory")) {
23738          dumphistory = ast_true(v->value);
23739       } else if (!strcasecmp(v->name, "recordhistory")) {
23740          recordhistory = ast_true(v->value);
23741       } else if (!strcasecmp(v->name, "registertimeout")) {
23742          global_reg_timeout = atoi(v->value);
23743          if (global_reg_timeout < 1)
23744             global_reg_timeout = DEFAULT_REGISTRATION_TIMEOUT;
23745       } else if (!strcasecmp(v->name, "registerattempts")) {
23746          global_regattempts_max = atoi(v->value);
23747       } else if (!strcasecmp(v->name, "stunaddr")) {
23748          stunaddr.sin_port = htons(3478);
23749          if (ast_parse_arg(v->value, PARSE_INADDR, &stunaddr))
23750             ast_log(LOG_WARNING, "Invalid STUN server address: %s\n", v->value);
23751          externexpire = time(NULL);
23752       } else if (!strcasecmp(v->name, "bindaddr") || !strcasecmp(v->name, "udpbindaddr")) {
23753          if (ast_parse_arg(v->value, PARSE_INADDR, &bindaddr))
23754             ast_log(LOG_WARNING, "Invalid address: %s\n", v->value);
23755       } else if (!strcasecmp(v->name, "localnet")) {
23756          struct ast_ha *na;
23757          int ha_error = 0;
23758 
23759          if (!(na = ast_append_ha("d", v->value, localaddr, &ha_error)))
23760             ast_log(LOG_WARNING, "Invalid localnet value: %s\n", v->value);
23761          else
23762             localaddr = na;
23763          if (ha_error)
23764             ast_log(LOG_ERROR, "Bad localnet configuration value line %d : %s\n", v->lineno, v->value);
23765       } else if (!strcasecmp(v->name, "externip")) {
23766          if (ast_parse_arg(v->value, PARSE_INADDR, &externip))
23767             ast_log(LOG_WARNING, "Invalid address for externip keyword: %s\n", v->value);
23768          externexpire = 0;
23769          /* If no port was specified use the value of bindport */
23770          if (!externip.sin_port)
23771             externip.sin_port = bindaddr.sin_port;
23772       } else if (!strcasecmp(v->name, "externhost")) {
23773          ast_copy_string(externhost, v->value, sizeof(externhost));
23774          if (ast_parse_arg(externhost, PARSE_INADDR, &externip))
23775             ast_log(LOG_WARNING, "Invalid address for externhost keyword: %s\n", externhost);
23776          externexpire = time(NULL);
23777          /* If no port was specified use the value of bindport */
23778          if (!externip.sin_port)
23779             externip.sin_port = bindaddr.sin_port;
23780       } else if (!strcasecmp(v->name, "externrefresh")) {
23781          if (sscanf(v->value, "%30d", &externrefresh) != 1) {
23782             ast_log(LOG_WARNING, "Invalid externrefresh value '%s', must be an integer >0 at line %d\n", v->value, v->lineno);
23783             externrefresh = 10;
23784          }
23785       } else if (!strcasecmp(v->name, "allow")) {
23786          int error =  ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, TRUE);
23787          if (error)
23788             ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
23789       } else if (!strcasecmp(v->name, "disallow")) {
23790          int error =  ast_parse_allow_disallow(&default_prefs, &global_capability, v->value, FALSE);
23791          if (error)
23792             ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
23793       } else if (!strcasecmp(v->name, "autoframing")) {
23794          global_autoframing = ast_true(v->value);
23795       } else if (!strcasecmp(v->name, "allowexternaldomains")) {
23796          allow_external_domains = ast_true(v->value);
23797       } else if (!strcasecmp(v->name, "autodomain")) {
23798          auto_sip_domains = ast_true(v->value);
23799       } else if (!strcasecmp(v->name, "domain")) {
23800          char *domain = ast_strdupa(v->value);
23801          char *cntx = strchr(domain, ',');
23802 
23803          if (cntx)
23804             *cntx++ = '\0';
23805 
23806          if (ast_strlen_zero(cntx))
23807             ast_debug(1, "No context specified at line %d for domain '%s'\n", v->lineno, domain);
23808          if (ast_strlen_zero(domain))
23809             ast_log(LOG_WARNING, "Empty domain specified at line %d\n", v->lineno);
23810          else
23811             add_sip_domain(ast_strip(domain), SIP_DOMAIN_CONFIG, cntx ? ast_strip(cntx) : "");
23812       } else if (!strcasecmp(v->name, "register")) {
23813          if (sip_register(v->value, v->lineno) == 0)
23814             registry_count++;
23815       } else if (!strcasecmp(v->name, "tos_sip")) {
23816          if (ast_str2tos(v->value, &global_tos_sip))
23817             ast_log(LOG_WARNING, "Invalid tos_sip value at line %d, refer to QoS documentation\n", v->lineno);
23818       } else if (!strcasecmp(v->name, "tos_audio")) {
23819          if (ast_str2tos(v->value, &global_tos_audio))
23820             ast_log(LOG_WARNING, "Invalid tos_audio value at line %d, refer to QoS documentation\n", v->lineno);
23821       } else if (!strcasecmp(v->name, "tos_video")) {
23822          if (ast_str2tos(v->value, &global_tos_video))
23823             ast_log(LOG_WARNING, "Invalid tos_video value at line %d, refer to QoS documentation\n", v->lineno);
23824       } else if (!strcasecmp(v->name, "tos_text")) {
23825          if (ast_str2tos(v->value, &global_tos_text))
23826             ast_log(LOG_WARNING, "Invalid tos_text value at line %d, refer to QoS documentation\n", v->lineno);
23827       } else if (!strcasecmp(v->name, "cos_sip")) {
23828          if (ast_str2cos(v->value, &global_cos_sip))
23829             ast_log(LOG_WARNING, "Invalid cos_sip value at line %d, refer to QoS documentation\n", v->lineno);
23830       } else if (!strcasecmp(v->name, "cos_audio")) {
23831          if (ast_str2cos(v->value, &global_cos_audio))
23832             ast_log(LOG_WARNING, "Invalid cos_audio value at line %d, refer to QoS documentation\n", v->lineno);
23833       } else if (!strcasecmp(v->name, "cos_video")) {
23834          if (ast_str2cos(v->value, &global_cos_video))
23835             ast_log(LOG_WARNING, "Invalid cos_video value at line %d, refer to QoS documentation\n", v->lineno);
23836       } else if (!strcasecmp(v->name, "cos_text")) {
23837          if (ast_str2cos(v->value, &global_cos_text))
23838             ast_log(LOG_WARNING, "Invalid cos_text value at line %d, refer to QoS documentation\n", v->lineno);
23839       } else if (!strcasecmp(v->name, "bindport")) {
23840          int i;
23841          if (sscanf(v->value, "%5d", &i) == 1) {
23842             bindaddr.sin_port = htons(i);
23843          } else {
23844             ast_log(LOG_WARNING, "Invalid port number '%s' at line %d of %s\n", v->value, v->lineno, config);
23845          }
23846       } else if (!strcasecmp(v->name, "hash_user")) {
23847          int i;
23848          if (sscanf(v->value, "%30d", &i) == 1 && i > 2) {
23849             hash_user_size = i;
23850          } else {
23851             ast_log(LOG_WARNING, "Invalid hash_user size '%s' at line %d of %s -- should be much larger than 2\n", v->value, v->lineno, config);
23852          }
23853       } else if (!strcasecmp(v->name, "hash_peer")) {
23854          int i;
23855          if (sscanf(v->value, "%30d", &i) == 1 && i > 2) {
23856             hash_peer_size = i;
23857          } else {
23858             ast_log(LOG_WARNING, "Invalid hash_peer size '%s' at line %d of %s -- should be much larger than 2\n", v->value, v->lineno, config);
23859          }
23860       } else if (!strcasecmp(v->name, "hash_dialog")) {
23861          int i;
23862          if (sscanf(v->value, "%30d", &i) == 1 && i > 2) {
23863             hash_dialog_size = i;
23864          } else {
23865             ast_log(LOG_WARNING, "Invalid hash_dialog size '%s' at line %d of %s -- should be much larger than 2\n", v->value, v->lineno, config);
23866          }
23867       } else if (!strcasecmp(v->name, "qualify")) {
23868          if (!strcasecmp(v->value, "no")) {
23869             default_qualify = 0;
23870          } else if (!strcasecmp(v->value, "yes")) {
23871             default_qualify = DEFAULT_MAXMS;
23872          } else if (sscanf(v->value, "%30d", &default_qualify) != 1) {
23873             ast_log(LOG_WARNING, "Qualification default should be 'yes', 'no', or a number of milliseconds at line %d of sip.conf\n", v->lineno);
23874             default_qualify = 0;
23875          }
23876       } else if (!strcasecmp(v->name, "qualifyfreq")) {
23877          int i;
23878          if (sscanf(v->value, "%30d", &i) == 1)
23879             global_qualifyfreq = i * 1000;
23880          else {
23881             ast_log(LOG_WARNING, "Invalid qualifyfreq number '%s' at line %d of %s\n", v->value, v->lineno, config);
23882             global_qualifyfreq = DEFAULT_QUALIFYFREQ;
23883          }
23884       } else if (!strcasecmp(v->name, "callevents")) {
23885          global_callevents = ast_true(v->value);
23886       } else if (!strcasecmp(v->name, "authfailureevents")) {
23887          global_authfailureevents = ast_true(v->value);
23888       } else if (!strcasecmp(v->name, "maxcallbitrate")) {
23889          default_maxcallbitrate = atoi(v->value);
23890          if (default_maxcallbitrate < 0)
23891             default_maxcallbitrate = DEFAULT_MAX_CALL_BITRATE;
23892       } else if (!strcasecmp(v->name, "matchexterniplocally")) {
23893          global_matchexterniplocally = ast_true(v->value);
23894       } else if (!strcasecmp(v->name, "session-timers")) {
23895          int i = (int) str2stmode(v->value); 
23896          if (i < 0) {
23897             ast_log(LOG_WARNING, "Invalid session-timers '%s' at line %d of %s\n", v->value, v->lineno, config);
23898             global_st_mode = SESSION_TIMER_MODE_ACCEPT;
23899          } else {
23900             global_st_mode = i;
23901          }
23902       } else if (!strcasecmp(v->name, "session-expires")) {
23903          if (sscanf(v->value, "%30d", &global_max_se) != 1) {
23904             ast_log(LOG_WARNING, "Invalid session-expires '%s' at line %d of %s\n", v->value, v->lineno, config);
23905             global_max_se = DEFAULT_MAX_SE;
23906          } 
23907       } else if (!strcasecmp(v->name, "session-minse")) {
23908          if (sscanf(v->value, "%30d", &global_min_se) != 1) {
23909             ast_log(LOG_WARNING, "Invalid session-minse '%s' at line %d of %s\n", v->value, v->lineno, config);
23910             global_min_se = DEFAULT_MIN_SE;
23911          } 
23912          if (global_min_se < 90) {
23913             ast_log(LOG_WARNING, "session-minse '%s' at line %d of %s is not allowed to be < 90 secs\n", v->value, v->lineno, config);
23914             global_min_se = DEFAULT_MIN_SE;
23915          } 
23916       } else if (!strcasecmp(v->name, "session-refresher")) {
23917          int i = (int) str2strefresher(v->value); 
23918          if (i < 0) {
23919             ast_log(LOG_WARNING, "Invalid session-refresher '%s' at line %d of %s\n", v->value, v->lineno, config);
23920             global_st_refresher = SESSION_TIMER_REFRESHER_UAS;
23921          } else {
23922             global_st_refresher = i;
23923          }
23924       } else if (!strcasecmp(v->name, "shrinkcallerid")) {
23925          if (ast_true(v->value)) {
23926             global_shrinkcallerid = 1;
23927          } else if (ast_false(v->value)) {
23928             global_shrinkcallerid = 0;
23929          } else {
23930             ast_log(LOG_WARNING, "shrinkcallerid value %s is not valid at line %d.\n", v->value, v->lineno);
23931          }
23932       }
23933    }
23934 
23935    if (!allow_external_domains && AST_LIST_EMPTY(&domain_list)) {
23936       ast_log(LOG_WARNING, "To disallow external domains, you need to configure local SIP domains.\n");
23937       allow_external_domains = 1;
23938    }
23939    
23940    /* Build list of authentication to various SIP realms, i.e. service providers */
23941    for (v = ast_variable_browse(cfg, "authentication"); v ; v = v->next) {
23942       /* Format for authentication is auth = username:password@realm */
23943       if (!strcasecmp(v->name, "auth"))
23944          authl = add_realm_authentication(authl, v->value, v->lineno);
23945    }
23946    
23947    if (ucfg) {
23948       struct ast_variable *gen;
23949       int genhassip, genregistersip;
23950       const char *hassip, *registersip;
23951       
23952       genhassip = ast_true(ast_variable_retrieve(ucfg, "general", "hassip"));
23953       genregistersip = ast_true(ast_variable_retrieve(ucfg, "general", "registersip"));
23954       gen = ast_variable_browse(ucfg, "general");
23955       cat = ast_category_browse(ucfg, NULL);
23956       while (cat) {
23957          if (strcasecmp(cat, "general")) {
23958             hassip = ast_variable_retrieve(ucfg, cat, "hassip");
23959             registersip = ast_variable_retrieve(ucfg, cat, "registersip");
23960             if (ast_true(hassip) || (!hassip && genhassip)) {
23961                peer = build_peer(cat, gen, ast_variable_browse(ucfg, cat), 0, 0);
23962                if (peer) {
23963                   /* user.conf entries are always of type friend */
23964                   peer->type = SIP_TYPE_USER | SIP_TYPE_PEER;
23965                   ao2_t_link(peers, peer, "link peer into peer table");
23966                   if ((peer->type & SIP_TYPE_PEER) && peer->addr.sin_addr.s_addr) {
23967                      ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
23968                   }
23969                   
23970                   unref_peer(peer, "unref_peer: from reload_config");
23971                   peer_count++;
23972                }
23973             }
23974             if (ast_true(registersip) || (!registersip && genregistersip)) {
23975                char tmp[256];
23976                const char *host = ast_variable_retrieve(ucfg, cat, "host");
23977                const char *username = ast_variable_retrieve(ucfg, cat, "username");
23978                const char *secret = ast_variable_retrieve(ucfg, cat, "secret");
23979                const char *contact = ast_variable_retrieve(ucfg, cat, "contact");
23980                const char *authuser = ast_variable_retrieve(ucfg, cat, "authuser");
23981                if (!host)
23982                   host = ast_variable_retrieve(ucfg, "general", "host");
23983                if (!username)
23984                   username = ast_variable_retrieve(ucfg, "general", "username");
23985                if (!secret)
23986                   secret = ast_variable_retrieve(ucfg, "general", "secret");
23987                if (!contact)
23988                   contact = "s";
23989                if (!ast_strlen_zero(username) && !ast_strlen_zero(host)) {
23990                   if (!ast_strlen_zero(secret)) {
23991                      if (!ast_strlen_zero(authuser)) {
23992                         snprintf(tmp, sizeof(tmp), "%s:%s:%s@%s/%s", username, secret, authuser, host, contact);
23993                      } else {
23994                         snprintf(tmp, sizeof(tmp), "%s:%s@%s/%s", username, secret, host, contact);
23995                      }
23996                   } else if (!ast_strlen_zero(authuser)) {
23997                      snprintf(tmp, sizeof(tmp), "%s::%s@%s/%s", username, authuser, host, contact);
23998                   } else {
23999                      snprintf(tmp, sizeof(tmp), "%s@%s/%s", username, host, contact);
24000                   }
24001                   if (sip_register(tmp, 0) == 0)
24002                      registry_count++;
24003                }
24004             }
24005          }
24006          cat = ast_category_browse(ucfg, cat);
24007       }
24008       ast_config_destroy(ucfg);
24009    }
24010    
24011 
24012    /* Load peers, users and friends */
24013    cat = NULL;
24014    while ( (cat = ast_category_browse(cfg, cat)) ) {
24015       const char *utype;
24016       if (!strcasecmp(cat, "general") || !strcasecmp(cat, "authentication"))
24017          continue;
24018       utype = ast_variable_retrieve(cfg, cat, "type");
24019       if (!utype) {
24020          ast_log(LOG_WARNING, "Section '%s' lacks type\n", cat);
24021          continue;
24022       } else {
24023          if (!strcasecmp(utype, "user")) {
24024             ;
24025          } else if (!strcasecmp(utype, "friend")) {
24026             ;
24027          } else if (!strcasecmp(utype, "peer")) {
24028             ;
24029          } else {
24030             ast_log(LOG_WARNING, "Unknown type '%s' for '%s' in %s\n", utype, cat, "sip.conf");
24031             continue;
24032          }
24033          peer = build_peer(cat, ast_variable_browse(cfg, cat), NULL, 0, 0);
24034          if (peer) {
24035             ao2_t_link(peers, peer, "link peer into peers table");
24036             if ((peer->type & SIP_TYPE_PEER) && peer->addr.sin_addr.s_addr) {
24037                ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
24038             }
24039             unref_peer(peer, "unref the result of the build_peer call. Now, the links from the tables are the only ones left.");
24040             peer_count++;
24041          }
24042       }
24043    }
24044    
24045    /* Set UDP address and open socket */
24046    bindaddr.sin_family = AF_INET;
24047    internip = bindaddr;
24048    if (ast_find_ourip(&internip.sin_addr, bindaddr)) {
24049       ast_log(LOG_WARNING, "Unable to get own IP address, SIP disabled\n");
24050       ast_config_destroy(cfg);
24051       return 0;
24052    }
24053    ast_mutex_lock(&netlock);
24054    if ((sipsock > -1) && (memcmp(&old_bindaddr, &bindaddr, sizeof(struct sockaddr_in)))) {
24055       close(sipsock);
24056       sipsock = -1;
24057    }
24058    if (sipsock < 0) {
24059       sipsock = socket(AF_INET, SOCK_DGRAM, 0);
24060       if (sipsock < 0) {
24061          ast_log(LOG_WARNING, "Unable to create SIP socket: %s\n", strerror(errno));
24062          ast_config_destroy(cfg);
24063          return -1;
24064       } else {
24065          /* Allow SIP clients on the same host to access us: */
24066          const int reuseFlag = 1;
24067 
24068          setsockopt(sipsock, SOL_SOCKET, SO_REUSEADDR,
24069                (const char*)&reuseFlag,
24070                sizeof reuseFlag);
24071 
24072          ast_enable_packet_fragmentation(sipsock);
24073 
24074          if (bind(sipsock, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) {
24075             ast_log(LOG_WARNING, "Failed to bind to %s:%d: %s\n",
24076             ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port),
24077             strerror(errno));
24078             close(sipsock);
24079             sipsock = -1;
24080          } else {
24081             ast_verb(2, "SIP Listening on %s:%d\n",
24082                   ast_inet_ntoa(bindaddr.sin_addr), ntohs(bindaddr.sin_port));
24083             ast_netsock_set_qos(sipsock, global_tos_sip, global_cos_sip, "SIP");
24084          }
24085       }
24086    }
24087    if (stunaddr.sin_addr.s_addr != 0) {
24088       ast_debug(1, "stun to %s:%d\n",
24089          ast_inet_ntoa(stunaddr.sin_addr) , ntohs(stunaddr.sin_port));
24090       ast_stun_request(sipsock, &stunaddr,
24091          NULL, &externip);
24092       ast_debug(1, "STUN sees us at %s:%d\n", 
24093          ast_inet_ntoa(externip.sin_addr) , ntohs(externip.sin_port));
24094    }
24095    ast_mutex_unlock(&netlock);
24096 
24097    /* Start TCP server */
24098    ast_tcptls_server_start(&sip_tcp_desc);
24099 
24100    /* Start TLS server if needed */
24101    memcpy(sip_tls_desc.tls_cfg, &default_tls_cfg, sizeof(default_tls_cfg));
24102 
24103    if (ast_ssl_setup(sip_tls_desc.tls_cfg))
24104       ast_tcptls_server_start(&sip_tls_desc);
24105    else if (sip_tls_desc.tls_cfg->enabled) {
24106       sip_tls_desc.tls_cfg = NULL;
24107       ast_log(LOG_WARNING, "SIP TLS server did not load because of errors.\n");
24108    }
24109 
24110 
24111    /* Add default domains - host name, IP address and IP:port
24112     * Only do this if user added any sip domain with "localdomains" 
24113     * In order to *not* break backwards compatibility 
24114     *    Some phones address us at IP only, some with additional port number 
24115     */
24116    if (auto_sip_domains) {
24117       char temp[MAXHOSTNAMELEN];
24118 
24119       /* First our default IP address */
24120       if (bindaddr.sin_addr.s_addr) {
24121          add_sip_domain(ast_inet_ntoa(bindaddr.sin_addr), SIP_DOMAIN_AUTO, NULL);
24122       } else if (internip.sin_addr.s_addr) {
24123       /* Our internal IP address, if configured */
24124          add_sip_domain(ast_inet_ntoa(internip.sin_addr), SIP_DOMAIN_AUTO, NULL);
24125       } else {
24126          ast_log(LOG_NOTICE, "Can't add wildcard IP address to domain list, please add IP address to domain manually.\n");
24127       }
24128 
24129       /* If TCP is running on a different IP than UDP, then add it too */
24130       if (sip_tcp_desc.local_address.sin_addr.s_addr && !inaddrcmp(&bindaddr, &sip_tcp_desc.local_address))
24131          add_sip_domain(ast_inet_ntoa(sip_tcp_desc.local_address.sin_addr), SIP_DOMAIN_AUTO, NULL);
24132 
24133       /* If TLS is running on a differen IP than UDP and TCP, then add that too */
24134       if (sip_tls_desc.local_address.sin_addr.s_addr && !inaddrcmp(&bindaddr, &sip_tls_desc.local_address) && inaddrcmp(&sip_tcp_desc.local_address, &sip_tls_desc.local_address))
24135          add_sip_domain(ast_inet_ntoa(sip_tls_desc.local_address.sin_addr), SIP_DOMAIN_AUTO, NULL);
24136 
24137       /* Our extern IP address, if configured */
24138       if (externip.sin_addr.s_addr)
24139          add_sip_domain(ast_inet_ntoa(externip.sin_addr), SIP_DOMAIN_AUTO, NULL);
24140 
24141       /* Extern host name (NAT traversal support) */
24142       if (!ast_strlen_zero(externhost))
24143          add_sip_domain(externhost, SIP_DOMAIN_AUTO, NULL);
24144       
24145       /* Our host name */
24146       if (!gethostname(temp, sizeof(temp)))
24147          add_sip_domain(temp, SIP_DOMAIN_AUTO, NULL);
24148    }
24149 
24150    /* Release configuration from memory */
24151    ast_config_destroy(cfg);
24152 
24153    /* Load the list of manual NOTIFY types to support */
24154    if (notify_types)
24155       ast_config_destroy(notify_types);
24156    notify_types = ast_config_load(notify_config, config_flags);
24157 
24158    /* Done, tell the manager */
24159    manager_event(EVENT_FLAG_SYSTEM, "ChannelReload", "ChannelType: SIP\r\nReloadReason: %s\r\nRegistry_Count: %d\r\nPeer_Count: %d\r\n", channelreloadreason2txt(reason), registry_count, peer_count);
24160    run_end = time(0);
24161    ast_debug(4, "SIP reload_config done...Runtime= %d sec\n", (int)(run_end-run_start));
24162 
24163    return 0;
24164 }

static char * remove_uri_parameters ( char *  uri  )  [static]

Definition at line 9898 of file chan_sip.c.

Referenced by extract_uri(), parse_moved_contact(), register_verify(), reqprep(), and transmit_state_notify().

09899 {
09900    char *atsign;
09901    atsign = strchr(uri, '@'); /* First, locate the at sign */
09902    if (!atsign)
09903       atsign = uri;  /* Ok hostname only, let's stick with the rest */
09904    atsign = strchr(atsign, ';'); /* Locate semi colon */
09905    if (atsign)
09906       *atsign = '\0';   /* Kill at the semi colon */
09907    return uri;
09908 }

static void replace_cid ( struct sip_pvt p,
const char *  rpid_num,
const char *  calleridname 
) [static]

helper function for check_{user|peer}_ok()

Definition at line 13131 of file chan_sip.c.

References ast_is_shrinkable_phonenumber(), ast_shrink_phone_number(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, cid_name, cid_num, sip_pvt::flags, and SIP_TRUSTRPID.

Referenced by check_peer_ok(), and check_user_full().

13132 {
13133    /* replace callerid if rpid found, and not restricted */
13134    if (!ast_strlen_zero(rpid_num) && ast_test_flag(&p->flags[0], SIP_TRUSTRPID)) {
13135       char *tmp = ast_strdupa(rpid_num); /* XXX the copy can be done later */
13136       if (!ast_strlen_zero(calleridname))
13137          ast_string_field_set(p, cid_name, calleridname);
13138       if (global_shrinkcallerid && ast_is_shrinkable_phonenumber(tmp))
13139          ast_shrink_phone_number(tmp);
13140       ast_string_field_set(p, cid_num, tmp);
13141    }
13142 }

static int reply_digest ( struct sip_pvt p,
struct sip_request req,
char *  header,
int  sipmethod,
char *  digest,
int  digest_len 
) [static]

reply to authentication for outbound registrations

Returns:
Returns -1 if we have no auth
Note:
This is used for register= servers in sip.conf, SIP proxies we register with for receiving calls from.

Definition at line 16261 of file chan_sip.c.

References ast_copy_string(), ast_log(), ast_skip_blanks(), ast_string_field_ptr_set, ast_string_field_set, ast_strlen_zero(), build_reply_digest(), sip_pvt::domain, get_header(), LOG_WARNING, sip_registry::nonce, sip_pvt::nonce, sip_registry::noncecount, sip_pvt::noncecount, sip_registry::opaque, sip_pvt::opaque, sip_registry::qop, sip_pvt::qop, sip_registry::realm, sip_pvt::realm, sip_pvt::registry, and strsep().

Referenced by do_proxy_auth(), and do_register_auth().

16262 {
16263    char tmp[512];
16264    char *c;
16265    char oldnonce[256];
16266 
16267    /* table of recognised keywords, and places where they should be copied */
16268    const struct x {
16269       const char *key;
16270       const ast_string_field *field;
16271    } *i, keys[] = {
16272       { "realm=", &p->realm },
16273       { "nonce=", &p->nonce },
16274       { "opaque=", &p->opaque },
16275       { "qop=", &p->qop },
16276       { "domain=", &p->domain },
16277       { NULL, 0 },
16278    };
16279 
16280    ast_copy_string(tmp, get_header(req, header), sizeof(tmp));
16281    if (ast_strlen_zero(tmp)) 
16282       return -1;
16283    if (strncasecmp(tmp, "Digest ", strlen("Digest "))) {
16284       ast_log(LOG_WARNING, "missing Digest.\n");
16285       return -1;
16286    }
16287    c = tmp + strlen("Digest ");
16288    ast_copy_string(oldnonce, p->nonce, sizeof(oldnonce));
16289    while (c && *(c = ast_skip_blanks(c))) {  /* lookup for keys */
16290       for (i = keys; i->key != NULL; i++) {
16291          char *src, *separator;
16292          if (strncasecmp(c, i->key, strlen(i->key)) != 0)
16293             continue;
16294          /* Found. Skip keyword, take text in quotes or up to the separator. */
16295          c += strlen(i->key);
16296          if (*c == '"') {
16297             src = ++c;
16298             separator = "\"";
16299          } else {
16300             src = c;
16301             separator = ",";
16302          }
16303          strsep(&c, separator); /* clear separator and move ptr */
16304          ast_string_field_ptr_set(p, i->field, src);
16305          break;
16306       }
16307       if (i->key == NULL) /* not found, try ',' */
16308          strsep(&c, ",");
16309    }
16310    /* Reset nonce count */
16311    if (strcmp(p->nonce, oldnonce)) 
16312       p->noncecount = 0;
16313 
16314    /* Save auth data for following registrations */
16315    if (p->registry) {
16316       struct sip_registry *r = p->registry;
16317 
16318       if (strcmp(r->nonce, p->nonce)) {
16319          ast_string_field_set(r, realm, p->realm);
16320          ast_string_field_set(r, nonce, p->nonce);
16321          ast_string_field_set(r, domain, p->domain);
16322          ast_string_field_set(r, opaque, p->opaque);
16323          ast_string_field_set(r, qop, p->qop);
16324          r->noncecount = 0;
16325       }
16326    }
16327    return build_reply_digest(p, sipmethod, digest, digest_len); 
16328 }

static int reqprep ( struct sip_request req,
struct sip_pvt p,
int  sipmethod,
int  seqno,
int  newbranch 
) [static]

Initialize a SIP request message (not the initial one in a dialog).

< Strict routing flag

Definition at line 8791 of file chan_sip.c.

References add_header(), add_route(), ast_copy_string(), ast_debug, ast_random(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, sip_pvt::branch, build_via(), sip_pvt::callid, copy_header(), DEFAULT_MAX_FORWARDS, FALSE, sip_pvt::flags, get_header(), get_in_brackets(), sip_route::hop, init_req(), sip_pvt::initreq, sip_pvt::invite_branch, sip_pvt::lastmsg, sip_route::next, sip_pvt::ocseq, sip_pvt::okcontacturi, sip_pvt::our_contact, remove_uri_parameters(), REQ_OFFSET_TO_STR, sip_request::rlPart2, sip_pvt::route, sip_pvt::rpid, set_destination(), SIP_ACK, SIP_BYE, SIP_CANCEL, SIP_INVITE, SIP_MESSAGE, sip_methods, SIP_OUTGOING, sip_st_dlg::st_active, sip_st_dlg::st_active_peer_ua, st_get_se(), sip_st_dlg::st_interval, sip_st_dlg::st_ref, sip_pvt::stimer, strcasestr(), strefresher2str(), sip_pvt::tag, text, cfsip_methods::text, sip_pvt::theirtag, TRUE, sip_pvt::uri, url, sip_pvt::url, and sip_pvt::via.

08792 {
08793    struct sip_request *orig = &p->initreq;
08794    char stripped[80];
08795    char tmp[80];
08796    char newto[256];
08797    const char *c;
08798    const char *ot, *of;
08799    int is_strict = FALSE;     /*!< Strict routing flag */
08800    int is_outbound = ast_test_flag(&p->flags[0], SIP_OUTGOING);   /* Session direction */
08801 
08802    memset(req, 0, sizeof(struct sip_request));
08803    
08804    snprintf(p->lastmsg, sizeof(p->lastmsg), "Tx: %s", sip_methods[sipmethod].text);
08805    
08806    if (!seqno) {
08807       p->ocseq++;
08808       seqno = p->ocseq;
08809    }
08810    
08811    /* A CANCEL must have the same branch as the INVITE that it is canceling. */
08812    if (sipmethod == SIP_CANCEL) {
08813       p->branch = p->invite_branch;
08814       build_via(p);
08815    } else if (newbranch && (sipmethod == SIP_INVITE)) {
08816       p->branch ^= ast_random();
08817       p->invite_branch = p->branch;
08818       build_via(p);
08819    } else if (newbranch) {
08820       p->branch ^= ast_random();
08821       build_via(p);
08822    }
08823 
08824    /* Check for strict or loose router */
08825    if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop, ";lr") == NULL) {
08826       is_strict = TRUE;
08827       if (sipdebug)
08828          ast_debug(1, "Strict routing enforced for session %s\n", p->callid);
08829    }
08830    
08831    if (sipmethod == SIP_CANCEL)
08832       c = REQ_OFFSET_TO_STR(&p->initreq, rlPart2); /* Use original URI */
08833    else if (sipmethod == SIP_ACK) {
08834       /* Use URI from Contact: in 200 OK (if INVITE) 
08835       (we only have the contacturi on INVITEs) */
08836       if (!ast_strlen_zero(p->okcontacturi))
08837          c = is_strict ? p->route->hop : p->okcontacturi;
08838       else
08839          c = REQ_OFFSET_TO_STR(&p->initreq, rlPart2);
08840    } else if (!ast_strlen_zero(p->okcontacturi)) 
08841       c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */
08842    else if (!ast_strlen_zero(p->uri)) 
08843       c = p->uri;
08844    else {
08845       char *n;
08846       /* We have no URI, use To: or From:  header as URI (depending on direction) */
08847       ast_copy_string(stripped, get_header(orig, is_outbound ? "To" : "From"),
08848             sizeof(stripped));
08849       n = get_in_brackets(stripped);
08850       c = remove_uri_parameters(n);
08851    }  
08852    init_req(req, sipmethod, c);
08853 
08854    snprintf(tmp, sizeof(tmp), "%d %s", seqno, sip_methods[sipmethod].text);
08855 
08856    add_header(req, "Via", p->via);
08857    if (p->route) {
08858       set_destination(p, p->route->hop);
08859       add_route(req, is_strict ? p->route->next : p->route);
08860    }
08861    add_header(req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
08862 
08863    ot = get_header(orig, "To");
08864    of = get_header(orig, "From");
08865 
08866    /* Add tag *unless* this is a CANCEL, in which case we need to send it exactly
08867       as our original request, including tag (or presumably lack thereof) */
08868    if (!strcasestr(ot, "tag=") && sipmethod != SIP_CANCEL) {
08869       /* Add the proper tag if we don't have it already.  If they have specified
08870          their tag, use it.  Otherwise, use our own tag */
08871       if (is_outbound && !ast_strlen_zero(p->theirtag))
08872          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
08873       else if (!is_outbound)
08874          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
08875       else
08876          snprintf(newto, sizeof(newto), "%s", ot);
08877       ot = newto;
08878    }
08879 
08880    if (is_outbound) {
08881       add_header(req, "From", of);
08882       add_header(req, "To", ot);
08883    } else {
08884       add_header(req, "From", ot);
08885       add_header(req, "To", of);
08886    }
08887    /* Do not add Contact for MESSAGE, BYE and Cancel requests */
08888    if (sipmethod != SIP_BYE && sipmethod != SIP_CANCEL && sipmethod != SIP_MESSAGE)
08889       add_header(req, "Contact", p->our_contact);
08890 
08891    copy_header(req, orig, "Call-ID");
08892    add_header(req, "CSeq", tmp);
08893 
08894    if (!ast_strlen_zero(global_useragent))
08895       add_header(req, "User-Agent", global_useragent);
08896 
08897    if (!ast_strlen_zero(p->rpid))
08898       add_header(req, "Remote-Party-ID", p->rpid);
08899 
08900    if (!ast_strlen_zero(p->url)) {
08901       add_header(req, "Access-URL", p->url);
08902       ast_string_field_set(p, url, NULL);
08903    }
08904 
08905    /* Add Session-Timers related headers if the feature is active for this session.
08906       An exception to this behavior is the ACK request. Since Asterisk never requires 
08907       session-timers support from a remote end-point (UAS) in an INVITE, it must 
08908       not send 'Require: timer' header in the ACK request. 
08909       This should only be added in the INVITE transactions, not MESSAGE or REFER or other
08910       in-dialog messages.
08911    */
08912    if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_active_peer_ua == TRUE 
08913        && sipmethod == SIP_INVITE) {
08914       char se_hdr[256];
08915       snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval, 
08916          strefresher2str(p->stimer->st_ref));
08917       add_header(req, "Require", "timer");
08918       add_header(req, "Session-Expires", se_hdr);
08919       snprintf(se_hdr, sizeof(se_hdr), "%d", st_get_se(p, FALSE));
08920       add_header(req, "Min-SE", se_hdr);
08921    }
08922 
08923    return 0;
08924 }

static int resp_needs_contact ( const char *  msg,
enum sipmethod  method 
) [inline, static]

Test if this response needs a contact header.

Definition at line 8665 of file chan_sip.c.

References SIP_ACK, SIP_BYE, SIP_CANCEL, SIP_INFO, SIP_INVITE, SIP_MESSAGE, SIP_NOTIFY, SIP_OPTIONS, SIP_PING, SIP_PRACK, SIP_PUBLISH, SIP_REFER, SIP_REGISTER, SIP_SUBSCRIBE, and SIP_UPDATE.

Referenced by respprep().

08665                                                                              {
08666    /* Requirements for Contact header inclusion in responses generated
08667     * from the header tables found in the following RFCs.  Where the
08668     * Contact header was marked mandatory (m) or optional (o) this
08669     * function returns 1.
08670     *
08671     * - RFC 3261 (ACK, BYE, CANCEL, INVITE, OPTIONS, REGISTER)
08672     * - RFC 2976 (INFO)
08673     * - RFC 3262 (PRACK)
08674     * - RFC 3265 (SUBSCRIBE, NOTIFY)
08675     * - RFC 3311 (UPDATE)
08676     * - RFC 3428 (MESSAGE)
08677     * - RFC 3515 (REFER)
08678     * - RFC 3903 (PUBLISH)
08679     */
08680 
08681    switch (method) {
08682       /* 1xx, 2xx, 3xx, 485 */
08683       case SIP_INVITE:
08684       case SIP_UPDATE:
08685       case SIP_SUBSCRIBE:
08686       case SIP_NOTIFY:
08687          if ((msg[0] >= '1' && msg[0] <= '3') || !strncmp(msg, "485", 3))
08688             return 1;
08689          break;
08690 
08691       /* 2xx, 3xx, 485 */
08692       case SIP_REGISTER:
08693       case SIP_OPTIONS:
08694          if (msg[0] == '2' || msg[0] == '3' || !strncmp(msg, "485", 3))
08695             return 1;
08696          break;
08697 
08698       /* 3xx, 485 */
08699       case SIP_BYE:
08700       case SIP_PRACK:
08701       case SIP_MESSAGE:
08702       case SIP_PUBLISH:
08703          if (msg[0] == '3' || !strncmp(msg, "485", 3))
08704             return 1;
08705          break;
08706 
08707       /* 2xx, 3xx, 4xx, 5xx, 6xx */
08708       case SIP_REFER:
08709          if (msg[0] >= '2' && msg[0] <= '6')
08710             return 1;
08711          break;
08712 
08713       /* contact will not be included for everything else */
08714       case SIP_ACK:
08715       case SIP_CANCEL:
08716       case SIP_INFO:
08717       case SIP_PING:
08718       default:
08719          return 0;
08720    }
08721    return 0;
08722 }

static int respprep ( struct sip_request resp,
struct sip_pvt p,
const char *  msg,
const struct sip_request req 
) [static]

Prepare SIP response packet.

Definition at line 8725 of file chan_sip.c.

References add_header(), ALLOWED_METHODS, ast_copy_string(), ast_string_field_set, ast_strlen_zero(), ast_test_flag, copy_all_header(), copy_header(), copy_via_headers(), sip_pvt::expiry, sip_pvt::flags, sip_pvt::fullcontact, get_header(), init_resp(), sip_pvt::method, sip_pvt::our_contact, resp_needs_contact(), SIP_INVITE, SIP_OUTGOING, SIP_REGISTER, SIP_SUBSCRIBE, SIPBUFSIZE, sip_st_dlg::st_active, sip_st_dlg::st_active_peer_ua, sip_st_dlg::st_interval, sip_st_dlg::st_ref, sip_pvt::stimer, strcasestr(), strefresher2str(), SUPPORTED_EXTENSIONS, sip_pvt::tag, sip_pvt::theirtag, TRUE, url, and sip_pvt::url.

08726 {
08727    char newto[256];
08728    const char *ot;
08729 
08730    init_resp(resp, msg);
08731    copy_via_headers(p, resp, req, "Via");
08732    if (msg[0] == '1' || msg[0] == '2')
08733       copy_all_header(resp, req, "Record-Route");
08734    copy_header(resp, req, "From");
08735    ot = get_header(req, "To");
08736    if (!strcasestr(ot, "tag=") && strncmp(msg, "100", 3)) {
08737       /* Add the proper tag if we don't have it already.  If they have specified
08738          their tag, use it.  Otherwise, use our own tag */
08739       if (!ast_strlen_zero(p->theirtag) && ast_test_flag(&p->flags[0], SIP_OUTGOING))
08740          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->theirtag);
08741       else if (p->tag && !ast_test_flag(&p->flags[0], SIP_OUTGOING))
08742          snprintf(newto, sizeof(newto), "%s;tag=%s", ot, p->tag);
08743       else
08744          ast_copy_string(newto, ot, sizeof(newto));
08745       ot = newto;
08746    }
08747    add_header(resp, "To", ot);
08748    copy_header(resp, req, "Call-ID");
08749    copy_header(resp, req, "CSeq");
08750    if (!ast_strlen_zero(global_useragent))
08751       add_header(resp, "Server", global_useragent);
08752    add_header(resp, "Allow", ALLOWED_METHODS);
08753    add_header(resp, "Supported", SUPPORTED_EXTENSIONS);
08754 
08755    /* If this is an invite, add Session-Timers related headers if the feature is active for this session */
08756    if (p->method == SIP_INVITE && p->stimer && p->stimer->st_active == TRUE && p->stimer->st_active_peer_ua == TRUE) {
08757       char se_hdr[256];
08758       snprintf(se_hdr, sizeof(se_hdr), "%d;refresher=%s", p->stimer->st_interval, 
08759          strefresher2str(p->stimer->st_ref));
08760       add_header(resp, "Require", "timer");
08761       add_header(resp, "Session-Expires", se_hdr);
08762    }
08763 
08764    if (msg[0] == '2' && (p->method == SIP_SUBSCRIBE || p->method == SIP_REGISTER)) {
08765       /* For registration responses, we also need expiry and
08766          contact info */
08767       char tmp[256];
08768 
08769       snprintf(tmp, sizeof(tmp), "%d", p->expiry);
08770       add_header(resp, "Expires", tmp);
08771       if (p->expiry) {  /* Only add contact if we have an expiry time */
08772          char contact[SIPBUFSIZE];
08773          const char *contact_uri = p->method == SIP_SUBSCRIBE ? p->our_contact : p->fullcontact;
08774          char *brackets = strchr(contact_uri, '<');
08775          snprintf(contact, sizeof(contact), "%s%s%s;expires=%d", brackets ? "" : "<", contact_uri, brackets ? "" : ">", p->expiry);
08776          add_header(resp, "Contact", contact);  /* Not when we unregister */
08777       }
08778    } else if (!ast_strlen_zero(p->our_contact) && resp_needs_contact(msg, p->method)) {
08779       add_header(resp, "Contact", p->our_contact);
08780    }
08781 
08782    if (!ast_strlen_zero(p->url)) {
08783       add_header(resp, "Access-URL", p->url);
08784       ast_string_field_set(p, url, NULL);
08785    }
08786 
08787    return 0;
08788 }

static int restart_monitor ( void   )  [static]

Start the channel monitor thread.

Definition at line 21571 of file chan_sip.c.

References ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_pthread_create_background, AST_PTHREADT_NULL, AST_PTHREADT_STOP, do_monitor(), LOG_ERROR, LOG_WARNING, and monlock.

21572 {
21573    /* If we're supposed to be stopped -- stay stopped */
21574    if (monitor_thread == AST_PTHREADT_STOP)
21575       return 0;
21576    ast_mutex_lock(&monlock);
21577    if (monitor_thread == pthread_self()) {
21578       ast_mutex_unlock(&monlock);
21579       ast_log(LOG_WARNING, "Cannot kill myself\n");
21580       return -1;
21581    }
21582    if (monitor_thread != AST_PTHREADT_NULL) {
21583       /* Wake up the thread */
21584       pthread_kill(monitor_thread, SIGURG);
21585    } else {
21586       /* Start a new monitor */
21587       if (ast_pthread_create_background(&monitor_thread, NULL, do_monitor, NULL) < 0) {
21588          ast_mutex_unlock(&monlock);
21589          ast_log(LOG_ERROR, "Unable to start monitor thread.\n");
21590          return -1;
21591       }
21592    }
21593    ast_mutex_unlock(&monlock);
21594    return 0;
21595 }

static void restart_session_timer ( struct sip_pvt p  )  [static]

Session-Timers: Restart session timer.

Definition at line 21599 of file chan_sip.c.

References ast_debug, ast_log(), AST_SCHED_DEL_UNREF, sip_pvt::callid, dialog_unref(), LOG_WARNING, sched, sip_st_dlg::st_active, sip_st_dlg::st_schedid, start_session_timer(), sip_pvt::stimer, and TRUE.

Referenced by handle_request_invite().

21600 {
21601    if (!p->stimer) {
21602       ast_log(LOG_WARNING, "Null stimer in restart_session_timer - %s\n", p->callid);
21603       return;
21604    }
21605 
21606    if (p->stimer->st_active == TRUE) {
21607       AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid,
21608             dialog_unref(p, "Removing session timer ref"));
21609       ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
21610       start_session_timer(p);
21611    }
21612 }

static int retrans_pkt ( const void *  data  )  [static]

Retransmit SIP message if no answer (Called from scheduler).

Definition at line 3344 of file chan_sip.c.

References __sip_xmit(), append_history, AST_CAUSE_NO_USER_RESPONSE, AST_CAUSE_PROTOCOL_ERROR, ast_channel_trylock, ast_channel_unlock, ast_debug, ast_free, ast_inet_ntoa(), ast_log(), ast_queue_hangup_with_cause(), ast_verbose, sip_pvt::callid, sip_pkt::data, DEFAULT_RETRANS, dialog_unref(), ast_channel::hangupcause, sip_pkt::is_fatal, sip_pkt::is_resp, LOG_WARNING, MAX_RETRANS, sip_pkt::method, sip_pvt::needdestroy, sip_pkt::next, sip_pvt::owner, sip_pkt::owner, sip_pkt::packetlen, sip_pvt::packets, sip_pkt::retrans, sip_pkt::retransid, sip_pkt::seqno, sip_alreadygone(), SIP_BYE, sip_debug_test_pvt(), SIP_INVITE, sip_methods, sip_nat_mode(), SIP_OPTIONS, sip_pvt_lock, sip_pvt_unlock, sip_real_dst(), SIP_REGISTER, ast_str::str, sip_pkt::timer_a, sip_pkt::timer_t1, UNLINK, and XMIT_ERROR.

03345 {
03346    struct sip_pkt *pkt = (struct sip_pkt *)data, *prev, *cur = NULL;
03347    int reschedule = DEFAULT_RETRANS;
03348    int xmitres = 0;
03349    
03350    /* Lock channel PVT */
03351    sip_pvt_lock(pkt->owner);
03352 
03353    if (pkt->retrans < MAX_RETRANS) {
03354       pkt->retrans++;
03355       if (!pkt->timer_t1) {   /* Re-schedule using timer_a and timer_t1 */
03356          if (sipdebug)
03357             ast_debug(4, "SIP TIMER: Not rescheduling id #%d:%s (Method %d) (No timer T1)\n", pkt->retransid, sip_methods[pkt->method].text, pkt->method);
03358       } else {
03359          int siptimer_a;
03360 
03361          if (sipdebug)
03362             ast_debug(4, "SIP TIMER: Rescheduling retransmission #%d (%d) %s - %d\n", pkt->retransid, pkt->retrans, sip_methods[pkt->method].text, pkt->method);
03363          if (!pkt->timer_a)
03364             pkt->timer_a = 2 ;
03365          else
03366             pkt->timer_a = 2 * pkt->timer_a;
03367  
03368          /* For non-invites, a maximum of 4 secs */
03369          siptimer_a = pkt->timer_t1 * pkt->timer_a;   /* Double each time */
03370          if (pkt->method != SIP_INVITE && siptimer_a > 4000)
03371             siptimer_a = 4000;
03372       
03373          /* Reschedule re-transmit */
03374          reschedule = siptimer_a;
03375          ast_debug(4, "** SIP timers: Rescheduling retransmission %d to %d ms (t1 %d ms (Retrans id #%d)) \n", pkt->retrans +1, siptimer_a, pkt->timer_t1, pkt->retransid);
03376       } 
03377 
03378       if (sip_debug_test_pvt(pkt->owner)) {
03379          const struct sockaddr_in *dst = sip_real_dst(pkt->owner);
03380          ast_verbose("Retransmitting #%d (%s) to %s:%d:\n%s\n---\n",
03381             pkt->retrans, sip_nat_mode(pkt->owner),
03382             ast_inet_ntoa(dst->sin_addr),
03383             ntohs(dst->sin_port), pkt->data->str);
03384       }
03385 
03386       append_history(pkt->owner, "ReTx", "%d %s", reschedule, pkt->data->str);
03387       xmitres = __sip_xmit(pkt->owner, pkt->data, pkt->packetlen);
03388       sip_pvt_unlock(pkt->owner);
03389       if (xmitres == XMIT_ERROR)
03390          ast_log(LOG_WARNING, "Network error on retransmit in dialog %s\n", pkt->owner->callid);
03391       else 
03392          return  reschedule;
03393    } 
03394    /* Too many retries */
03395    if (pkt->owner && pkt->method != SIP_OPTIONS && xmitres == 0) {
03396       if (pkt->is_fatal || sipdebug)   /* Tell us if it's critical or if we're debugging */
03397          ast_log(LOG_WARNING, "Maximum retries exceeded on transmission %s for seqno %d (%s %s) -- See doc/sip-retransmit.txt.\n",
03398             pkt->owner->callid, pkt->seqno,
03399             pkt->is_fatal ? "Critical" : "Non-critical", pkt->is_resp ? "Response" : "Request");
03400    } else if (pkt->method == SIP_OPTIONS && sipdebug) {
03401          ast_log(LOG_WARNING, "Cancelling retransmit of OPTIONs (call id %s)  -- See doc/sip-retransmit.txt.\n", pkt->owner->callid);
03402 
03403    } 
03404    if (xmitres == XMIT_ERROR) {
03405       ast_log(LOG_WARNING, "Transmit error :: Cancelling transmission on Call ID %s\n", pkt->owner->callid);
03406       append_history(pkt->owner, "XmitErr", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
03407    } else 
03408       append_history(pkt->owner, "MaxRetries", "%s", pkt->is_fatal ? "(Critical)" : "(Non-critical)");
03409       
03410    pkt->retransid = -1;
03411 
03412    if (pkt->is_fatal) {
03413       while(pkt->owner->owner && ast_channel_trylock(pkt->owner->owner)) {
03414          sip_pvt_unlock(pkt->owner);   /* SIP_PVT, not channel */
03415          usleep(1);
03416          sip_pvt_lock(pkt->owner);
03417       }
03418 
03419       if (pkt->owner->owner && !pkt->owner->owner->hangupcause) 
03420          pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE;
03421       
03422       if (pkt->owner->owner) {
03423          sip_alreadygone(pkt->owner);
03424          ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet (see doc/sip-retransmit.txt).\n", pkt->owner->callid);
03425          ast_queue_hangup_with_cause(pkt->owner->owner, AST_CAUSE_PROTOCOL_ERROR);
03426          ast_channel_unlock(pkt->owner->owner);
03427       } else {
03428          /* If no channel owner, destroy now */
03429 
03430          /* Let the peerpoke system expire packets when the timer expires for poke_noanswer */
03431          if (pkt->method != SIP_OPTIONS && pkt->method != SIP_REGISTER) {
03432             pkt->owner->needdestroy = 1;
03433             sip_alreadygone(pkt->owner);
03434             append_history(pkt->owner, "DialogKill", "Killing this failed dialog immediately");
03435          }
03436       }
03437    }
03438 
03439    if (pkt->method == SIP_BYE) {
03440       /* We're not getting answers on SIP BYE's.  Tear down the call anyway. */
03441       if (pkt->owner->owner) 
03442          ast_channel_unlock(pkt->owner->owner);
03443       append_history(pkt->owner, "ByeFailure", "Remote peer doesn't respond to bye. Destroying call anyway.");
03444       pkt->owner->needdestroy = 1;
03445    }
03446 
03447    /* Remove the packet */
03448    for (prev = NULL, cur = pkt->owner->packets; cur; prev = cur, cur = cur->next) {
03449       if (cur == pkt) {
03450          UNLINK(cur, pkt->owner->packets, prev);
03451          sip_pvt_unlock(pkt->owner);
03452          if (pkt->owner)
03453             pkt->owner = dialog_unref(pkt->owner,"pkt is being freed, its dialog ref is dead now");
03454          if (pkt->data)
03455             ast_free(pkt->data);
03456          pkt->data = NULL;
03457          ast_free(pkt);
03458          return 0;
03459       }
03460    }
03461    /* error case */
03462    ast_log(LOG_WARNING, "Weird, couldn't find packet owner!\n");
03463    sip_pvt_unlock(pkt->owner);
03464    return 0;
03465 }

static int scheduler_process_request_queue ( const void *  data  )  [static]

Definition at line 20883 of file chan_sip.c.

References ast_channel_trylock, sip_pvt::owner, sip_pvt_lock, and sip_pvt_unlock.

Referenced by queue_request().

20884 {
20885    struct sip_pvt *p = (struct sip_pvt *) data;
20886    int recount = 0;
20887    int nounlock = 0;
20888    int lockretry;
20889 
20890    for (lockretry = 10; lockretry > 0; lockretry--) {
20891       sip_pvt_lock(p);
20892 
20893       /* lock the owner if it has one -- we may need it */
20894       /* because this is deadlock-prone, we need to try and unlock if failed */
20895       if (!p->owner || !ast_channel_trylock(p->owner)) {
20896          break;   /* locking succeeded */
20897       }
20898 
20899       if (lockretry != 1) {
20900          sip_pvt_unlock(p);
20901          /* Sleep for a very short amount of time */
20902          usleep(1);
20903       }
20904    }
20905 
20906    if (!lockretry) {
20907       int retry = !AST_LIST_EMPTY(&p->request_queue);
20908 
20909       /* we couldn't get the owner lock, which is needed to process
20910          the queued requests, so return a non-zero value, which will
20911          cause the scheduler to run this request again later if there
20912          still requests to be processed
20913       */
20914       sip_pvt_unlock(p);
20915       if (!retry) {
20916          dialog_unref(p, "The ref to a dialog passed to this sched callback is going out of scope; unref it.");
20917       }
20918       return retry;
20919    };
20920 
20921    process_request_queue(p, &recount, &nounlock);
20922    p->request_queue_sched_id = -1;
20923 
20924    if (p->owner && !nounlock) {
20925       ast_channel_unlock(p->owner);
20926    }
20927    sip_pvt_unlock(p);
20928 
20929    if (recount) {
20930       ast_update_use_count();
20931    }
20932 
20933    dialog_unref(p, "The ref to a dialog passed to this sched callback is going out of scope; unref it.");
20934 
20935    return 0;
20936 }

static int send_provisional_keepalive ( const void *  data  )  [static]

Definition at line 3792 of file chan_sip.c.

References send_provisional_keepalive_full().

Referenced by update_provisional_keepalive().

03792                                                         {
03793    struct sip_pvt *pvt = (struct sip_pvt *) data;
03794 
03795    return send_provisional_keepalive_full(pvt, 0);
03796 }

static int send_provisional_keepalive_full ( struct sip_pvt pvt,
int  with_sdp 
) [static]

Definition at line 3772 of file chan_sip.c.

References FALSE, sip_pvt::initreq, INV_COMPLETED, sip_pvt::invitestate, sip_pvt::last_provisional, msg, PROVIS_KEEPALIVE_TIMEOUT, S_OR, transmit_response(), transmit_response_with_sdp(), and XMIT_UNRELIABLE.

Referenced by send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().

03773 {
03774    const char *msg = NULL;
03775 
03776    if (!pvt->last_provisional || !strncasecmp(pvt->last_provisional, "100", 3)) {
03777       msg = "183 Session Progress";
03778    }
03779 
03780    if (pvt->invitestate < INV_COMPLETED) {
03781       if (with_sdp) {
03782          transmit_response_with_sdp(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq, XMIT_UNRELIABLE, FALSE);
03783       } else {
03784          transmit_response(pvt, S_OR(msg, pvt->last_provisional), &pvt->initreq);
03785       }
03786       return PROVIS_KEEPALIVE_TIMEOUT;
03787    }
03788 
03789    return 0;
03790 }

static int send_provisional_keepalive_with_sdp ( const void *  data  )  [static]

Definition at line 3798 of file chan_sip.c.

References send_provisional_keepalive_full().

Referenced by update_provisional_keepalive().

03798                                                                  {
03799    struct sip_pvt *pvt = (void *)data;
03800 
03801    return send_provisional_keepalive_full(pvt, 1);
03802 }

static int send_request ( struct sip_pvt p,
struct sip_request req,
enum xmittype  reliable,
int  seqno 
) [static]

Send SIP Request to the other part of the dialogue.

Definition at line 3850 of file chan_sip.c.

References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_free, ast_inet_ntoa(), ast_test_flag, ast_verbose, sip_request::data, sip_pvt::do_history, sip_pvt::flags, get_header(), sip_proxy::ip, sip_request::len, sip_request::method, sip_pvt::outboundproxy, parse_copy(), sip_pvt::recv, sip_request::rlPart1, sip_pvt::sa, sip_debug_test_pvt(), sip_methods, SIP_NAT_ROUTE, ast_str::str, and XMIT_CRITICAL.

03851 {
03852    int res;
03853 
03854    /* If we have an outbound proxy, reset peer address 
03855       Only do this once.
03856    */
03857    if (p->outboundproxy) {
03858       p->sa = p->outboundproxy->ip;
03859    }
03860 
03861    add_blank(req);
03862    if (sip_debug_test_pvt(p)) {
03863       if (ast_test_flag(&p->flags[0], SIP_NAT_ROUTE))
03864          ast_verbose("%sTransmitting (NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port), req->data->str);
03865       else
03866          ast_verbose("%sTransmitting (no NAT) to %s:%d:\n%s\n---\n", reliable ? "Reliably " : "", ast_inet_ntoa(p->sa.sin_addr), ntohs(p->sa.sin_port), req->data->str);
03867    }
03868    if (p->do_history) {
03869       struct sip_request tmp = { .rlPart1 = 0, };
03870       parse_copy(&tmp, req);
03871       append_history(p, reliable ? "TxReqRel" : "TxReq", "%s / %s - %s", tmp.data->str, get_header(&tmp, "CSeq"), sip_methods[tmp.method].text);
03872       ast_free(tmp.data);
03873    }
03874    res = (reliable) ?
03875       __sip_reliable_xmit(p, seqno, 0, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
03876       __sip_xmit(p, req->data, req->len);
03877    if (req->data) {
03878       ast_free(req->data);
03879       req->data = NULL;
03880    }
03881    return res;
03882 }

static int send_response ( struct sip_pvt p,
struct sip_request req,
enum xmittype  reliable,
int  seqno 
) [static]

Transmit response on SIP request.

Definition at line 3813 of file chan_sip.c.

References __sip_reliable_xmit(), __sip_xmit(), add_blank(), append_history, ast_free, ast_inet_ntoa(), AST_SCHED_DEL_UNREF, ast_verbose, sip_request::data, dialog_unref(), sip_pvt::do_history, get_header(), sip_pvt::initreq, sip_request::len, sip_request::method, parse_copy(), sip_pvt::provisional_keepalive_sched_id, REQ_OFFSET_TO_STR, sip_request::rlPart1, sip_request::rlPart2, sched, sip_debug_test_pvt(), SIP_INVITE, sip_methods, sip_nat_mode(), sip_real_dst(), SIP_RESPONSE, SIP_UNKNOWN, ast_str::str, cfsip_methods::text, and XMIT_CRITICAL.

03814 {
03815    int res;
03816 
03817    add_blank(req);
03818    if (sip_debug_test_pvt(p)) {
03819       const struct sockaddr_in *dst = sip_real_dst(p);
03820 
03821       ast_verbose("\n<--- %sTransmitting (%s) to %s:%d --->\n%s\n<------------>\n",
03822          reliable ? "Reliably " : "", sip_nat_mode(p),
03823          ast_inet_ntoa(dst->sin_addr),
03824          ntohs(dst->sin_port), req->data->str);
03825    }
03826    if (p->do_history) {
03827       struct sip_request tmp = { .rlPart1 = 0, };
03828       parse_copy(&tmp, req);
03829       append_history(p, reliable ? "TxRespRel" : "TxResp", "%s / %s - %s", tmp.data->str, get_header(&tmp, "CSeq"), 
03830          (tmp.method == SIP_RESPONSE || tmp.method == SIP_UNKNOWN) ? REQ_OFFSET_TO_STR(&tmp, rlPart2) : sip_methods[tmp.method].text);
03831       ast_free(tmp.data);
03832    }
03833 
03834    /* If we are sending a final response to an INVITE, stop retransmitting provisional responses */
03835    if (p->initreq.method == SIP_INVITE && reliable == XMIT_CRITICAL) {
03836       AST_SCHED_DEL_UNREF(sched, p->provisional_keepalive_sched_id, dialog_unref(p, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr"));
03837    }
03838 
03839    res = (reliable) ?
03840        __sip_reliable_xmit(p, seqno, 1, req->data, req->len, (reliable == XMIT_CRITICAL), req->method) :
03841       __sip_xmit(p, req->data, req->len);
03842    ast_free(req->data);
03843    req->data = NULL;
03844    if (res > 0)
03845       return 0;
03846    return res;
03847 }

static int set_address_from_contact ( struct sip_pvt pvt  )  [static]

Change the other partys IP address based on given contact.

Definition at line 11413 of file chan_sip.c.

References __set_address_from_contact(), ast_test_flag, sip_pvt::flags, sip_pvt::fullcontact, sip_pvt::recv, sip_pvt::sa, SIP_NAT_ROUTE, SIP_TRANSPORT_TLS, sip_pvt::socket, and sip_socket::type.

Referenced by handle_response_invite().

11414 {
11415    if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) {
11416       /* NAT: Don't trust the contact field.  Just use what they came to us
11417          with. */
11418       pvt->sa = pvt->recv;
11419       return 0;
11420    }
11421 
11422    return __set_address_from_contact(pvt->fullcontact, &pvt->sa, pvt->socket.type == SIP_TRANSPORT_TLS ? 1 : 0);
11423 }

static void set_destination ( struct sip_pvt p,
char *  uri 
) [static]

Set destination from SIP URI.

Definition at line 8571 of file chan_sip.c.

References ahp, ast_copy_string(), ast_gethostbyname(), ast_inet_ntoa(), ast_log(), ast_verbose, sip_request::debug, hostname, hp, LOG_WARNING, sip_pvt::sa, sip_debug_test_pvt(), and STANDARD_SIP_PORT.

Referenced by reqprep().

08572 {
08573    char *h, *maddr, hostname[256];
08574    int port, hn;
08575    struct hostent *hp;
08576    struct ast_hostent ahp;
08577    int debug=sip_debug_test_pvt(p);
08578 
08579    /* Parse uri to h (host) and port - uri is already just the part inside the <> */
08580    /* general form we are expecting is sip[s]:username[:password][;parameter]@host[:port][;...] */
08581 
08582    if (debug)
08583       ast_verbose("set_destination: Parsing <%s> for address/port to send to\n", uri);
08584 
08585    /* Find and parse hostname */
08586    h = strchr(uri, '@');
08587    if (h)
08588       ++h;
08589    else {
08590       h = uri;
08591       if (!strncasecmp(h, "sip:", 4))
08592          h += 4;
08593       else if (!strncasecmp(h, "sips:", 5))
08594          h += 5;
08595    }
08596    hn = strcspn(h, ":;>") + 1;
08597    if (hn > sizeof(hostname)) 
08598       hn = sizeof(hostname);
08599    ast_copy_string(hostname, h, hn);
08600    /* XXX bug here if string has been trimmed to sizeof(hostname) */
08601    h += hn - 1;
08602 
08603    /* Is "port" present? if not default to STANDARD_SIP_PORT */
08604    if (*h == ':') {
08605       /* Parse port */
08606       ++h;
08607       port = strtol(h, &h, 10);
08608    }
08609    else
08610       port = STANDARD_SIP_PORT;
08611 
08612    /* Got the hostname:port - but maybe there's a "maddr=" to override address? */
08613    maddr = strstr(h, "maddr=");
08614    if (maddr) {
08615       maddr += 6;
08616       hn = strspn(maddr, "0123456789.") + 1;
08617       if (hn > sizeof(hostname))
08618          hn = sizeof(hostname);
08619       ast_copy_string(hostname, maddr, hn);
08620    }
08621    
08622    hp = ast_gethostbyname(hostname, &ahp);
08623    if (hp == NULL)  {
08624       ast_log(LOG_WARNING, "Can't find address for host '%s'\n", hostname);
08625       return;
08626    }
08627    p->sa.sin_family = AF_INET;
08628    memcpy(&p->sa.sin_addr, hp->h_addr, sizeof(p->sa.sin_addr));
08629    p->sa.sin_port = htons(port);
08630    if (debug)
08631       ast_verbose("set_destination: set destination to %s, port %d\n", ast_inet_ntoa(p->sa.sin_addr), port);
08632 }

static void set_insecure_flags ( struct ast_flags flags,
const char *  value,
int  lineno 
) [static]

Parse insecure= setting in sip.conf and set flags according to setting.

Definition at line 22313 of file chan_sip.c.

References ast_copy_string(), ast_false(), ast_log(), ast_set_flag, ast_strlen_zero(), buf, ast_channel::flags, LOG_WARNING, ast_channel::next, SIP_INSECURE_INVITE, SIP_INSECURE_PORT, and strsep().

Referenced by get_insecure_variable_from_config(), and handle_common_options().

22314 {
22315    if (ast_strlen_zero(value))
22316       return;
22317 
22318    if (!ast_false(value)) {
22319       char buf[64];
22320       char *word, *next;
22321 
22322       ast_copy_string(buf, value, sizeof(buf));
22323       next = buf;
22324       while ((word = strsep(&next, ","))) {
22325          if (!strcasecmp(word, "port"))
22326             ast_set_flag(&flags[0], SIP_INSECURE_PORT);
22327          else if (!strcasecmp(word, "invite"))
22328             ast_set_flag(&flags[0], SIP_INSECURE_INVITE);
22329          else
22330             ast_log(LOG_WARNING, "Unknown insecure mode '%s' on line %d\n", value, lineno);
22331       }
22332    }
22333 }

static void set_nonce_randdata ( struct sip_pvt p,
int  forceupdate 
) [static]

builds the sip_pvt's randdata field which is used for the nonce challenge. When forceupdate is not set, the nonce is only updated if the current one is stale. In this case, a stalenonce is one which has already received a response, if a nonce has not received a response it is not always necessary or beneficial to create a new one.

Definition at line 11758 of file chan_sip.c.

References ast_random(), ast_string_field_build, ast_strlen_zero(), sip_pvt::randdata, and sip_pvt::stalenonce.

Referenced by check_auth(), and transmit_fake_auth_response().

11759 {
11760    if (p->stalenonce || forceupdate || ast_strlen_zero(p->randdata)) {
11761       ast_string_field_build(p, randdata, "%08lx", ast_random()); /* Create nonce for challenge */
11762       p->stalenonce = 0;
11763    }
11764 }

static void set_peer_defaults ( struct sip_peer peer  )  [static]

Set peer defaults before configuring specific configurations.

Definition at line 22665 of file chan_sip.c.

References sip_peer::addr, sip_peer::allowtransfer, ast_copy_flags, sip_peer::autoframing, sip_peer::call_limit, sip_peer::callgroup, sip_peer::capability, sip_peer::cid_name, sip_peer::cid_num, clear_peer_mailboxes(), sip_peer::context, sip_peer::defaddr, default_prefs, sip_peer::expire, sip_peer::flags, sip_peer::fromdomain, sip_peer::fromuser, global_flags, sip_peer::language, sip_peer::maxcallbitrate, sip_peer::maxms, sip_peer::md5secret, sip_peer::mohinterpret, sip_peer::mohsuggest, sip_peer::pickupgroup, sip_peer::pokeexpire, sip_peer::prefs, sip_peer::qualifyfreq, sip_peer::regexten, sip_peer::rtpholdtimeout, sip_peer::rtpkeepalive, sip_peer::rtptimeout, sip_peer::secret, set_socket_transport(), SIP_FLAGS_TO_COPY, SIP_PAGE2_FLAGS_TO_COPY, SIP_TRANSPORT_UDP, SIP_TYPE_PEER, sip_peer::socket, sip_st_cfg::st_max_se, sip_st_cfg::st_min_se, sip_st_cfg::st_mode_oper, sip_st_cfg::st_ref, STANDARD_SIP_PORT, sip_peer::stimer, sip_peer::subscribecontext, sip_peer::t38_maxdatagram, sip_peer::timer_b, sip_peer::timer_t1, sip_peer::type, and sip_peer::vmexten.

Referenced by build_peer(), and temp_peer().

22666 {
22667    if (peer->expire == 0) {
22668       /* Don't reset expire or port time during reload 
22669          if we have an active registration 
22670       */
22671       peer->expire = -1;
22672       peer->pokeexpire = -1;
22673       peer->addr.sin_port = htons(STANDARD_SIP_PORT);
22674       set_socket_transport(&peer->socket, SIP_TRANSPORT_UDP);
22675    }
22676    peer->type = SIP_TYPE_PEER;
22677    ast_copy_flags(&peer->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
22678    ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
22679    strcpy(peer->context, default_context);
22680    strcpy(peer->subscribecontext, default_subscribecontext);
22681    strcpy(peer->language, default_language);
22682    strcpy(peer->mohinterpret, default_mohinterpret);
22683    strcpy(peer->mohsuggest, default_mohsuggest);
22684    peer->addr.sin_family = AF_INET;
22685    peer->defaddr.sin_family = AF_INET;
22686    peer->capability = global_capability;
22687    peer->maxcallbitrate = default_maxcallbitrate;
22688    peer->rtptimeout = global_rtptimeout;
22689    peer->rtpholdtimeout = global_rtpholdtimeout;
22690    peer->rtpkeepalive = global_rtpkeepalive;
22691    peer->allowtransfer = global_allowtransfer;
22692    peer->autoframing = global_autoframing;
22693    peer->t38_maxdatagram = global_t38_maxdatagram;
22694    peer->qualifyfreq = global_qualifyfreq;
22695    if (global_callcounter)
22696       peer->call_limit=999;
22697    strcpy(peer->vmexten, default_vmexten);
22698    peer->secret[0] = '\0';
22699    peer->md5secret[0] = '\0';
22700    peer->cid_num[0] = '\0';
22701    peer->cid_name[0] = '\0';
22702    peer->fromdomain[0] = '\0';
22703    peer->fromuser[0] = '\0';
22704    peer->regexten[0] = '\0';
22705    peer->callgroup = 0;
22706    peer->pickupgroup = 0;
22707    peer->maxms = default_qualify;
22708    peer->prefs = default_prefs;
22709    peer->stimer.st_mode_oper = global_st_mode;  /* Session-Timers */
22710    peer->stimer.st_ref = global_st_refresher;
22711    peer->stimer.st_min_se = global_min_se;
22712    peer->stimer.st_max_se = global_max_se;
22713    peer->timer_t1 = global_t1;
22714    peer->timer_b = global_timer_b;
22715    clear_peer_mailboxes(peer);
22716 }

static void set_socket_transport ( struct sip_socket socket,
int  transport 
) [static]

Definition at line 11214 of file chan_sip.c.

References ao2_ref, sip_socket::fd, sip_request::socket, sip_socket::tcptls_session, and sip_socket::type.

Referenced by _sip_tcp_helper_thread(), build_peer(), create_addr(), expire_register(), get_transport_pvt(), parse_moved_contact(), parse_register_contact(), set_peer_defaults(), sip_alloc(), sip_request_call(), sip_send_mwi_to_peer(), sipsock_read(), and transmit_register().

11215 {
11216    /* if the transport type changes, clear all socket data */
11217    if (socket->type != transport) {
11218       socket->fd = -1;
11219       socket->type = transport;
11220       if (socket->tcptls_session) {
11221          ao2_ref(socket->tcptls_session, -1);
11222          socket->tcptls_session = NULL;
11223       }
11224    }
11225 }

static void set_t38_capabilities ( struct sip_pvt p  )  [static]

Set the global T38 capabilities on a SIP dialog structure.

Definition at line 4693 of file chan_sip.c.

References ast_test_flag, ast_udptl_set_error_correction_scheme(), sip_pvt::flags, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_T38SUPPORT_UDPTL, SIP_PAGE2_T38SUPPORT_UDPTL_FEC, SIP_PAGE2_T38SUPPORT_UDPTL_REDUNDANCY, sip_pvt::udptl, UDPTL_ERROR_CORRECTION_FEC, UDPTL_ERROR_CORRECTION_NONE, and UDPTL_ERROR_CORRECTION_REDUNDANCY.

Referenced by check_peer_ok(), create_addr_from_peer(), handle_request_invite(), and sip_alloc().

static int show_channels_cb ( void *  __cur,
void *  __arg,
int  flags 
) [static]

callback for show channel|subscription

Definition at line 15381 of file chan_sip.c.

References ast_cli(), ast_extension_state2str(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_str_alloca, ast_test_flag, sip_pvt::callid, sip_pvt::cid_num, cli_yesno(), sip_pvt::expiry, __show_chan_arg::fd, sip_pvt::flags, FORMAT, FORMAT4, sip_pvt::lastmsg, sip_pvt::laststate, ast_channel::nativeformats, sip_pvt::needdestroy, NONE, __show_chan_arg::numchans, sip_pvt::owner, peer_mailboxes_to_str(), sip_pvt::refer, referstatus2str(), sip_pvt::relatedpeer, S_OR, SIP_PAGE2_CALL_ONHOLD, sip_real_dst(), SIPBUFSIZE, sip_refer::status, ast_str::str, sip_pvt::subscribed, sip_pvt::subscribeuri, subscription_type2str(), __show_chan_arg::subscriptions, and sip_pvt::username.

Referenced by sip_show_channels().

15382 {
15383    struct sip_pvt *cur = __cur;
15384    struct __show_chan_arg *arg = __arg;
15385    const struct sockaddr_in *dst = sip_real_dst(cur);
15386    
15387    /* XXX indentation preserved to reduce diff. Will be fixed later */
15388    if (cur->subscribed == NONE && !arg->subscriptions) {
15389       /* set if SIP transfer in progress */
15390       const char *referstatus = cur->refer ? referstatus2str(cur->refer->status) : "";
15391       char formatbuf[SIPBUFSIZE/2];
15392       
15393       ast_cli(arg->fd, FORMAT, ast_inet_ntoa(dst->sin_addr), 
15394             S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
15395             cur->callid, 
15396             ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0),
15397             cli_yesno(ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD)),
15398             cur->needdestroy ? "(d)" : "",
15399             cur->lastmsg ,
15400             referstatus
15401          );
15402       arg->numchans++;
15403    }
15404    if (cur->subscribed != NONE && arg->subscriptions) {
15405       struct ast_str *mailbox_str = ast_str_alloca(512);
15406       if (cur->subscribed == MWI_NOTIFICATION && cur->relatedpeer)
15407          peer_mailboxes_to_str(&mailbox_str, cur->relatedpeer);
15408       ast_cli(arg->fd, FORMAT4, ast_inet_ntoa(dst->sin_addr),
15409             S_OR(cur->username, S_OR(cur->cid_num, "(None)")), 
15410                cur->callid,
15411             /* the 'complete' exten/context is hidden in the refer_to field for subscriptions */
15412             cur->subscribed == MWI_NOTIFICATION ? "--" : cur->subscribeuri,
15413             cur->subscribed == MWI_NOTIFICATION ? "<none>" : ast_extension_state2str(cur->laststate), 
15414             subscription_type2str(cur->subscribed),
15415             cur->subscribed == MWI_NOTIFICATION ? S_OR(mailbox_str->str, "<none>") : "<none>",
15416             cur->expiry
15417          );
15418       arg->numchans++;
15419    }
15420    return 0;   /* don't care, we scan all channels */
15421 }

static int show_chanstats_cb ( void *  __cur,
void *  __arg,
int  flags 
) [static]

Callback for show_chanstats.

Definition at line 15060 of file chan_sip.c.

References ast_cli(), ast_inet_ntoa(), ast_rtp_get_qosvalue(), AST_RTP_RXCOUNT, AST_RTP_RXJITTER, AST_RTP_RXPLOSS, AST_RTP_TXCOUNT, AST_RTP_TXJITTER, AST_RTP_TXPLOSS, ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), sip_pvt::callid, ast_channel::cdr, __show_chan_arg::fd, FORMAT, sip_pvt::invitestate, invitestate2string, NONE, __show_chan_arg::numchans, sip_pvt::owner, sip_pvt::rtp, sip_pvt::sa, ast_cdr::start, and sip_pvt::subscribed.

Referenced by sip_show_channelstats().

15061 {
15062 #define FORMAT2 "%-15.15s  %-11.11s  %-8.8s %-10.10s  %-10.10s (     %%) %-6.6s %-10.10s  %-10.10s (     %%) %-6.6s\n"
15063 #define FORMAT  "%-15.15s  %-11.11s  %-8.8s %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.6u %-10.10u%-1.1s %-10.10u (%5.2f%%) %-6.6u\n"
15064    struct sip_pvt *cur = __cur;
15065    unsigned int rxcount, txcount, rxploss, txploss;
15066    char durbuf[10];
15067         int duration;
15068         int durh, durm, durs;
15069    struct ast_channel *c = cur->owner;
15070    struct __show_chan_arg *arg = __arg;
15071    int fd = arg->fd;
15072 
15073 
15074    if (cur->subscribed != NONE) /* Subscriptions */
15075       return 0;   /* don't care, we scan all channels */
15076 
15077    if (!cur->rtp) {
15078       if (sipdebug)
15079          ast_cli(fd, "%-15.15s  %-11.11s (inv state: %s) -- %s\n", ast_inet_ntoa(cur->sa.sin_addr), cur->callid, invitestate2string[cur->invitestate].desc, "-- No RTP active");
15080       return 0;   /* don't care, we scan all channels */
15081    }
15082    rxcount = ast_rtp_get_qosvalue(cur->rtp, AST_RTP_RXCOUNT);
15083    txcount = ast_rtp_get_qosvalue(cur->rtp, AST_RTP_TXCOUNT);
15084    rxploss = ast_rtp_get_qosvalue(cur->rtp, AST_RTP_RXPLOSS);
15085    txploss = ast_rtp_get_qosvalue(cur->rtp, AST_RTP_TXPLOSS);
15086 
15087    /* Find the duration of this channel */
15088    if (c && c->cdr && !ast_tvzero(c->cdr->start)) {
15089       duration = (int)(ast_tvdiff_ms(ast_tvnow(), c->cdr->start) / 1000);
15090       durh = duration / 3600;
15091       durm = (duration % 3600) / 60;
15092       durs = duration % 60;
15093       snprintf(durbuf, sizeof(durbuf), "%02d:%02d:%02d", durh, durm, durs);
15094    } else {
15095       durbuf[0] = '\0';
15096    }
15097    /* Print stats for every call with RTP */
15098    ast_cli(fd, FORMAT, 
15099       ast_inet_ntoa(cur->sa.sin_addr), 
15100       cur->callid, 
15101       durbuf,
15102       rxcount > (unsigned int) 100000 ? (unsigned int) (rxcount)/(unsigned int) 1000 : rxcount,
15103       rxcount > (unsigned int) 100000 ? "K":" ",
15104       rxploss,
15105       (rxcount + rxploss) > 0 ? (double) rxploss / (rxcount + rxploss) * 100 : 0,
15106       ast_rtp_get_qosvalue(cur->rtp, AST_RTP_RXJITTER),
15107       txcount > (unsigned int) 100000 ? (unsigned int) (txcount)/(unsigned int) 1000 : txcount,
15108       txcount > (unsigned int) 100000 ? "K":" ",
15109       txploss,
15110       txcount > 0 ? (double) txploss / txcount * 100 : 0,
15111       ast_rtp_get_qosvalue(cur->rtp, AST_RTP_TXJITTER)
15112    );
15113    arg->numchans++;
15114 
15115    return 0;   /* don't care, we scan all channels */
15116 }

static int sip_addheader ( struct ast_channel chan,
void *  data 
) [static]

Add a SIP header to an outbound INVITE.

Definition at line 24434 of file chan_sip.c.

References ast_channel_lock, ast_channel_unlock, ast_debug, ast_get_encoded_str(), ast_log(), ast_strlen_zero(), chan, FALSE, inbuf(), LOG_WARNING, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and TRUE.

Referenced by load_module().

24435 {
24436    int no = 0;
24437    int ok = FALSE;
24438    char varbuf[30];
24439    char *inbuf = data, *subbuf;
24440    
24441    if (ast_strlen_zero(inbuf)) {
24442       ast_log(LOG_WARNING, "This application requires the argument: Header\n");
24443       return 0;
24444    }
24445    ast_channel_lock(chan);
24446 
24447    /* Check for headers */
24448    while (!ok && no <= 50) {
24449       no++;
24450       snprintf(varbuf, sizeof(varbuf), "__SIPADDHEADER%.2d", no);
24451 
24452       /* Compare without the leading underscores */
24453       if ((pbx_builtin_getvar_helper(chan, (const char *) varbuf + 2) == (const char *) NULL)) {
24454          ok = TRUE;
24455       }
24456    }
24457    if (ok) {
24458       size_t len = strlen(inbuf);
24459       subbuf = alloca(len + 1);
24460       ast_get_encoded_str(inbuf, subbuf, len + 1);
24461       pbx_builtin_setvar_helper(chan, varbuf, subbuf);
24462       if (sipdebug) {
24463          ast_debug(1, "SIP Header added \"%s\" as %s\n", inbuf, varbuf);
24464       }
24465    } else {
24466       ast_log(LOG_WARNING, "Too many SIP headers added, max 50\n");
24467    }
24468    ast_channel_unlock(chan);
24469    return 0;
24470 }

static struct sip_pvt * sip_alloc ( ast_string_field  callid,
struct sockaddr_in *  sin,
int  useglobal_nat,
const int  intended_method,
struct sip_request req 
) [static]

Allocate sip_pvt structure, set defaults and link in the container. Returns a reference to the object so whoever uses it later must remember to release the reference.

Definition at line 6737 of file chan_sip.c.

References ao2_t_alloc, ao2_t_link, ao2_t_ref, ast_copy_flags, ast_debug, AST_LIST_HEAD_INIT_NOLOCK, ast_log(), ast_random(), ast_rtp_codec_setpref(), AST_RTP_DTMF, ast_rtp_new_with_bindaddr(), ast_rtp_set_rtpholdtimeout(), ast_rtp_set_rtpkeepalive(), ast_rtp_set_rtptimeout(), ast_rtp_setdtmf(), ast_rtp_setdtmfcompensate(), ast_rtp_setqos(), ast_sip_ouraddrfor(), ast_string_field_init, ast_string_field_set, ast_test_flag, ast_udptl_new_with_bindaddr(), ast_udptl_setqos(), ast_variables_destroy(), build_callid_pvt(), build_via(), context, default_prefs, dialogs, do_setnat(), errno, sip_pvt::fromdomain, global_flags, INITIAL_CSEQ, io, LOG_WARNING, make_our_tag(), mohinterpret, mohsuggest, NONE, parkinglot, sched, set_socket_transport(), set_t38_capabilities(), sip_destroy_fn(), SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_RFC2833, SIP_FLAGS_TO_COPY, sip_methods, SIP_NAT, SIP_NAT_ROUTE, SIP_OPTIONS, SIP_PAGE2_FLAGS_TO_COPY, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_TEXTSUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_REGISTER, SIP_TRANSPORT_UDP, sip_request::socket, cfsip_methods::text, TRUE, and sip_socket::type.

Referenced by find_call(), manager_sipnotify(), sip_cli_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), and transmit_register().

06739 {
06740    struct sip_pvt *p;
06741 
06742    if (!(p = ao2_t_alloc(sizeof(*p), sip_destroy_fn, "allocate a dialog(pvt) struct")))
06743       return NULL;
06744 
06745    if (ast_string_field_init(p, 512)) {
06746       ao2_t_ref(p, -1, "failed to string_field_init, drop p");
06747       return NULL;
06748    }
06749 
06750    if (req) {
06751       set_socket_transport(&p->socket, req->socket.type); /* Later in ast_sip_ouraddrfor we need this to choose the right ip and port for the specific transport */
06752    } else {
06753       set_socket_transport(&p->socket, SIP_TRANSPORT_UDP);
06754    }
06755 
06756    p->socket.fd = -1;
06757    p->method = intended_method;
06758    p->initid = -1;
06759    p->waitid = -1;
06760    p->autokillid = -1;
06761    p->request_queue_sched_id = -1;
06762    p->provisional_keepalive_sched_id = -1;
06763    p->t38id = -1;
06764    p->subscribed = NONE;
06765    p->stateid = -1;
06766    p->sessionversion_remote = -1;
06767    p->session_modify = TRUE;
06768    p->stimer = NULL;
06769    p->prefs = default_prefs;     /* Set default codecs for this call */
06770 
06771    if (intended_method != SIP_OPTIONS) {  /* Peerpoke has it's own system */
06772       p->timer_t1 = global_t1;   /* Default SIP retransmission timer T1 (RFC 3261) */
06773       p->timer_b = global_timer_b;  /* Default SIP transaction timer B (RFC 3261) */
06774    }
06775 
06776    if (!sin)
06777       p->ourip = internip;
06778    else {
06779       p->sa = *sin;
06780       ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip, p);
06781    }
06782 
06783    /* Copy global flags to this PVT at setup. */
06784    ast_copy_flags(&p->flags[0], &global_flags[0], SIP_FLAGS_TO_COPY);
06785    ast_copy_flags(&p->flags[1], &global_flags[1], SIP_PAGE2_FLAGS_TO_COPY);
06786 
06787    p->do_history = recordhistory;
06788 
06789    p->branch = ast_random();  
06790    make_our_tag(p->tag, sizeof(p->tag));
06791    p->ocseq = INITIAL_CSEQ;
06792 
06793    if (sip_methods[intended_method].need_rtp) {
06794       p->rtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
06795       /* If the global videosupport flag is on, we always create a RTP interface for video */
06796       if (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT))
06797          p->vrtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
06798       if (ast_test_flag(&p->flags[1], SIP_PAGE2_TEXTSUPPORT))
06799          p->trtp = ast_rtp_new_with_bindaddr(sched, io, 1, 0, bindaddr.sin_addr);
06800       if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT))
06801          p->udptl = ast_udptl_new_with_bindaddr(sched, io, 0, bindaddr.sin_addr);
06802       if (!p->rtp|| (ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) && !p->vrtp) 
06803             || (ast_test_flag(&p->flags[1], SIP_PAGE2_TEXTSUPPORT) && !p->trtp)) {
06804          ast_log(LOG_WARNING, "Unable to create RTP audio %s%ssession: %s\n",
06805             ast_test_flag(&p->flags[1], SIP_PAGE2_VIDEOSUPPORT) ? "and video " : "",
06806             ast_test_flag(&p->flags[1], SIP_PAGE2_TEXTSUPPORT) ? "and text " : "", strerror(errno));
06807          if (p->chanvars) {
06808             ast_variables_destroy(p->chanvars);
06809             p->chanvars = NULL;
06810          }
06811          ao2_t_ref(p, -1, "failed to create RTP audio session, drop p");
06812          return NULL;
06813          p->t38_maxdatagram = global_t38_maxdatagram;
06814       }
06815       ast_rtp_setqos(p->rtp, global_tos_audio, global_cos_audio, "SIP RTP");
06816       ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
06817       ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
06818       ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout);
06819       ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout);
06820       ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive);
06821       if (p->vrtp) {
06822          ast_rtp_setqos(p->vrtp, global_tos_video, global_cos_video, "SIP VRTP");
06823          ast_rtp_setdtmf(p->vrtp, 0);
06824          ast_rtp_setdtmfcompensate(p->vrtp, 0);
06825          ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout);
06826          ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout);
06827          ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive);
06828       }
06829       if (p->trtp) {
06830          ast_rtp_setqos(p->trtp, global_tos_text, global_cos_text, "SIP TRTP");
06831          ast_rtp_setdtmf(p->trtp, 0);
06832          ast_rtp_setdtmfcompensate(p->trtp, 0);
06833       }
06834       if (p->udptl)
06835          ast_udptl_setqos(p->udptl, global_tos_audio, global_cos_audio);
06836       p->maxcallbitrate = default_maxcallbitrate;
06837       p->autoframing = global_autoframing;
06838       ast_rtp_codec_setpref(p->rtp, &p->prefs);
06839    }
06840 
06841    if (useglobal_nat && sin) {
06842       /* Setup NAT structure according to global settings if we have an address */
06843       ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT);
06844       p->recv = *sin;
06845       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
06846    }
06847 
06848    if (p->method != SIP_REGISTER)
06849       ast_string_field_set(p, fromdomain, default_fromdomain);
06850    build_via(p);
06851    if (!callid)
06852       build_callid_pvt(p);
06853    else
06854       ast_string_field_set(p, callid, callid);
06855    /* Assign default music on hold class */
06856    ast_string_field_set(p, mohinterpret, default_mohinterpret);
06857    ast_string_field_set(p, mohsuggest, default_mohsuggest);
06858    p->capability = global_capability;
06859    p->allowtransfer = global_allowtransfer;
06860    if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
06861        (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
06862       p->noncodeccapability |= AST_RTP_DTMF;
06863    if (p->udptl) {
06864       p->t38_maxdatagram = global_t38_maxdatagram;
06865       set_t38_capabilities(p);
06866    }
06867    ast_string_field_set(p, context, default_context);
06868    ast_string_field_set(p, parkinglot, default_parkinglot);
06869 
06870    AST_LIST_HEAD_INIT_NOLOCK(&p->request_queue);
06871 
06872    /* Add to active dialog list */
06873 
06874    ao2_t_link(dialogs, p, "link pvt into dialogs table");
06875    
06876    ast_debug(1, "Allocating new SIP dialog for %s - %s (%s)\n", callid ? callid : p->callid, sip_methods[intended_method].text, p->rtp ? "With RTP" : "No RTP");
06877    return p;
06878 }

static void sip_alreadygone ( struct sip_pvt dialog  )  [static]

Encapsulate setting of SIP_ALREADYGONE to be able to trace it with debugging.

Definition at line 2906 of file chan_sip.c.

References sip_pvt::alreadygone, ast_debug, and sip_pvt::callid.

Referenced by handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), retrans_pkt(), sip_indicate(), and sip_sipredirect().

02907 {
02908    ast_debug(3, "Setting SIP_ALREADYGONE on dialog %s\n", dialog->callid);
02909    dialog->alreadygone = 1;
02910 }

static int sip_answer ( struct ast_channel ast  )  [static]

sip_answer: Answer SIP call , send 200 OK on Invite Part of PBX interface

Definition at line 5779 of file chan_sip.c.

References ast_channel::_state, ast_debug, ast_rtp_new_source(), ast_set_flag, ast_setstate(), AST_STATE_UP, FALSE, ast_channel::name, SIP_PAGE2_DIALOG_ESTABLISHED, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, transmit_response_with_sdp(), try_suggested_sip_codec(), and XMIT_CRITICAL.

05780 {
05781    int res = 0;
05782    struct sip_pvt *p = ast->tech_pvt;
05783 
05784    sip_pvt_lock(p);
05785    if (ast->_state != AST_STATE_UP) {
05786       try_suggested_sip_codec(p);   
05787 
05788       ast_setstate(ast, AST_STATE_UP);
05789       ast_debug(1, "SIP answering channel: %s\n", ast->name);
05790       ast_rtp_new_source(p->rtp);
05791       res = transmit_response_with_sdp(p, "200 OK", &p->initreq, XMIT_CRITICAL, FALSE);
05792       ast_set_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
05793    }
05794    sip_pvt_unlock(p);
05795    return res;
05796 }

static int sip_call ( struct ast_channel ast,
char *  dest,
int  timeout 
) [static]

Initiate SIP call from PBX used from the dial() application.

Definition at line 4989 of file chan_sip.c.

References ast_channel::_state, sip_invite_param::addsipheaders, AST_CAUSE_USER_BUSY, ast_debug, AST_FORMAT_AUDIO_MASK, AST_LIST_TRAVERSE, ast_log(), AST_SCHED_REPLACE_UNREF, ast_set_flag, AST_STATE_DOWN, AST_STATE_RESERVED, ast_string_field_set, ast_translate_available_formats(), ast_var_name(), ast_var_value(), auto_congest(), buf, sip_pvt::callingpres, sip_pvt::capability, ast_channel::cid, cid_name, sip_pvt::cid_name, ast_callerid::cid_pres, dialog_ref(), dialog_unref(), ast_var_t::entries, sip_pvt::flags, ast_channel::hangupcause, INC_CALL_RINGING, sip_pvt::initid, INV_CALLING, sip_pvt::invitestate, sip_pvt::jointcapability, sip_pvt::jointnoncodeccapability, LOG_WARNING, ast_channel::name, sip_pvt::noncodeccapability, sip_pvt::options, sip_pvt::prefcodec, sip_invite_param::replaces, sched, SIP_INVITE, SIP_OUTGOING, SIPBUFSIZE, ast_channel::tech_pvt, sip_pvt::timer_b, sip_invite_param::transfer, transmit_invite(), update_call_counter(), sip_invite_param::uri_options, sip_pvt::username, ast_channel::varshead, sip_invite_param::vxml_url, and XMIT_ERROR.

04990 {
04991    int res;
04992    struct sip_pvt *p = ast->tech_pvt;  /* chan is locked, so the reference cannot go away */
04993    struct varshead *headp;
04994    struct ast_var_t *current;
04995    const char *referer = NULL;   /* SIP referrer */
04996 
04997    if ((ast->_state != AST_STATE_DOWN) && (ast->_state != AST_STATE_RESERVED)) {
04998       ast_log(LOG_WARNING, "sip_call called on %s, neither down nor reserved\n", ast->name);
04999       return -1;
05000    }
05001 
05002    /* Check whether there is vxml_url, distinctive ring variables */
05003    headp=&ast->varshead;
05004    AST_LIST_TRAVERSE(headp, current, entries) {
05005       /* Check whether there is a VXML_URL variable */
05006       if (!p->options->vxml_url && !strcasecmp(ast_var_name(current), "VXML_URL")) {
05007          p->options->vxml_url = ast_var_value(current);
05008       } else if (!p->options->uri_options && !strcasecmp(ast_var_name(current), "SIP_URI_OPTIONS")) {
05009          p->options->uri_options = ast_var_value(current);
05010       } else if (!p->options->addsipheaders && !strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
05011          /* Check whether there is a variable with a name starting with SIPADDHEADER */
05012          p->options->addsipheaders = 1;
05013       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER")) {
05014          /* This is a transfered call */
05015          p->options->transfer = 1;
05016       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REFERER")) {
05017          /* This is the referrer */
05018          referer = ast_var_value(current);
05019       } else if (!strcasecmp(ast_var_name(current), "SIPTRANSFER_REPLACES")) {
05020          /* We're replacing a call. */
05021          p->options->replaces = ast_var_value(current);
05022       }
05023    }
05024 
05025    res = 0;
05026    ast_set_flag(&p->flags[0], SIP_OUTGOING);
05027 
05028    if (p->options->transfer) {
05029       char buf[SIPBUFSIZE/2];
05030 
05031       if (referer) {
05032          if (sipdebug)
05033             ast_debug(3, "Call for %s transfered by %s\n", p->username, referer);
05034          snprintf(buf, sizeof(buf)-1, "-> %s (via %s)", p->cid_name, referer);
05035       } else 
05036          snprintf(buf, sizeof(buf)-1, "-> %s", p->cid_name);
05037       ast_string_field_set(p, cid_name, buf);
05038    } 
05039    ast_debug(1, "Outgoing Call for %s\n", p->username);
05040 
05041    res = update_call_counter(p, INC_CALL_RINGING);
05042 
05043    if (res == -1) {
05044       ast->hangupcause = AST_CAUSE_USER_BUSY;
05045       return res;
05046    }
05047    p->callingpres = ast->cid.cid_pres;
05048    p->jointcapability = ast_translate_available_formats(p->capability, p->prefcodec);
05049    p->jointnoncodeccapability = p->noncodeccapability;
05050 
05051    /* If there are no audio formats left to offer, punt */
05052    if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
05053       ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username);
05054       res = -1;
05055    } else {
05056       int xmitres;
05057 
05058       xmitres = transmit_invite(p, SIP_INVITE, 1, 2);
05059       if (xmitres == XMIT_ERROR)
05060          return -1;
05061       p->invitestate = INV_CALLING;
05062    
05063       /* Initialize auto-congest time */
05064       AST_SCHED_REPLACE_UNREF(p->initid, sched, p->timer_b, auto_congest, p, 
05065                         dialog_unref(_data, "dialog ptr dec when SCHED_REPLACE del op succeeded"), 
05066                         dialog_unref(p, "dialog ptr dec when SCHED_REPLACE add failed"),
05067                         dialog_ref(p, "dialog ptr inc when SCHED_REPLACE add succeeded") );
05068    }
05069    return res;
05070 }

static int sip_cancel_destroy ( struct sip_pvt p  )  [static]

Cancel destruction of SIP dialog. Be careful as this also absorbs the reference - if you call it from within the scheduler, this might be the last reference.

Definition at line 3633 of file chan_sip.c.

References append_history, ast_sched_del(), sip_pvt::autokillid, dialog_unref(), and sched.

Referenced by cb_extensionstate(), handle_request_invite(), handle_request_subscribe(), handle_response(), handle_response_invite(), register_verify(), sip_hangup(), and sip_scheddestroy().

03634 {
03635    int res = 0;
03636    if (p->autokillid > -1) {
03637       int res3;
03638 
03639       if (!(res3 = ast_sched_del(sched, p->autokillid))) {
03640          append_history(p, "CancelDestroy", "");
03641          p->autokillid = -1;
03642          dialog_unref(p, "dialog unrefd because autokillid is de-sched'd");
03643       }
03644    }
03645    return res;
03646 }

static char * sip_cli_notify ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Cli command to send SIP notify to peer.

Definition at line 16083 of file chan_sip.c.

References ao2_t_link, ao2_t_unlink, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_log(), ast_set_flag, ast_sip_ouraddrfor(), ast_variable_browse(), build_callid_pvt(), build_via(), CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, ast_cli_entry::command, complete_sipnotify(), create_addr(), dialog_ref(), dialog_unlink_all(), dialog_unref(), dialogs, ast_cli_args::fd, sip_pvt::flags, ast_cli_args::line, LOG_WARNING, ast_cli_args::n, notify_types, sip_pvt::ourip, ast_cli_args::pos, sip_pvt::sa, sip_alloc(), SIP_NOTIFY, SIP_OUTGOING, sip_scheddestroy(), SIP_TRANS_TIMEOUT, transmit_notify_custom(), TRUE, ast_cli_entry::usage, and ast_cli_args::word.

16084 {
16085    struct ast_variable *varlist;
16086    int i;
16087 
16088    switch (cmd) {
16089    case CLI_INIT:
16090       e->command = "sip notify";
16091       e->usage =
16092          "Usage: sip notify <type> <peer> [<peer>...]\n"
16093          "       Send a NOTIFY message to a SIP peer or peers\n"
16094          "       Message types are defined in sip_notify.conf\n";
16095       return NULL;
16096    case CLI_GENERATE:
16097       return complete_sipnotify(a->line, a->word, a->pos, a->n);
16098    }
16099 
16100    if (a->argc < 4)
16101       return CLI_SHOWUSAGE;
16102 
16103    if (!notify_types) {
16104       ast_cli(a->fd, "No %s file found, or no types listed there\n", notify_config);
16105       return CLI_FAILURE;
16106    }
16107 
16108    varlist = ast_variable_browse(notify_types, a->argv[2]);
16109 
16110    if (!varlist) {
16111       ast_cli(a->fd, "Unable to find notify type '%s'\n", a->argv[2]);
16112       return CLI_FAILURE;
16113    }
16114 
16115    for (i = 3; i < a->argc; i++) {
16116       struct sip_pvt *p;
16117 
16118       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) {
16119          ast_log(LOG_WARNING, "Unable to build sip pvt data for notify (memory/socket error)\n");
16120          return CLI_FAILURE;
16121       }
16122 
16123       if (create_addr(p, a->argv[i], NULL, 1)) {
16124          /* Maybe they're not registered, etc. */
16125          dialog_unlink_all(p, TRUE, TRUE);
16126          dialog_unref(p, "unref dialog inside for loop" );
16127          /* sip_destroy(p); */
16128          ast_cli(a->fd, "Could not create address for '%s'\n", a->argv[i]);
16129          continue;
16130       }
16131 
16132       /* Notify is outgoing call */
16133       ast_set_flag(&p->flags[0], SIP_OUTGOING);
16134 
16135       /* Recalculate our side, and recalculate Call ID */
16136       ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip, p);
16137       build_via(p);
16138       ao2_t_unlink(dialogs, p, "About to change the callid -- remove the old name");
16139       build_callid_pvt(p);
16140       ao2_t_link(dialogs, p, "Linking in new name");
16141       ast_cli(a->fd, "Sending NOTIFY of type '%s' to '%s'\n", a->argv[2], a->argv[i]);
16142       dialog_ref(p, "bump the count of p, which transmit_sip_request will decrement.");
16143       sip_scheddestroy(p, SIP_TRANS_TIMEOUT);
16144       transmit_notify_custom(p, varlist);
16145    }
16146 
16147    return CLI_SUCCESS;
16148 }

static int sip_debug_test_addr ( const struct sockaddr_in *  addr  )  [inline, static]

See if we pass debug IP filter.

Definition at line 3064 of file chan_sip.c.

Referenced by check_peer_ok(), handle_request_do(), and sip_debug_test_pvt().

03065 {
03066    if (!sipdebug)
03067       return 0;
03068    if (debugaddr.sin_addr.s_addr) {
03069       if (((ntohs(debugaddr.sin_port) != 0)
03070          && (debugaddr.sin_port != addr->sin_port))
03071          || (debugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
03072          return 0;
03073    }
03074    return 1;
03075 }

static int sip_debug_test_pvt ( struct sip_pvt p  )  [inline, static]

Test PVT for debugging output.

Definition at line 3093 of file chan_sip.c.

References sip_debug_test_addr(), and sip_real_dst().

Referenced by __sip_destroy(), add_sdp(), build_route(), check_via(), do_register_auth(), get_also_info(), get_destination(), get_rdnis(), get_refer_info(), handle_incoming(), process_sdp(), process_sdp_a_audio(), process_sdp_a_text(), process_sdp_a_video(), receive_message(), retrans_pkt(), send_request(), send_response(), set_destination(), sip_scheddestroy(), sip_sendhtml(), sip_sendtext(), and transmit_register().

03094 {
03095    if (!sipdebug)
03096       return 0;
03097    return sip_debug_test_addr(sip_real_dst(p));
03098 }

static struct sip_pvt * sip_destroy ( struct sip_pvt p  )  [static]

Destroy SIP call structure. Make it return NULL so the caller can do things like foo = sip_destroy(foo); and reduce the chance of bugs due to dangling pointers.

Definition at line 5382 of file chan_sip.c.

References __sip_destroy(), ast_debug, sip_pvt::callid, and TRUE.

Referenced by sip_destroy_fn().

05383 {
05384    ast_debug(3, "Destroying SIP dialog %s\n", p->callid);
05385    __sip_destroy(p, TRUE, TRUE);
05386    return NULL;
05387 }

static void sip_destroy_fn ( void *  p  )  [static]

Definition at line 5372 of file chan_sip.c.

References sip_destroy().

Referenced by sip_alloc().

05373 {
05374    sip_destroy(p);
05375 }

static void sip_destroy_peer ( struct sip_peer peer  )  [static]

Destroy peer object from memory.

Definition at line 4264 of file chan_sip.c.

References ao2_ref, ast_atomic_fetchadd_int(), ast_debug, ast_dnsmgr_release(), ast_free_ha(), ast_variables_destroy(), sip_peer::auth, sip_peer::call, sip_peer::chanvars, clear_peer_mailboxes(), clear_realm_authentication(), dialog_unlink_all(), dialog_unref(), sip_peer::dnsmgr, FALSE, sip_peer::ha, sip_peer::is_realtime, sip_peer::mwipvt, sip_peer::name, sip_peer::outboundproxy, register_peer_exten(), sip_peer::selfdestruct, sip_peer::socket, sip_socket::tcptls_session, and TRUE.

Referenced by sip_destroy_peer_fn().

04265 {
04266    ast_debug(3, "Destroying SIP peer %s\n", peer->name);
04267    if (peer->outboundproxy)
04268       ao2_ref(peer->outboundproxy, -1);
04269    peer->outboundproxy = NULL;
04270 
04271    /* Delete it, it needs to disappear */
04272    if (peer->call) {
04273       dialog_unlink_all(peer->call, TRUE, TRUE);
04274       peer->call = dialog_unref(peer->call, "peer->call is being unset");
04275    }
04276    
04277 
04278    if (peer->mwipvt) {  /* We have an active subscription, delete it */
04279       dialog_unlink_all(peer->mwipvt, TRUE, TRUE);
04280       peer->mwipvt = dialog_unref(peer->mwipvt, "unreffing peer->mwipvt");
04281    }
04282    
04283    if (peer->chanvars) {
04284       ast_variables_destroy(peer->chanvars);
04285       peer->chanvars = NULL;
04286    }
04287    
04288    register_peer_exten(peer, FALSE);
04289    ast_free_ha(peer->ha);
04290    if (peer->selfdestruct)
04291       ast_atomic_fetchadd_int(&apeerobjs, -1);
04292    else if (peer->is_realtime) {
04293       ast_atomic_fetchadd_int(&rpeerobjs, -1);
04294       ast_debug(3, "-REALTIME- peer Destroyed. Name: %s. Realtime Peer objects: %d\n", peer->name, rpeerobjs);
04295    } else
04296       ast_atomic_fetchadd_int(&speerobjs, -1);
04297    clear_realm_authentication(peer->auth);
04298    peer->auth = NULL;
04299    if (peer->dnsmgr)
04300       ast_dnsmgr_release(peer->dnsmgr);
04301    clear_peer_mailboxes(peer);
04302 
04303    if (peer->socket.tcptls_session) {
04304       ao2_ref(peer->socket.tcptls_session, -1);
04305       peer->socket.tcptls_session = NULL;
04306    }
04307 }

static void sip_destroy_peer_fn ( void *  peer  )  [static]

Definition at line 4258 of file chan_sip.c.

References sip_destroy_peer().

Referenced by build_peer(), and temp_peer().

04259 {
04260    sip_destroy_peer(peer);
04261 }

static int sip_devicestate ( void *  data  )  [static]

Part of PBX channel interface.

Note:
Return values:---
If we have qualify on and the device is not reachable, regardless of registration state we return AST_DEVICE_UNAVAILABLE

For peers with call limit:

For peers without call limit:

Peers that does not have a known call and can't be reached by OPTIONS

If we return AST_DEVICE_UNKNOWN, the device state engine will try to find out a state by walking the channel list.

The queue system (app_queue.c) treats a member as "active" if devicestate is != AST_DEVICE_UNAVAILBALE && != AST_DEVICE_INVALID

When placing a call to the queue member, queue system sets a member to busy if != AST_DEVICE_NOT_INUSE and != AST_DEVICE_UNKNOWN

Definition at line 22071 of file chan_sip.c.

References sip_peer::addr, ast_debug, AST_DEVICE_BUSY, AST_DEVICE_INUSE, AST_DEVICE_INVALID, AST_DEVICE_NOT_INUSE, AST_DEVICE_ONHOLD, AST_DEVICE_RINGING, AST_DEVICE_RINGINUSE, AST_DEVICE_UNAVAILABLE, AST_DEVICE_UNKNOWN, ast_strdupa, sip_peer::busy_level, sip_peer::call_limit, sip_peer::defaddr, FALSE, find_peer(), FINDALLDEVICES, sip_peer::inRinging, sip_peer::inUse, sip_peer::lastms, sip_peer::maxms, sip_peer::onHold, TRUE, and unref_peer().

22072 {
22073    char *host;
22074    char *tmp;
22075    struct sip_peer *p;
22076 
22077    int res = AST_DEVICE_INVALID;
22078 
22079    /* make sure data is not null. Maybe unnecessary, but better be safe */
22080    host = ast_strdupa(data ? data : "");
22081    if ((tmp = strchr(host, '@')))
22082       host = tmp + 1;
22083 
22084    ast_debug(3, "Checking device state for peer %s\n", host);
22085 
22086    /* If find_peer asks for a realtime peer, then this breaks rtautoclear.  This
22087     * is because when a peer tries to autoexpire, the last thing it does is to
22088     * queue up an event telling the system that the devicestate has changed
22089     * (presumably to unavailable).  If we ask for a realtime peer here, this would
22090     * load it BACK into memory, thus defeating the point of trying to clear dead
22091     * hosts out of memory.
22092     */
22093    if ((p = find_peer(host, NULL, FALSE, FINDALLDEVICES, TRUE, 0))) {
22094       if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
22095          /* we have an address for the peer */
22096       
22097          /* Check status in this order
22098             - Hold
22099             - Ringing
22100             - Busy (enforced only by call limit)
22101             - Inuse (we have a call)
22102             - Unreachable (qualify)
22103             If we don't find any of these state, report AST_DEVICE_NOT_INUSE
22104             for registered devices */
22105 
22106          if (p->onHold)
22107             /* First check for hold or ring states */
22108             res = AST_DEVICE_ONHOLD;
22109          else if (p->inRinging) {
22110             if (p->inRinging == p->inUse)
22111                res = AST_DEVICE_RINGING;
22112             else
22113                res = AST_DEVICE_RINGINUSE;
22114          } else if (p->call_limit && (p->inUse == p->call_limit))
22115             /* check call limit */
22116             res = AST_DEVICE_BUSY;
22117          else if (p->call_limit && p->busy_level && p->inUse >= p->busy_level)
22118             /* We're forcing busy before we've reached the call limit */
22119             res = AST_DEVICE_BUSY;
22120          else if (p->call_limit && p->inUse)
22121             /* Not busy, but we do have a call */
22122             res = AST_DEVICE_INUSE;
22123          else if (p->maxms && ((p->lastms > p->maxms) || (p->lastms < 0))) 
22124             /* We don't have a call. Are we reachable at all? Requires qualify= */
22125             res = AST_DEVICE_UNAVAILABLE;
22126          else  /* Default reply if we're registered and have no other data */
22127             res = AST_DEVICE_NOT_INUSE;
22128       } else {
22129          /* there is no address, it's unavailable */
22130          res = AST_DEVICE_UNAVAILABLE;
22131       }
22132       unref_peer(p, "unref_peer, from sip_devicestate, release ref from find_peer");
22133    } else {
22134       res = AST_DEVICE_UNKNOWN;
22135    }
22136 
22137    return res;
22138 }

static char * sip_do_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Turn on SIP debugging (CLI command).

Note:
this can be a special debug command - "sip debug text" or something

Definition at line 16040 of file chan_sip.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_peer(), ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, sip_debug_console, sip_do_debug_ip(), sip_do_debug_peer(), strcasestr(), ast_cli_entry::usage, and ast_cli_args::word.

16041 {
16042    int oldsipdebug = sipdebug & sip_debug_console;
16043    char *what;
16044 
16045    if (cmd == CLI_INIT) {
16046       e->command = "sip set debug {on|off|ip|peer}";
16047       e->usage =
16048          "Usage: sip set debug {off|on|ip addr[:port]|peer peername}\n"
16049          "       Globally disables dumping of SIP packets,\n"
16050          "       or enables it either globally or for a (single)\n"
16051          "       IP address or registered peer.\n";
16052       return NULL;
16053    } else if (cmd == CLI_GENERATE) {
16054       if (a->pos == 4 && strcasestr(a->line, " peer")) /* XXX should check on argv too */
16055          return complete_sip_peer(a->word, a->n, 0);
16056       return NULL;
16057         }
16058 
16059    what = a->argv[e->args-1];      /* guaranteed to exist */
16060    if (a->argc == e->args) {       /* on/off */
16061       if (!strcasecmp(what, "on")) {
16062          sipdebug |= sip_debug_console;
16063          sipdebug_text = 1;   /*! \note this can be a special debug command - "sip debug text" or something */
16064          memset(&debugaddr, 0, sizeof(debugaddr));
16065          ast_cli(a->fd, "SIP Debugging %senabled\n", oldsipdebug ? "re-" : "");
16066          return CLI_SUCCESS;
16067       } else if (!strcasecmp(what, "off")) {
16068          sipdebug &= ~sip_debug_console;
16069          sipdebug_text = 0;
16070          ast_cli(a->fd, "SIP Debugging Disabled\n");
16071          return CLI_SUCCESS;
16072       }
16073    } else if (a->argc == e->args +1) {/* ip/peer */
16074       if (!strcasecmp(what, "ip"))
16075          return sip_do_debug_ip(a->fd, a->argv[e->args]);
16076       else if (!strcasecmp(what, "peer"))
16077          return sip_do_debug_peer(a->fd, a->argv[e->args]);
16078    }
16079    return CLI_SHOWUSAGE;   /* default, failure */
16080 }

static char * sip_do_debug_ip ( int  fd,
char *  arg 
) [static]

Enable SIP Debugging for a single IP.

Definition at line 15990 of file chan_sip.c.

References ahp, ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), CLI_SHOWUSAGE, CLI_SUCCESS, hp, sip_debug_console, and strsep().

Referenced by sip_do_debug().

15991 {
15992    struct hostent *hp;
15993    struct ast_hostent ahp;
15994    int port = 0;
15995    char *p;
15996 
15997    p = arg;
15998    strsep(&p, ":");
15999    if (p)
16000       port = atoi(p);
16001    hp = ast_gethostbyname(arg, &ahp);
16002    if (hp == NULL)
16003       return CLI_SHOWUSAGE;
16004 
16005    debugaddr.sin_family = AF_INET;
16006    memcpy(&debugaddr.sin_addr, hp->h_addr, sizeof(debugaddr.sin_addr));
16007    debugaddr.sin_port = htons(port);
16008    if (port == 0)
16009       ast_cli(fd, "SIP Debugging Enabled for IP: %s\n", ast_inet_ntoa(debugaddr.sin_addr));
16010    else
16011       ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(debugaddr.sin_addr), port);
16012 
16013    sipdebug |= sip_debug_console;
16014 
16015    return CLI_SUCCESS;
16016 }

static char * sip_do_debug_peer ( int  fd,
char *  arg 
) [static]

Turn on SIP debugging for a given peer.

Definition at line 16019 of file chan_sip.c.

References sip_peer::addr, ast_cli(), ast_inet_ntoa(), CLI_SUCCESS, FALSE, find_peer(), FINDPEERS, sip_debug_console, TRUE, and unref_peer().

Referenced by sip_do_debug().

16020 {
16021    struct sip_peer *peer = find_peer(arg, NULL, TRUE, FINDPEERS, FALSE, 0);
16022    if (!peer)
16023       ast_cli(fd, "No such peer '%s'\n", arg);
16024    else if (peer->addr.sin_addr.s_addr == 0)
16025       ast_cli(fd, "Unable to get IP address of peer '%s'\n", arg);
16026    else {
16027       debugaddr.sin_family = AF_INET;
16028       debugaddr.sin_addr = peer->addr.sin_addr;
16029       debugaddr.sin_port = peer->addr.sin_port;
16030       ast_cli(fd, "SIP Debugging Enabled for IP: %s:%d\n",
16031          ast_inet_ntoa(debugaddr.sin_addr), ntohs(debugaddr.sin_port));
16032       sipdebug |= sip_debug_console;
16033    }
16034    if (peer)
16035       unref_peer(peer, "sip_do_debug_peer: unref_peer, from find_peer call");
16036    return CLI_SUCCESS;
16037 }

static char * sip_do_history_deprecated ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Enable/Disable SIP History logging (CLI) - deprecated. use sip_set_history instead.

Definition at line 16151 of file chan_sip.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, TRUE, and ast_cli_entry::usage.

16152 {
16153    switch (cmd) {
16154    case CLI_INIT:
16155       e->command = "sip history [off]";
16156       e->usage =
16157          "Usage: sip history [off]\n"
16158          "       Enables/Disables recording of SIP dialog history for debugging purposes.\n"
16159          "       Use 'sip show history' to view the history of a call number.\n";
16160       return NULL;
16161    case CLI_GENERATE:
16162       return NULL;
16163    }
16164 
16165    if (a->argc < 2 || a->argc > 3) {
16166       return CLI_SHOWUSAGE;
16167    }
16168    if (a->argc == 2) {
16169       recordhistory = TRUE;
16170       ast_cli(a->fd, "SIP History Recording Enabled (use 'sip show history')\n");
16171    } else {
16172       if (strncasecmp(a->argv[2], "off", 3))
16173          return CLI_SHOWUSAGE;
16174       recordhistory = FALSE;
16175       ast_cli(a->fd, "SIP History Recording Disabled\n");
16176    }
16177    return CLI_SUCCESS;
16178 }

static int sip_do_reload ( enum channelreloadreason  reason  )  [static]

Reload module.

Definition at line 24590 of file chan_sip.c.

References ao2_t_callback, ast_debug, ast_sched_dump(), OBJ_MULTIPLE, OBJ_NODATA, OBJ_UNLINK, peer_is_marked(), peers, reload_config(), sched, sip_poke_all_peers(), and sip_send_all_registers().

Referenced by do_monitor().

24591 {
24592    time_t start_poke, end_poke;
24593    
24594    reload_config(reason);
24595    ast_sched_dump(sched);
24596 
24597    start_poke = time(0);
24598    /* Prune peers who still are supposed to be deleted */
24599    ao2_t_callback(peers, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, peer_is_marked, 0, 
24600          "callback to remove marked peers");
24601    
24602    ast_debug(4, "--------------- Done destroying pruned peers\n");
24603 
24604    /* Send qualify (OPTIONS) to all peers */
24605    sip_poke_all_peers();
24606 
24607    /* Register with all services */
24608    sip_send_all_registers();
24609    end_poke = time(0);
24610    
24611    ast_debug(4, "do_reload finished. peer poke/prune reg contact time = %d sec.\n", (int)(end_poke-start_poke));
24612 
24613    ast_debug(4, "--------------- SIP reload done\n");
24614 
24615    return 0;
24616 }

static int sip_dtmfmode ( struct ast_channel chan,
void *  data 
) [static]

Set the DTMFmode for an outbound SIP call (application).

Definition at line 24376 of file chan_sip.c.

References ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_dsp_free(), ast_dsp_new(), ast_dsp_set_features(), ast_log(), AST_RTP_DTMF, ast_rtp_setdtmf(), ast_set_flag, ast_test_flag, chan, sip_pvt::dsp, DSP_FEATURE_DIGIT_DETECT, sip_pvt::flags, IS_SIP_TECH, sip_pvt::jointnoncodeccapability, LOG_WARNING, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_DTMF_SHORTINFO, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech, and ast_channel::tech_pvt.

Referenced by load_module().

24377 {
24378    struct sip_pvt *p;
24379    char *mode = data;
24380 
24381    if (!data) {
24382       ast_log(LOG_WARNING, "This application requires the argument: info, inband, rfc2833\n");
24383       return 0;
24384    }
24385    ast_channel_lock(chan);
24386    if (!IS_SIP_TECH(chan->tech)) {
24387       ast_log(LOG_WARNING, "Call this application only on SIP incoming calls\n");
24388       ast_channel_unlock(chan);
24389       return 0;
24390    }
24391    p = chan->tech_pvt;
24392    if (!p) {
24393       ast_channel_unlock(chan);
24394       return 0;
24395    }
24396    sip_pvt_lock(p);
24397    if (!strcasecmp(mode, "info")) {
24398       ast_clear_flag(&p->flags[0], SIP_DTMF);
24399       ast_set_flag(&p->flags[0], SIP_DTMF_INFO);
24400       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
24401    } else if (!strcasecmp(mode, "shortinfo")) {
24402       ast_clear_flag(&p->flags[0], SIP_DTMF);
24403       ast_set_flag(&p->flags[0], SIP_DTMF_SHORTINFO);
24404       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
24405    } else if (!strcasecmp(mode, "rfc2833")) {
24406       ast_clear_flag(&p->flags[0], SIP_DTMF);
24407       ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
24408       p->jointnoncodeccapability |= AST_RTP_DTMF;
24409    } else if (!strcasecmp(mode, "inband")) { 
24410       ast_clear_flag(&p->flags[0], SIP_DTMF);
24411       ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
24412       p->jointnoncodeccapability &= ~AST_RTP_DTMF;
24413    } else
24414       ast_log(LOG_WARNING, "I don't know about this dtmf mode: %s\n", mode);
24415    if (p->rtp)
24416       ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833);
24417    if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) {
24418       if (!p->dsp) {
24419          p->dsp = ast_dsp_new();
24420          ast_dsp_set_features(p->dsp, DSP_FEATURE_DIGIT_DETECT);
24421       }
24422    } else {
24423       if (p->dsp) {
24424          ast_dsp_free(p->dsp);
24425          p->dsp = NULL;
24426       }
24427    }
24428    sip_pvt_unlock(p);
24429    ast_channel_unlock(chan);
24430    return 0;
24431 }

static void sip_dump_history ( struct sip_pvt dialog  )  [static]

Dump SIP history to debug log file at end of lifespan for SIP dialog.

Definition at line 15775 of file chan_sip.c.

References ast_debug, AST_LIST_TRAVERSE, ast_log(), sip_pvt::callid, sip_history::event, sip_pvt::history, sip_history::list, LOG_NOTICE, option_debug, and sip_pvt::subscribed.

Referenced by __sip_destroy().

15776 {
15777    int x = 0;
15778    struct sip_history *hist;
15779    static int errmsg = 0;
15780 
15781    if (!dialog)
15782       return;
15783 
15784    if (!option_debug && !sipdebug) {
15785       if (!errmsg) {
15786          ast_log(LOG_NOTICE, "You must have debugging enabled (SIP or Asterisk) in order to dump SIP history.\n");
15787          errmsg = 1;
15788       }
15789       return;
15790    }
15791 
15792    ast_debug(1, "\n---------- SIP HISTORY for '%s' \n", dialog->callid);
15793    if (dialog->subscribed)
15794       ast_debug(1, "  * Subscription\n");
15795    else
15796       ast_debug(1, "  * SIP Call\n");
15797    if (dialog->history)
15798       AST_LIST_TRAVERSE(dialog->history, hist, list)
15799          ast_debug(1, "  %-3.3d. %s\n", ++x, hist->event);
15800    if (!x)
15801       ast_debug(1, "Call '%s' has no history\n", dialog->callid);
15802    ast_debug(1, "\n---------- END SIP HISTORY for '%s' \n", dialog->callid);
15803 }

static int sip_fixup ( struct ast_channel oldchan,
struct ast_channel newchan 
) [static]

sip_fixup: Fix up a channel: If a channel is consumed, this is called. Basically update any ->owner links

Definition at line 5909 of file chan_sip.c.

References append_history, ast_debug, AST_FLAG_ZOMBIE, ast_log(), ast_test_flag, sip_pvt::callid, LOG_WARNING, ast_channel::name, sip_pvt::owner, sip_pvt_lock, sip_pvt_unlock, sip_set_rtp_peer(), and ast_channel::tech_pvt.

05910 {
05911    int ret = -1;
05912    struct sip_pvt *p;
05913 
05914    if (newchan && ast_test_flag(newchan, AST_FLAG_ZOMBIE))
05915       ast_debug(1, "New channel is zombie\n");
05916    if (oldchan && ast_test_flag(oldchan, AST_FLAG_ZOMBIE))
05917       ast_debug(1, "Old channel is zombie\n");
05918 
05919    if (!newchan || !newchan->tech_pvt) {
05920       if (!newchan)
05921          ast_log(LOG_WARNING, "No new channel! Fixup of %s failed.\n", oldchan->name);
05922       else
05923          ast_log(LOG_WARNING, "No SIP tech_pvt! Fixup of %s failed.\n", oldchan->name);
05924       return -1;
05925    }
05926    p = newchan->tech_pvt;
05927 
05928    sip_pvt_lock(p);
05929    append_history(p, "Masq", "Old channel: %s\n", oldchan->name);
05930    append_history(p, "Masq (cont)", "...new owner: %s\n", newchan->name);
05931    if (p->owner != oldchan)
05932       ast_log(LOG_WARNING, "old channel wasn't %p but was %p\n", oldchan, p->owner);
05933    else {
05934       p->owner = newchan;
05935       /* Re-invite RTP back to Asterisk. Needed if channel is masqueraded out of a native
05936          RTP bridge (i.e., RTP not going through Asterisk): RTP bridge code might not be
05937          able to do this if the masquerade happens before the bridge breaks (e.g., AMI
05938          redirect of both channels). Note that a channel can not be masqueraded *into*
05939          a native bridge. So there is no danger that this breaks a native bridge that
05940          should stay up. */
05941       sip_set_rtp_peer(newchan, NULL, NULL, 0, 0, 0);
05942       ret = 0;
05943    }
05944    ast_debug(3, "SIP Fixup: New owner for dialogue %s: %s (Old parent: %s)\n", p->callid, p->owner->name, oldchan->name);
05945 
05946    sip_pvt_unlock(p);
05947    return ret;
05948 }

static const char * sip_get_callid ( struct ast_channel chan  )  [static]

Deliver SIP call ID for the call.

Definition at line 4125 of file chan_sip.c.

References chan, and ast_channel::tech_pvt.

04126 {
04127    return chan->tech_pvt ? ((struct sip_pvt *) chan->tech_pvt)->callid : "";
04128 }

static int sip_get_codec ( struct ast_channel chan  )  [static]

Return SIP UA's codec (part of the RTP interface).

Definition at line 24533 of file chan_sip.c.

References sip_pvt::capability, chan, sip_pvt::jointcapability, and ast_channel::tech_pvt.

24534 {
24535    struct sip_pvt *p = chan->tech_pvt;
24536    return p->jointcapability ? p->jointcapability : p->capability;   
24537 }

static enum ast_rtp_get_result sip_get_rtp_peer ( struct ast_channel chan,
struct ast_rtp **  rtp 
) [static]

Returns null if we can't reinvite audio (part of RTP interface).

Definition at line 24210 of file chan_sip.c.

References AST_JB_FORCED, AST_RTP_GET_FAILED, ast_rtp_getnat(), AST_RTP_TRY_NATIVE, AST_RTP_TRY_PARTIAL, ast_test_flag, chan, sip_pvt::flags, global_jbconf, sip_pvt::rtp, SIP_CAN_REINVITE, SIP_CAN_REINVITE_NAT, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.

24211 {
24212    struct sip_pvt *p = NULL;
24213    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
24214 
24215    if (!(p = chan->tech_pvt))
24216       return AST_RTP_GET_FAILED;
24217 
24218    sip_pvt_lock(p);
24219    if (!(p->rtp)) {
24220       sip_pvt_unlock(p);
24221       return AST_RTP_GET_FAILED;
24222    }
24223 
24224    *rtp = p->rtp;
24225 
24226    if (ast_rtp_getnat(*rtp) && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT))
24227       res = AST_RTP_TRY_PARTIAL;
24228    else if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
24229       res = AST_RTP_TRY_NATIVE;
24230    else if (ast_test_flag(&global_jbconf, AST_JB_FORCED))
24231       res = AST_RTP_GET_FAILED;
24232 
24233    sip_pvt_unlock(p);
24234 
24235    return res;
24236 }

static enum ast_rtp_get_result sip_get_trtp_peer ( struct ast_channel chan,
struct ast_rtp **  rtp 
) [static]

Returns null if we can't reinvite text (part of RTP interface).

Definition at line 24264 of file chan_sip.c.

References AST_RTP_GET_FAILED, AST_RTP_TRY_NATIVE, AST_RTP_TRY_PARTIAL, ast_test_flag, chan, sip_pvt::flags, sip_pvt::rtp, SIP_CAN_REINVITE, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and sip_pvt::trtp.

24265 {
24266    struct sip_pvt *p = NULL;
24267    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
24268    
24269    if (!(p = chan->tech_pvt))
24270       return AST_RTP_GET_FAILED;
24271 
24272    sip_pvt_lock(p);
24273    if (!(p->trtp)) {
24274       sip_pvt_unlock(p);
24275       return AST_RTP_GET_FAILED;
24276    }
24277 
24278    *rtp = p->trtp;
24279 
24280    if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
24281       res = AST_RTP_TRY_NATIVE;
24282 
24283    sip_pvt_unlock(p);
24284 
24285    return res;
24286 }

static struct ast_udptl * sip_get_udptl_peer ( struct ast_channel chan  )  [static]

Definition at line 24166 of file chan_sip.c.

References ast_test_flag, chan, sip_pvt::flags, SIP_CAN_REINVITE, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and sip_pvt::udptl.

24167 {
24168    struct sip_pvt *p;
24169    struct ast_udptl *udptl = NULL;
24170    
24171    p = chan->tech_pvt;
24172    if (!p)
24173       return NULL;
24174    
24175    sip_pvt_lock(p);
24176    if (p->udptl && ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
24177       udptl = p->udptl;
24178    sip_pvt_unlock(p);
24179    return udptl;
24180 }

static enum ast_rtp_get_result sip_get_vrtp_peer ( struct ast_channel chan,
struct ast_rtp **  rtp 
) [static]

Returns null if we can't reinvite video (part of RTP interface).

Definition at line 24239 of file chan_sip.c.

References AST_RTP_GET_FAILED, AST_RTP_TRY_NATIVE, AST_RTP_TRY_PARTIAL, ast_test_flag, chan, sip_pvt::flags, sip_pvt::rtp, SIP_CAN_REINVITE, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and sip_pvt::vrtp.

24240 {
24241    struct sip_pvt *p = NULL;
24242    enum ast_rtp_get_result res = AST_RTP_TRY_PARTIAL;
24243    
24244    if (!(p = chan->tech_pvt))
24245       return AST_RTP_GET_FAILED;
24246 
24247    sip_pvt_lock(p);
24248    if (!(p->vrtp)) {
24249       sip_pvt_unlock(p);
24250       return AST_RTP_GET_FAILED;
24251    }
24252 
24253    *rtp = p->vrtp;
24254 
24255    if (ast_test_flag(&p->flags[0], SIP_CAN_REINVITE))
24256       res = AST_RTP_TRY_NATIVE;
24257 
24258    sip_pvt_unlock(p);
24259 
24260    return res;
24261 }

static int sip_hangup ( struct ast_channel ast  )  [static]

sip_hangup: Hangup SIP call Part of PBX interface, called from ast_hangup

Definition at line 5552 of file chan_sip.c.

References __sip_pretend_ack(), __sip_semi_ack(), ast_channel::_state, sip_pvt::alreadygone, sip_pvt::answered_elsewhere, append_history, ast_bridged_channel(), ast_cause2str(), ast_channel_trylock, ast_channel_unlock, ast_clear_flag, ast_debug, ast_dsp_free(), AST_FLAG_ANSWERED_ELSEWHERE, AST_FLAG_ZOMBIE, ast_log(), ast_module_unref(), ast_rtp_get_quality(), ast_rtp_set_vars(), AST_SCHED_DEL_UNREF, ast_set_flag, ast_state2str(), AST_STATE_UP, ast_strlen_zero(), ast_test_flag, sip_pvt::autokillid, sip_pvt::callid, CHANNEL_DEADLOCK_AVOIDANCE, sip_pkt::data, DEC_CALL_LIMIT, DEFAULT_TRANS_TIMEOUT, dialog_unref(), sip_pvt::dsp, FALSE, find_sip_method(), sip_pvt::flags, hangup_cause2sip(), ast_channel::hangupcause, sip_pvt::hangupcause, INV_CALLING, INV_CANCELLED, INV_COMPLETED, INV_TERMINATED, sip_pvt::invitestate, sip_pkt::is_resp, IS_SIP_TECH, LOG_WARNING, sip_pkt::method, ast_channel::name, sip_pvt::needdestroy, sip_pkt::next, sip_pvt::owner, pbx_builtin_setvar_helper(), sip_pvt::refer, sip_pvt::rtp, RTPQOS_SUMMARY, sched, sip_pkt::seqno, SIP_BYE, SIP_CANCEL, sip_cancel_destroy(), SIP_DEFER_BYE_ON_TRANSFER, SIP_INC_COUNT, SIP_NEEDREINVITE, SIP_OUTGOING, SIP_PAGE2_CALL_ONHOLD, SIP_PENDINGBYE, sip_pvt_lock, sip_pvt_trylock, sip_pvt_unlock, sip_scheddestroy(), stop_media_flows(), stop_session_timer(), ast_str::str, ast_channel::tech, ast_channel::tech_pvt, transmit_request(), transmit_request_with_auth(), transmit_response_reliable(), TRUE, update_call_counter(), sip_pvt::username, and XMIT_RELIABLE.

05553 {
05554    struct sip_pvt *p = ast->tech_pvt;
05555    int needcancel = FALSE;
05556    int needdestroy = 0;
05557    struct ast_channel *oldowner = ast;
05558 
05559    if (!p) {
05560       ast_debug(1, "Asked to hangup channel that was not connected\n");
05561       return 0;
05562    }
05563    if (ast_test_flag(ast, AST_FLAG_ANSWERED_ELSEWHERE)) {
05564       ast_debug(1, "This call was answered elsewhere");
05565       append_history(p, "Cancel", "Call answered elsewhere");
05566       p->answered_elsewhere = TRUE;
05567    }
05568 
05569    /* Store hangupcause locally in PVT so we still have it before disconnect */
05570    if (p->owner)
05571       p->hangupcause = p->owner->hangupcause;
05572 
05573    if (ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
05574       if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
05575          if (sipdebug)
05576             ast_debug(1, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username);
05577          update_call_counter(p, DEC_CALL_LIMIT);
05578       }
05579       ast_debug(4, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid);
05580       if (p->autokillid > -1 && sip_cancel_destroy(p))
05581          ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
05582       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
05583       ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER); /* Really hang up next time */
05584       p->needdestroy = 0;
05585       p->owner->tech_pvt = dialog_unref(p->owner->tech_pvt, "unref p->owner->tech_pvt");
05586       sip_pvt_lock(p);
05587       p->owner = NULL;  /* Owner will be gone after we return, so take it away */
05588       sip_pvt_unlock(p);
05589       return 0;
05590    }
05591 
05592    if (ast_test_flag(ast, AST_FLAG_ZOMBIE)) {
05593       if (p->refer)
05594          ast_debug(1, "SIP Transfer: Hanging up Zombie channel %s after transfer ... Call-ID: %s\n", ast->name, p->callid);
05595       else
05596          ast_debug(1, "Hanging up zombie call. Be scared.\n");
05597    } else
05598       ast_debug(1, "Hangup call %s, SIP callid %s\n", ast->name, p->callid);
05599 
05600    sip_pvt_lock(p);
05601    if (ast_test_flag(&p->flags[0], SIP_INC_COUNT) || ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
05602       if (sipdebug)
05603          ast_debug(1, "update_call_counter(%s) - decrement call limit counter on hangup\n", p->username);
05604       update_call_counter(p, DEC_CALL_LIMIT);
05605    }
05606 
05607    /* Determine how to disconnect */
05608    if (p->owner != ast) {
05609       ast_log(LOG_WARNING, "Huh?  We aren't the owner? Can't hangup call.\n");
05610       sip_pvt_unlock(p);
05611       return 0;
05612    }
05613    /* If the call is not UP, we need to send CANCEL instead of BYE */
05614    /* In case of re-invites, the call might be UP even though we have an incomplete invite transaction */
05615    if (p->invitestate < INV_COMPLETED && p->owner->_state != AST_STATE_UP) {
05616       needcancel = TRUE;
05617       ast_debug(4, "Hanging up channel in state %s (not UP)\n", ast_state2str(ast->_state));
05618    }
05619 
05620    stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */
05621 
05622    append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->hangupcause) : "Unknown");
05623 
05624    /* Disconnect */
05625    if (p->dsp)
05626       ast_dsp_free(p->dsp);
05627 
05628    p->owner = NULL;
05629    ast->tech_pvt = dialog_unref(ast->tech_pvt, "unref ast->tech_pvt");
05630 
05631    ast_module_unref(ast_module_info->self);
05632    /* Do not destroy this pvt until we have timeout or
05633       get an answer to the BYE or INVITE/CANCEL 
05634       If we get no answer during retransmit period, drop the call anyway.
05635       (Sorry, mother-in-law, you can't deny a hangup by sending
05636       603 declined to BYE...)
05637    */
05638    if (p->alreadygone)
05639       needdestroy = 1;  /* Set destroy flag at end of this function */
05640    else if (p->invitestate != INV_CALLING)
05641       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
05642 
05643    /* Start the process if it's not already started */
05644    if (!p->alreadygone && p->initreq.data && !ast_strlen_zero(p->initreq.data->str)) {
05645       if (needcancel) { /* Outgoing call, not up */
05646          if (ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
05647             /* stop retransmitting an INVITE that has not received a response */
05648             /* if we can't send right now, mark it pending */
05649             if (p->invitestate == INV_CALLING) {
05650                /* We can't send anything in CALLING state */
05651                ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
05652                __sip_pretend_ack(p);
05653                /* Do we need a timer here if we don't hear from them at all? Yes we do or else we will get hung dialogs and those are no fun. */
05654                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
05655                append_history(p, "DELAY", "Not sending cancel, waiting for timeout");
05656             } else {
05657                struct sip_pkt *cur;
05658 
05659                for (cur = p->packets; cur; cur = cur->next) {
05660                   __sip_semi_ack(p, cur->seqno, cur->is_resp, cur->method ? cur->method : find_sip_method(cur->data->str));
05661                }
05662                p->invitestate = INV_CANCELLED;
05663                /* Send a new request: CANCEL */
05664                transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE);
05665                /* Actually don't destroy us yet, wait for the 487 on our original 
05666                   INVITE, but do set an autodestruct just in case we never get it. */
05667                needdestroy = 0;
05668                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
05669             }
05670          } else { /* Incoming call, not up */
05671             const char *res;
05672             AST_SCHED_DEL_UNREF(sched, p->provisional_keepalive_sched_id, dialog_unref(p, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr"));
05673             if (p->hangupcause && (res = hangup_cause2sip(p->hangupcause)))
05674                transmit_response_reliable(p, res, &p->initreq);
05675             else 
05676                transmit_response_reliable(p, "603 Declined", &p->initreq);
05677             p->invitestate = INV_TERMINATED;
05678          }
05679       } else { /* Call is in UP state, send BYE */
05680          if (p->stimer->st_active == TRUE) {
05681             stop_session_timer(p);
05682          }
05683 
05684          if (!p->pendinginvite) {
05685             struct ast_channel *bridge = ast_bridged_channel(oldowner);
05686             char *audioqos = "";
05687             char *videoqos = "";
05688             char *textqos = "";
05689 
05690             /* We need to get the lock on bridge because ast_rtp_set_vars will attempt
05691              * to lock the bridge. This may get hairy...
05692              */
05693             while (bridge && ast_channel_trylock(bridge)) {
05694                sip_pvt_unlock(p);
05695                do {
05696                   /* Use oldowner since p->owner is already NULL */
05697                   CHANNEL_DEADLOCK_AVOIDANCE(oldowner);
05698                } while (sip_pvt_trylock(p));
05699                bridge = ast_bridged_channel(oldowner);
05700             }
05701 
05702             if (p->rtp)
05703                ast_rtp_set_vars(oldowner, p->rtp);
05704 
05705             if (bridge) {
05706                struct sip_pvt *q = bridge->tech_pvt;
05707 
05708                if (IS_SIP_TECH(bridge->tech) && q && q->rtp)
05709                   ast_rtp_set_vars(bridge, q->rtp);
05710                ast_channel_unlock(bridge);
05711             }
05712 
05713             if (p->vrtp)
05714                videoqos = ast_rtp_get_quality(p->vrtp, NULL, RTPQOS_SUMMARY);
05715             if (p->trtp)
05716                textqos = ast_rtp_get_quality(p->trtp, NULL, RTPQOS_SUMMARY);
05717             /* Send a hangup */
05718             if (oldowner->_state == AST_STATE_UP) {
05719                transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, 1);
05720             }
05721 
05722             /* Get RTCP quality before end of call */
05723             if (p->do_history) {
05724                if (p->rtp)
05725                   append_history(p, "RTCPaudio", "Quality:%s", audioqos);
05726                if (p->vrtp)
05727                   append_history(p, "RTCPvideo", "Quality:%s", videoqos);
05728                if (p->trtp)
05729                   append_history(p, "RTCPtext", "Quality:%s", textqos);
05730             }
05731             if (p->rtp && oldowner)
05732                pbx_builtin_setvar_helper(oldowner, "RTPAUDIOQOS", audioqos);
05733             if (p->vrtp && oldowner)
05734                pbx_builtin_setvar_helper(oldowner, "RTPVIDEOQOS", videoqos);
05735             if (p->trtp && oldowner)
05736                pbx_builtin_setvar_helper(oldowner, "RTPTEXTQOS", textqos);
05737          } else {
05738             /* Note we will need a BYE when this all settles out
05739                but we can't send one while we have "INVITE" outstanding. */
05740             ast_set_flag(&p->flags[0], SIP_PENDINGBYE);  
05741             ast_clear_flag(&p->flags[0], SIP_NEEDREINVITE); 
05742             AST_SCHED_DEL_UNREF(sched, p->waitid, dialog_unref(p, "when you delete the waitid sched, you should dec the refcount for the stored dialog ptr"));
05743             if (sip_cancel_destroy(p))
05744                ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
05745          }
05746       }
05747    }
05748    if (needdestroy)
05749       p->needdestroy = 1;
05750    sip_pvt_unlock(p);
05751    return 0;
05752 }

static int sip_indicate ( struct ast_channel ast,
int  condition,
const void *  data,
size_t  datalen 
) [static]

Play indication to user With SIP a lot of indications is sent as messages, letting the device play the indication - busy signal, congestion etc.

Returns:
-1 to force ast_indicate to send indication in audio, 0 if SIP can handle the indication by sending a message

Definition at line 6083 of file chan_sip.c.

References ast_channel::_state, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_log(), ast_moh_start(), ast_moh_stop(), ast_rtp_change_source(), ast_rtp_new_source(), ast_set_flag, AST_SOFTHANGUP_DEV, ast_softhangup_nolock(), AST_STATE_RING, AST_STATE_UP, ast_test_flag, sip_pvt::flags, sip_pvt::initreq, interpret_t38_parameters(), INV_COMPLETED, INV_EARLY_MEDIA, INV_PROCEEDING, sip_pvt::invitestate, LOG_ERROR, LOG_WARNING, sip_pvt::mohinterpret, sip_pvt::novideo, sip_pvt::rtp, sip_alreadygone(), SIP_OUTGOING, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_YES, SIP_PROGRESS_SENT, sip_pvt_lock, sip_pvt_unlock, SIP_RINGING, ast_channel::tech_pvt, transmit_info_with_vidupdate(), transmit_provisional_response(), transmit_response(), transmit_response_reliable(), TRUE, and sip_pvt::vrtp.

06084 {
06085    struct sip_pvt *p = ast->tech_pvt;
06086    int res = 0;
06087 
06088    sip_pvt_lock(p);
06089    switch(condition) {
06090    case AST_CONTROL_RINGING:
06091       if (ast->_state == AST_STATE_RING) {
06092          p->invitestate = INV_EARLY_MEDIA;
06093          if (!ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) ||
06094              (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER)) {            
06095             /* Send 180 ringing if out-of-band seems reasonable */
06096             transmit_provisional_response(p, "180 Ringing", &p->initreq, 0);
06097             ast_set_flag(&p->flags[0], SIP_RINGING);
06098             if (ast_test_flag(&p->flags[0], SIP_PROG_INBAND) != SIP_PROG_INBAND_YES)
06099                break;
06100          } else {
06101             /* Well, if it's not reasonable, just send in-band */
06102          }
06103       }
06104       res = -1;
06105       break;
06106    case AST_CONTROL_BUSY:
06107       if (ast->_state != AST_STATE_UP) {
06108          transmit_response_reliable(p, "486 Busy Here", &p->initreq);
06109          p->invitestate = INV_COMPLETED;
06110          sip_alreadygone(p);
06111          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
06112          break;
06113       }
06114       res = -1;
06115       break;
06116    case AST_CONTROL_CONGESTION:
06117       if (ast->_state != AST_STATE_UP) {
06118          transmit_response_reliable(p, "503 Service Unavailable", &p->initreq);
06119          p->invitestate = INV_COMPLETED;
06120          sip_alreadygone(p);
06121          ast_softhangup_nolock(ast, AST_SOFTHANGUP_DEV);
06122          break;
06123       }
06124       res = -1;
06125       break;
06126    case AST_CONTROL_PROCEEDING:
06127       if ((ast->_state != AST_STATE_UP) &&
06128           !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
06129           !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06130          transmit_response(p, "100 Trying", &p->initreq);
06131          p->invitestate = INV_PROCEEDING;  
06132          break;
06133       }
06134       res = -1;
06135       break;
06136    case AST_CONTROL_PROGRESS:
06137       if ((ast->_state != AST_STATE_UP) &&
06138           !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
06139           !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
06140          p->invitestate = INV_EARLY_MEDIA;
06141          transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
06142          ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
06143          break;
06144       }
06145       res = -1;
06146       break;
06147    case AST_CONTROL_HOLD:
06148       ast_rtp_new_source(p->rtp);
06149       ast_moh_start(ast, data, p->mohinterpret);
06150       break;
06151    case AST_CONTROL_UNHOLD:
06152       ast_rtp_new_source(p->rtp);
06153       ast_moh_stop(ast);
06154       break;
06155    case AST_CONTROL_VIDUPDATE:   /* Request a video frame update */
06156       if (p->vrtp && !p->novideo) {
06157          transmit_info_with_vidupdate(p);
06158          /* ast_rtcp_send_h261fur(p->vrtp); */
06159       } else
06160          res = -1;
06161       break;
06162    case AST_CONTROL_T38_PARAMETERS:
06163       if (datalen != sizeof(struct ast_control_t38_parameters)) {
06164          ast_log(LOG_ERROR, "Invalid datalen for AST_CONTROL_T38_PARAMETERS. Expected %d, got %d\n", (int) sizeof(struct ast_control_t38_parameters), (int) datalen);
06165       } else {
06166          const struct ast_control_t38_parameters *parameters = data;
06167          interpret_t38_parameters(p, parameters);
06168       }
06169       break;
06170    case AST_CONTROL_SRCUPDATE:
06171       ast_rtp_new_source(p->rtp);
06172       break;
06173    case AST_CONTROL_SRCCHANGE:
06174       ast_rtp_change_source(p->rtp);
06175       break;
06176    case -1:
06177       res = -1;
06178       break;
06179    default:
06180       ast_log(LOG_WARNING, "Don't know how to indicate condition %d\n", condition);
06181       res = -1;
06182       break;
06183    }
06184    sip_pvt_unlock(p);
06185    return res;
06186 }

static const char * sip_nat_mode ( const struct sip_pvt p  )  [static]

Display SIP nat mode.

Definition at line 3087 of file chan_sip.c.

References ast_test_flag, sip_pvt::flags, SIP_NAT, and SIP_NAT_ROUTE.

Referenced by check_via(), retrans_pkt(), and send_response().

03088 {
03089    return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? "NAT" : "no NAT";
03090 }

static struct ast_channel* sip_new ( struct sip_pvt i,
int  state,
const char *  title 
) [static]

Initiate a call in the SIP channel called from sip_request_call (calls from the pbx ) for outbound channels and from handle_request_invite for inbound channels.

Definition at line 6194 of file chan_sip.c.

References accountcode, sip_pvt::accountcode, ast_channel::adsicpe, ast_channel::amaflags, sip_pvt::amaflags, append_history, AST_ADSI_UNAVAILABLE, ast_atomic_fetchadd_int(), ast_best_codec(), AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc, ast_channel_set_fd(), ast_codec_choose(), ast_copy_string(), ast_debug, ast_dsp_new(), ast_dsp_set_digitmode(), ast_dsp_set_features(), AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, ast_getformatname_multiple(), ast_hangup(), ast_jb_configure(), ast_log(), ast_module_ref(), ast_pbx_start(), ast_rtcp_fd(), ast_rtp_fd(), AST_STATE_DOWN, AST_STATE_RING, ast_strdup, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, ast_udptl_fd(), ast_uri_decode(), buf, sip_pvt::callgroup, ast_channel::callgroup, sip_pvt::callid, sip_pvt::callingpres, sip_pvt::capability, sip_pvt::chanvars, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_dnid, sip_pvt::cid_name, sip_pvt::cid_num, ast_callerid::cid_pres, ast_callerid::cid_rdnis, ast_channel::context, sip_pvt::context, dialog_ref(), sip_pvt::do_history, sip_pvt::domain, sip_pvt::dsp, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_RELAXDTMF, DSP_FEATURE_DIGIT_DETECT, DSP_FEATURE_FAX_DETECT, EVENT_FLAG_SYSTEM, ast_channel::exten, sip_pvt::exten, sip_pvt::flags, sip_pvt::fromdomain, sip_pvt::fullcontact, global_jbconf, ast_channel::hangupcause, sip_pvt::jointcapability, language, sip_pvt::language, LOG_WARNING, manager_event, ast_channel::name, ast_variable::name, ast_channel::nativeformats, ast_variable::next, sip_pvt::owner, parkinglot, sip_pvt::parkinglot, pbx_builtin_setvar_helper(), sip_pvt::pickupgroup, ast_channel::pickupgroup, sip_pvt::prefcodec, sip_pvt::prefs, ast_channel::priority, ast_channel::rawreadformat, ast_channel::rawwriteformat, sip_pvt::rdnis, ast_channel::readformat, ast_channel::rings, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_AUTO, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_SHORTINFO, SIP_PAGE2_FAX_DETECT, SIP_PAGE2_VIDEOSUPPORT, sip_pvt_lock, sip_pvt_unlock, sip_tech, sip_tech_info, SIPBUFSIZE, ast_channel::tech, ast_channel::tech_pvt, text, sip_pvt::trtp, sip_pvt::udptl, ast_channel::uniqueid, sip_pvt::uri, ast_variable::value, sip_pvt::vrtp, and ast_channel::writeformat.

Referenced by handle_request_invite(), and sip_request_call().

06195 {
06196    struct ast_channel *tmp;
06197    struct ast_variable *v = NULL;
06198    int fmt;
06199    int what;
06200    int video;
06201    int text;
06202    int needvideo = 0;
06203    int needtext = 0;
06204    char buf[SIPBUFSIZE];
06205    char *decoded_exten;
06206 
06207    {
06208       const char *my_name; /* pick a good name */
06209    
06210       if (title)
06211          my_name = title;
06212       else if ( (my_name = strchr(i->fromdomain, ':')) )
06213          my_name++;  /* skip ':' */
06214       else
06215          my_name = i->fromdomain;
06216 
06217       sip_pvt_unlock(i);
06218       /* Don't hold a sip pvt lock while we allocate a channel */
06219       tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "SIP/%s-%08x", my_name, ast_atomic_fetchadd_int((int *)&chan_idx, +1));
06220 
06221    }
06222    if (!tmp) {
06223       ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n");
06224       sip_pvt_lock(i);
06225       return NULL;
06226    }
06227    sip_pvt_lock(i);
06228 
06229    tmp->tech = ( ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INFO || ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_SHORTINFO) ?  &sip_tech_info : &sip_tech;
06230 
06231    /* Select our native format based on codec preference until we receive
06232       something from another device to the contrary. */
06233    if (i->jointcapability) {  /* The joint capabilities of us and peer */
06234       what = i->jointcapability;
06235       video = i->jointcapability & AST_FORMAT_VIDEO_MASK;
06236       text = i->jointcapability & AST_FORMAT_TEXT_MASK;
06237    } else if (i->capability) {      /* Our configured capability for this peer */
06238       what = i->capability;
06239       video = i->capability & AST_FORMAT_VIDEO_MASK;
06240       text = i->capability & AST_FORMAT_TEXT_MASK;
06241    } else {
06242       what = global_capability;  /* Global codec support */
06243       video = global_capability & AST_FORMAT_VIDEO_MASK;
06244       text = global_capability & AST_FORMAT_TEXT_MASK;
06245    }
06246 
06247    /* Set the native formats for audio  and merge in video */
06248    tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video | text;
06249    ast_debug(3, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats));
06250    ast_debug(3, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability));
06251    ast_debug(3, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability));
06252    ast_debug(3, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1)));
06253    if (i->prefcodec)
06254       ast_debug(3, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec));
06255 
06256    /* XXX Why are we choosing a codec from the native formats?? */
06257    fmt = ast_best_codec(tmp->nativeformats);
06258 
06259    /* If we have a prefcodec setting, we have an inbound channel that set a 
06260       preferred format for this call. Otherwise, we check the jointcapability
06261       We also check for vrtp. If it's not there, we are not allowed do any video anyway.
06262     */
06263    if (i->vrtp) {
06264       if (ast_test_flag(&i->flags[1], SIP_PAGE2_VIDEOSUPPORT))
06265          needvideo = AST_FORMAT_VIDEO_MASK;
06266       else if (i->prefcodec)
06267          needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK;  /* Outbound call */
06268       else
06269          needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK;  /* Inbound call */
06270    }
06271 
06272    if (i->trtp) {
06273       if (i->prefcodec)
06274          needtext = i->prefcodec & AST_FORMAT_TEXT_MASK; /* Outbound call */
06275       else
06276          needtext = i->jointcapability & AST_FORMAT_TEXT_MASK; /* Inbound call */
06277    }
06278 
06279    if (needvideo) 
06280       ast_debug(3, "This channel can handle video! HOLLYWOOD next!\n");
06281    else
06282       ast_debug(3, "This channel will not be able to handle video.\n");
06283 
06284    if ((ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || (ast_test_flag(&i->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) ||
06285        (ast_test_flag(&i->flags[1], SIP_PAGE2_FAX_DETECT))) {
06286       int features = DSP_FEATURE_DIGIT_DETECT;
06287 
06288       if (ast_test_flag(&i->flags[1], SIP_PAGE2_FAX_DETECT)) {
06289          features |= DSP_FEATURE_FAX_DETECT;
06290       }
06291 
06292       i->dsp = ast_dsp_new();
06293       ast_dsp_set_features(i->dsp, features);
06294       if (global_relaxdtmf)
06295          ast_dsp_set_digitmode(i->dsp, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
06296          }
06297 
06298    /* Set file descriptors for audio, video, realtime text and UDPTL as needed */
06299    if (i->rtp) {
06300       ast_channel_set_fd(tmp, 0, ast_rtp_fd(i->rtp));
06301       ast_channel_set_fd(tmp, 1, ast_rtcp_fd(i->rtp));
06302    }
06303    if (needvideo && i->vrtp) {
06304       ast_channel_set_fd(tmp, 2, ast_rtp_fd(i->vrtp));
06305       ast_channel_set_fd(tmp, 3, ast_rtcp_fd(i->vrtp));
06306    }
06307    if (needtext && i->trtp) 
06308       ast_channel_set_fd(tmp, 4, ast_rtp_fd(i->trtp));
06309    if (i->udptl)
06310       ast_channel_set_fd(tmp, 5, ast_udptl_fd(i->udptl));
06311 
06312    if (state == AST_STATE_RING)
06313       tmp->rings = 1;
06314    tmp->adsicpe = AST_ADSI_UNAVAILABLE;
06315    tmp->writeformat = fmt;
06316    tmp->rawwriteformat = fmt;
06317    tmp->readformat = fmt;
06318    tmp->rawreadformat = fmt;
06319    tmp->tech_pvt = dialog_ref(i, "sip_new: set chan->tech_pvt to i");
06320 
06321    tmp->callgroup = i->callgroup;
06322    tmp->pickupgroup = i->pickupgroup;
06323    tmp->cid.cid_pres = i->callingpres;
06324    if (!ast_strlen_zero(i->parkinglot))
06325       ast_string_field_set(tmp, parkinglot, i->parkinglot);
06326    if (!ast_strlen_zero(i->accountcode))
06327       ast_string_field_set(tmp, accountcode, i->accountcode);
06328    if (i->amaflags)
06329       tmp->amaflags = i->amaflags;
06330    if (!ast_strlen_zero(i->language))
06331       ast_string_field_set(tmp, language, i->language);
06332    i->owner = tmp;
06333    ast_module_ref(ast_module_info->self);
06334    ast_copy_string(tmp->context, i->context, sizeof(tmp->context));
06335    /*Since it is valid to have extensions in the dialplan that have unescaped characters in them
06336     * we should decode the uri before storing it in the channel, but leave it encoded in the sip_pvt
06337     * structure so that there aren't issues when forming URI's
06338     */
06339    decoded_exten = ast_strdupa(i->exten);
06340    ast_uri_decode(decoded_exten);
06341    ast_copy_string(tmp->exten, decoded_exten, sizeof(tmp->exten));
06342 
06343    /* Don't use ast_set_callerid() here because it will
06344     * generate an unnecessary NewCallerID event  */
06345    tmp->cid.cid_ani = ast_strdup(i->cid_num);
06346    if (!ast_strlen_zero(i->rdnis))
06347       tmp->cid.cid_rdnis = ast_strdup(i->rdnis);
06348    
06349    if (!ast_strlen_zero(i->exten) && strcmp(i->exten, "s"))
06350       tmp->cid.cid_dnid = ast_strdup(i->exten);
06351 
06352    tmp->priority = 1;
06353    if (!ast_strlen_zero(i->uri))
06354       pbx_builtin_setvar_helper(tmp, "SIPURI", i->uri);
06355    if (!ast_strlen_zero(i->domain))
06356       pbx_builtin_setvar_helper(tmp, "SIPDOMAIN", i->domain);
06357    if (!ast_strlen_zero(i->callid))
06358       pbx_builtin_setvar_helper(tmp, "SIPCALLID", i->callid);
06359    if (i->rtp)
06360       ast_jb_configure(tmp, &global_jbconf);
06361 
06362    /* Set channel variables for this call from configuration */
06363    for (v = i->chanvars ; v ; v = v->next)
06364       pbx_builtin_setvar_helper(tmp, v->name, v->value);
06365 
06366    if (state != AST_STATE_DOWN && ast_pbx_start(tmp)) {
06367       ast_log(LOG_WARNING, "Unable to start PBX on %s\n", tmp->name);
06368       tmp->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
06369       ast_hangup(tmp);
06370       tmp = NULL;
06371    }
06372 
06373    if (i->do_history)
06374       append_history(i, "NewChan", "Channel %s - from %s", tmp->name, i->callid);
06375 
06376    /* Inform manager user about new channel and their SIP call ID */
06377    if (global_callevents)
06378       manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
06379          "Channel: %s\r\nUniqueid: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\n",
06380          tmp->name, tmp->uniqueid, "SIP", i->callid, i->fullcontact);
06381 
06382    return tmp;
06383 }

static int sip_park ( struct ast_channel chan1,
struct ast_channel chan2,
struct sip_request req,
int  seqno 
) [static]

Park a call using the subsystem in res_features.c This is executed in a separate thread.

Definition at line 17967 of file chan_sip.c.

References ast_channel::accountcode, ast_channel::amaflags, ast_calloc, AST_CAUSE_SWITCH_CONGESTION, ast_channel_alloc, ast_channel_lock, ast_channel_masquerade(), ast_channel_trylock, ast_channel_unlock, ast_copy_string(), ast_debug, ast_do_masquerade(), ast_free, ast_hangup(), ast_log(), ast_pthread_create_detached_background, AST_STATE_DOWN, ast_string_field_set, ast_strlen_zero(), ast_channel::context, copy_request(), ast_channel::exten, ast_channel::hangupcause, LOG_WARNING, ast_channel::name, parkinglot, ast_channel::parkinglot, ast_channel::priority, ast_channel::readformat, sip_park_thread(), sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and ast_channel::writeformat.

Referenced by handle_request_refer().

17968 {
17969    struct sip_dual *d;
17970    struct ast_channel *transferee, *transferer;
17971       /* Chan2m: The transferer, chan1m: The transferee */
17972    pthread_t th;
17973 
17974    transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name);
17975    transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name);
17976    if ((!transferer) || (!transferee)) {
17977       if (transferee) {
17978          transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
17979          ast_hangup(transferee);
17980       }
17981       if (transferer) {
17982          transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
17983          ast_hangup(transferer);
17984       }
17985       return -1;
17986    }
17987 
17988    /* Make formats okay */
17989    transferee->readformat = chan1->readformat;
17990    transferee->writeformat = chan1->writeformat;
17991 
17992    /* Prepare for taking over the channel */
17993    ast_channel_masquerade(transferee, chan1);
17994 
17995    /* Setup the extensions and such */
17996    ast_copy_string(transferee->context, chan1->context, sizeof(transferee->context));
17997    ast_copy_string(transferee->exten, chan1->exten, sizeof(transferee->exten));
17998    transferee->priority = chan1->priority;
17999       
18000    /* We make a clone of the peer channel too, so we can play
18001       back the announcement */
18002 
18003    /* Make formats okay */
18004    transferer->readformat = chan2->readformat;
18005    transferer->writeformat = chan2->writeformat;
18006    if (!ast_strlen_zero(chan2->parkinglot))
18007       ast_string_field_set(transferer, parkinglot, chan2->parkinglot);
18008 
18009    /* Prepare for taking over the channel.  Go ahead and grab this channel
18010     * lock here to avoid a deadlock with callbacks into the channel driver
18011     * that hold the channel lock and want the pvt lock.  */
18012    while (ast_channel_trylock(chan2)) {
18013       struct sip_pvt *pvt = chan2->tech_pvt;
18014       sip_pvt_unlock(pvt);
18015       usleep(1);
18016       sip_pvt_lock(pvt);
18017    }
18018    ast_channel_masquerade(transferer, chan2);
18019    ast_channel_unlock(chan2);
18020 
18021    /* Setup the extensions and such */
18022    ast_copy_string(transferer->context, chan2->context, sizeof(transferer->context));
18023    ast_copy_string(transferer->exten, chan2->exten, sizeof(transferer->exten));
18024    transferer->priority = chan2->priority;
18025 
18026    ast_channel_lock(transferer);
18027    if (ast_do_masquerade(transferer)) {
18028       ast_log(LOG_WARNING, "Masquerade failed :(\n");
18029       ast_channel_unlock(transferer);
18030       transferer->hangupcause = AST_CAUSE_SWITCH_CONGESTION;
18031       ast_hangup(transferer);
18032       return -1;
18033    }
18034    ast_channel_unlock(transferer);
18035    if (!transferer || !transferee) {
18036       if (!transferer) { 
18037          ast_debug(1, "No transferer channel, giving up parking\n");
18038       }
18039       if (!transferee) {
18040          ast_debug(1, "No transferee channel, giving up parking\n");
18041       }
18042       return -1;
18043    }
18044    if ((d = ast_calloc(1, sizeof(*d)))) {
18045 
18046       /* Save original request for followup */
18047       copy_request(&d->req, req);
18048       d->chan1 = transferee;  /* Transferee */
18049       d->chan2 = transferer;  /* Transferer */
18050       d->seqno = seqno;
18051       if (ast_pthread_create_detached_background(&th, NULL, sip_park_thread, d) < 0) {
18052          /* Could not start thread */
18053          if (d->req.data)
18054             ast_free(d->req.data);
18055          ast_free(d);   /* We don't need it anymore. If thread is created, d will be free'd
18056                   by sip_park_thread() */
18057          return 0;
18058       }
18059    } 
18060    return -1;
18061 }

static void * sip_park_thread ( void *  stuff  )  [static]

Park SIP call support function Starts in a new thread, then parks the call XXX Should we add a wait period after streaming audio and before hangup?? Sometimes the audio can't be heard before hangup.

Definition at line 17895 of file chan_sip.c.

References append_history, AST_CAUSE_NORMAL_CLEARING, ast_channel_lock, ast_channel_unlock, ast_debug, ast_do_masquerade(), ast_free, ast_hangup(), ast_log(), ast_park_call(), buf, sip_dual::chan1, sip_dual::chan2, copy_request(), sip_request::data, ext, free, ast_channel::hangupcause, LOG_ERROR, LOG_WARNING, ast_channel::name, sip_dual::req, sip_dual::seqno, ast_channel::tech_pvt, transmit_message_with_text(), transmit_notify_with_sipfrag(), transmit_response(), and TRUE.

Referenced by sip_park().

17896 {
17897    struct ast_channel *transferee, *transferer; /* Chan1: The transferee, Chan2: The transferer */
17898    struct sip_dual *d;
17899    struct sip_request req = {0,};
17900    int ext;
17901    int res;
17902 
17903    d = stuff;
17904    transferee = d->chan1;
17905    transferer = d->chan2;
17906    copy_request(&req, &d->req);
17907 
17908    if (!transferee || !transferer) {
17909       ast_log(LOG_ERROR, "Missing channels for parking! Transferer %s Transferee %s\n", transferer ? "<available>" : "<missing>", transferee ? "<available>" : "<missing>" );
17910       if (d->req.data)
17911          ast_free(d->req.data);
17912       free(d);
17913       return NULL;
17914    }
17915    ast_debug(4, "SIP Park: Transferer channel %s, Transferee %s\n", transferer->name, transferee->name);
17916 
17917    ast_channel_lock(transferee);
17918    if (ast_do_masquerade(transferee)) {
17919       ast_log(LOG_WARNING, "Masquerade failed.\n");
17920       transmit_response(transferer->tech_pvt, "503 Internal error", &req);
17921       ast_channel_unlock(transferee);
17922       if (d->req.data)
17923          ast_free(d->req.data);
17924       free(d);
17925       return NULL;
17926    } 
17927    ast_channel_unlock(transferee);
17928 
17929    res = ast_park_call(transferee, transferer, 0, &ext);
17930    
17931 
17932 #ifdef WHEN_WE_KNOW_THAT_THE_CLIENT_SUPPORTS_MESSAGE
17933    if (!res) {
17934       transmit_message_with_text(transferer->tech_pvt, "Unable to park call.\n");
17935    } else {
17936       /* Then tell the transferer what happened */
17937       sprintf(buf, "Call parked on extension '%d'", ext);
17938       transmit_message_with_text(transferer->tech_pvt, buf);
17939    }
17940 #endif
17941 
17942    /* Any way back to the current call??? */
17943    /* Transmit response to the REFER request */
17944    transmit_response(transferer->tech_pvt, "202 Accepted", &req);
17945    if (!res)   {
17946       /* Transfer succeeded */
17947       append_history(transferer->tech_pvt, "SIPpark", "Parked call on %d", ext);
17948       transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "200 OK", TRUE);
17949       transferer->hangupcause = AST_CAUSE_NORMAL_CLEARING;
17950       ast_hangup(transferer); /* This will cause a BYE */
17951       ast_debug(1, "SIP Call parked on extension '%d'\n", ext);
17952    } else {
17953       transmit_notify_with_sipfrag(transferer->tech_pvt, d->seqno, "503 Service Unavailable", TRUE);
17954       append_history(transferer->tech_pvt, "SIPpark", "Parking failed\n");
17955       ast_debug(1, "SIP Call parked failed \n");
17956       /* Do not hangup call */
17957    }
17958    if (d->req.data)
17959       ast_free(d->req.data);
17960    free(d);
17961    return NULL;
17962 }

static int sip_parse_host ( char *  line,
int  lineno,
char **  hostname,
int *  portnum,
enum sip_transport transport 
) [static]

Small function to parse a config line for a host with a transport i.e. tls://www.google.com:8056.

Definition at line 21292 of file chan_sip.c.

References ast_log(), LOG_NOTICE, SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, SIP_TRANSPORT_UDP, STANDARD_SIP_PORT, and STANDARD_TLS_PORT.

Referenced by sip_register().

21293 {
21294    char *port;
21295 
21296    if ((*hostname = strstr(line, "://"))) {
21297       *hostname += 3;
21298 
21299       if (!strncasecmp(line, "tcp", 3))
21300          *transport = SIP_TRANSPORT_TCP;
21301       else if (!strncasecmp(line, "tls", 3))
21302          *transport = SIP_TRANSPORT_TLS;
21303       else if (!strncasecmp(line, "udp", 3))
21304          *transport = SIP_TRANSPORT_UDP;
21305       else
21306          ast_log(LOG_NOTICE, "'%.3s' is not a valid transport type on line %d of sip.conf. defaulting to udp.\n", line, lineno);
21307    } else {
21308       *hostname = line;
21309       *transport = SIP_TRANSPORT_UDP;
21310    }
21311 
21312    if ((line = strrchr(*hostname, '@')))
21313       line++;
21314    else
21315       line = *hostname;
21316 
21317    if ((port = strrchr(line, ':'))) {
21318       *port++ = '\0';
21319 
21320       if (!sscanf(port, "%5u", portnum)) {
21321          ast_log(LOG_NOTICE, "'%s' is not a valid port number on line %d of sip.conf. using default.\n", port, lineno);
21322          port = NULL;
21323       }
21324    }
21325 
21326    if (!port) {
21327       if (*transport & SIP_TRANSPORT_TLS) {
21328          *portnum = STANDARD_TLS_PORT;
21329       } else {
21330          *portnum = STANDARD_SIP_PORT;
21331       }
21332    }
21333 
21334    return 0;
21335 }

static void sip_peer_hold ( struct sip_pvt p,
int  hold 
) [static]

Change onhold state of a peer using a pvt structure.

Definition at line 11952 of file chan_sip.c.

References ast_atomic_fetchadd_int(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), FALSE, find_peer(), FINDALLDEVICES, sip_peer::name, sip_peer::onHold, sip_pvt::peername, and unref_peer().

Referenced by process_sdp(), and update_call_counter().

11953 {
11954    struct sip_peer *peer = find_peer(p->peername, NULL, 1, FINDALLDEVICES, FALSE, 0);
11955 
11956    if (!peer)
11957       return;
11958 
11959    /* If they put someone on hold, increment the value... otherwise decrement it */
11960    ast_atomic_fetchadd_int(&peer->onHold, (hold ? +1 : -1));
11961 
11962    /* Request device state update */
11963    ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
11964    unref_peer(peer, "sip_peer_hold: from find_peer operation");
11965    
11966    return;
11967 }

static void sip_poke_all_peers ( void   )  [static]

Send a poke to all known peers Space them out 100 ms apart XXX We might have a cool algorithm for this or use random - any suggestions?

Definition at line 24543 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock(), ao2_t_iterator_next, ao2_unlock(), AST_SCHED_REPLACE_UNREF, peers, sip_peer::pokeexpire, ref_peer(), sched, sip_poke_peer_s(), and unref_peer().

Referenced by load_module(), and sip_do_reload().

24544 {
24545    int ms = 0;
24546    struct ao2_iterator i;
24547    struct sip_peer *peer;
24548 
24549    if (!speerobjs)   /* No peers, just give up */
24550       return;
24551 
24552    i = ao2_iterator_init(peers, 0);
24553    while ((peer = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
24554       ao2_lock(peer);
24555       ms += 100;
24556       AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, ms, sip_poke_peer_s, peer,
24557             unref_peer(_data, "removing poke peer ref"),
24558             unref_peer(peer, "removing poke peer ref"),
24559             ref_peer(peer, "adding poke peer ref"));
24560       ao2_unlock(peer);
24561       unref_peer(peer, "toss iterator peer ptr");
24562    }
24563    ao2_iterator_destroy(&i);
24564 }

static int sip_poke_noanswer ( const void *  data  )  [static]

React to lack of answer to Qualify poke.

Definition at line 21916 of file chan_sip.c.

References ast_check_realtime(), AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_log(), AST_SCHED_REPLACE_UNREF, ast_update_realtime(), sip_peer::call, DEFAULT_FREQ_NOTOK, dialog_unlink_all(), dialog_unref(), EVENT_FLAG_SYSTEM, FALSE, sip_peer::lastms, LOG_NOTICE, manager_event, sip_peer::name, sip_settings::peer_rtupdate, sip_peer::pokeexpire, ref_peer(), register_peer_exten(), sched, SENTINEL, sip_cfg, sip_poke_peer_s(), TRUE, and unref_peer().

Referenced by sip_poke_peer(), and sip_show_sched().

21917 {
21918    struct sip_peer *peer = (struct sip_peer *)data;
21919    
21920    peer->pokeexpire = -1;
21921 
21922    if (peer->lastms > -1) {
21923       ast_log(LOG_NOTICE, "Peer '%s' is now UNREACHABLE!  Last qualify: %d\n", peer->name, peer->lastms);
21924       if (sip_cfg.peer_rtupdate) {
21925          ast_update_realtime(ast_check_realtime("sipregs") ? "sipregs" : "sippeers", "name", peer->name, "lastms", "-1", SENTINEL);
21926       }
21927       manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: SIP\r\nPeer: SIP/%s\r\nPeerStatus: Unreachable\r\nTime: %d\r\n", peer->name, -1);
21928       if (global_regextenonqualify) {
21929          register_peer_exten(peer, FALSE);
21930       }
21931    }
21932 
21933    if (peer->call) {
21934       dialog_unlink_all(peer->call, TRUE, TRUE);
21935       peer->call = dialog_unref(peer->call, "unref dialog peer->call");
21936       /* peer->call = sip_destroy(peer->call);*/
21937    }
21938    
21939    peer->lastms = -1;
21940    ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", peer->name);
21941 
21942    /* Try again quickly */
21943    AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, 
21944          DEFAULT_FREQ_NOTOK, sip_poke_peer_s, peer,
21945          unref_peer(_data, "removing poke peer ref"),
21946          unref_peer(peer, "removing poke peer ref"),
21947          ref_peer(peer, "adding poke peer ref"));
21948 
21949    /* Release the ref held by the running scheduler entry */
21950    unref_peer(peer, "release peer poke noanswer ref");
21951 
21952    return 0;
21953 }

static int sip_poke_peer ( struct sip_peer peer,
int  force 
) [static]

Check availability of peer, also keep NAT open.

Note:
This is done with 60 seconds between each ping, unless forced by cli or manager. If peer is unreachable, we check every 10th second by default.

Definition at line 21960 of file chan_sip.c.

References sip_peer::addr, ao2_t_link, ao2_t_unlink, ast_copy_flags, ast_copy_string(), ast_inet_ntoa(), ast_log(), AST_SCHED_DEL_UNREF, AST_SCHED_REPLACE_UNREF, ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_set, ast_strlen_zero(), ast_tvnow(), build_callid_pvt(), build_via(), sip_peer::call, copy_socket_data(), dialog_ref(), dialog_unlink_all(), dialog_unref(), dialogs, sip_peer::flags, sip_pvt::flags, sip_pvt::fullcontact, sip_peer::fullcontact, sip_peer::lastms, LOG_NOTICE, sip_peer::maxms, sip_pvt::ourip, sip_peer::pokeexpire, sip_peer::ps, sip_pvt::recv, ref_peer(), sip_pvt::relatedpeer, sip_pvt::sa, sched, sip_alloc(), SIP_FLAGS_TO_COPY, SIP_INVITE, SIP_OPTIONS, SIP_OUTGOING, SIP_PAGE2_FLAGS_TO_COPY, sip_poke_noanswer(), sip_peer::socket, sip_pvt::socket, sip_pvt::tohost, sip_peer::tohost, transmit_invite(), TRUE, unref_peer(), sip_pvt::username, and XMIT_ERROR.

Referenced by _sip_qualify_peer(), build_peer(), parse_register_contact(), reg_source_db(), and sip_poke_peer_s().

21961 {
21962    struct sip_pvt *p;
21963    int xmitres = 0;
21964    
21965    if ((!peer->maxms && !force) || !peer->addr.sin_addr.s_addr) {
21966       /* IF we have no IP, or this isn't to be monitored, return
21967         immediately after clearing things out */
21968       AST_SCHED_DEL_UNREF(sched, peer->pokeexpire,
21969             unref_peer(peer, "removing poke peer ref"));
21970       
21971       peer->lastms = 0;
21972       if (peer->call) {
21973          peer->call = dialog_unref(peer->call, "unref dialog peer->call");
21974       }
21975       return 0;
21976    }
21977    if (peer->call) {
21978       if (sipdebug) {
21979          ast_log(LOG_NOTICE, "Still have a QUALIFY dialog active, deleting\n");
21980       }
21981       dialog_unlink_all(peer->call, TRUE, TRUE);
21982       peer->call = dialog_unref(peer->call, "unref dialog peer->call");
21983       /* peer->call = sip_destroy(peer->call); */
21984    }
21985    if (!(p = sip_alloc(NULL, NULL, 0, SIP_OPTIONS, NULL))) {
21986       return -1;
21987    }
21988    peer->call = dialog_ref(p, "copy sip alloc from p to peer->call");
21989    
21990    p->sa = peer->addr;
21991    p->recv = peer->addr;
21992    copy_socket_data(&p->socket, &peer->socket);
21993    ast_copy_flags(&p->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
21994    ast_copy_flags(&p->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
21995 
21996    /* Send OPTIONs to peer's fullcontact */
21997    if (!ast_strlen_zero(peer->fullcontact))
21998       ast_string_field_set(p, fullcontact, peer->fullcontact);
21999 
22000    if (!ast_strlen_zero(peer->tohost))
22001       ast_string_field_set(p, tohost, peer->tohost);
22002    else
22003       ast_string_field_set(p, tohost, ast_inet_ntoa(peer->addr.sin_addr));
22004 
22005    /* Recalculate our side, and recalculate Call ID */
22006    ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip, p);
22007    build_via(p);
22008    ao2_t_unlink(dialogs, p, "About to change the callid -- remove the old name");
22009    build_callid_pvt(p);
22010    ao2_t_link(dialogs, p, "Linking in under new name");
22011 
22012    AST_SCHED_DEL_UNREF(sched, peer->pokeexpire,
22013          unref_peer(peer, "removing poke peer ref"));
22014    
22015    if (p->relatedpeer)
22016       p->relatedpeer = unref_peer(p->relatedpeer,"unsetting the relatedpeer field in the dialog, before it is set to something else.");
22017    p->relatedpeer = ref_peer(peer, "setting the relatedpeer field in the dialog");
22018    ast_set_flag(&p->flags[0], SIP_OUTGOING);
22019 #ifdef VOCAL_DATA_HACK
22020    ast_copy_string(p->username, "__VOCAL_DATA_SHOULD_READ_THE_SIP_SPEC__", sizeof(p->username));
22021    xmitres = transmit_invite(p, SIP_INVITE, 0, 2); /* sinks the p refcount */
22022 #else
22023    xmitres = transmit_invite(p, SIP_OPTIONS, 0, 2); /* sinks the p refcount */
22024 #endif
22025    peer->ps = ast_tvnow();
22026    if (xmitres == XMIT_ERROR) {
22027       sip_poke_noanswer(peer);   /* Immediately unreachable, network problems */
22028    } else if (!force) {
22029       AST_SCHED_REPLACE_UNREF(peer->pokeexpire, sched, peer->maxms * 2, sip_poke_noanswer, peer,
22030             unref_peer(_data, "removing poke peer ref"),
22031             unref_peer(peer, "removing poke peer ref"),
22032             ref_peer(peer, "adding poke peer ref"));
22033    }
22034    dialog_unref(p, "unref dialog at end of sip_poke_peer, obtained from sip_alloc, just before it goes out of scope");
22035    return 0;
22036 }

static int sip_poke_peer_s ( const void *  data  )  [static]

Poke peer (send qualify to check if peer is alive and well).

Definition at line 11271 of file chan_sip.c.

References sip_peer::pokeexpire, sip_poke_peer(), and unref_peer().

Referenced by handle_response_peerpoke(), reg_source_db(), sip_poke_all_peers(), sip_poke_noanswer(), and sip_show_sched().

11272 {
11273    struct sip_peer *peer = (struct sip_peer *)data;
11274 
11275    peer->pokeexpire = -1;
11276 
11277    sip_poke_peer(peer, 0);
11278 
11279    unref_peer(peer, "removing poke peer ref");
11280 
11281    return 0;
11282 }

static int sip_prepare_socket ( struct sip_pvt p  )  [static]

Todo:
document this function.

Definition at line 21161 of file chan_sip.c.

References ao2_alloc, ao2_ref, ao2_t_ref, ao2_t_unlink, ast_calloc, ast_copy_string(), ast_debug, ast_pthread_create_background, ast_strdup, ast_strlen_zero(), ast_tcptls_client_create(), ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, ast_tls_config::cipher, default_tls_cfg, ast_tcptls_session_instance::fd, ast_tcptls_session_args::name, name, sip_pvt::outboundproxy, ast_tcptls_session_args::remote_address, s, sip_real_dst(), sip_tcp_locate(), sip_tcp_worker_fn(), sip_tcptls_client_args_destructor(), sip_threadinfo_create(), SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, SIP_TRANSPORT_UDP, sip_pvt::socket, threadt, sip_pvt::tohost, and sip_proxy::transport.

Referenced by __sip_xmit().

21162 {
21163    struct sip_socket *s = &p->socket;
21164    static const char name[] = "SIP socket";
21165    struct sip_threadinfo *th = NULL;
21166    struct ast_tcptls_session_instance *tcptls_session;
21167    struct ast_tcptls_session_args tmp_ca = {
21168       .name = name,
21169       .accept_fd = -1,
21170    };
21171    struct ast_tcptls_session_args *ca;
21172 
21173    /* check to see if a socket is already active */
21174    if ((s->fd != -1) && (s->type == SIP_TRANSPORT_UDP)) {
21175       return s->fd;
21176    }
21177    if ((s->type & (SIP_TRANSPORT_TCP | SIP_TRANSPORT_TLS)) &&
21178          (s->tcptls_session) &&
21179          (s->tcptls_session->fd != -1)) {
21180       return s->tcptls_session->fd;
21181    }
21182 
21183    if (p->outboundproxy && p->outboundproxy->transport) {
21184       s->type = p->outboundproxy->transport;
21185    }
21186 
21187    if (s->type == SIP_TRANSPORT_UDP) {
21188       s->fd = sipsock;
21189       return s->fd;
21190    }
21191 
21192    /* At this point we are dealing with a TCP/TLS connection
21193     * 1. We need to check to see if a connectin thread exists
21194     *    for this address, if so use that.
21195     * 2. If a thread does not exist for this address, but the tcptls_session
21196     *    exists on the socket, the connection was closed.
21197     * 3. If no tcptls_session thread exists for the address, and no tcptls_session
21198     *    already exists on the socket, create a new one and launch a new thread.
21199     */
21200 
21201    /* 1.  check for existing threads */
21202    tmp_ca.remote_address = *(sip_real_dst(p));
21203    if ((tcptls_session = sip_tcp_locate(&tmp_ca.remote_address))) {
21204       s->fd = tcptls_session->fd;
21205       if (s->tcptls_session) {
21206          ao2_ref(s->tcptls_session, -1);
21207          s->tcptls_session = NULL;
21208       }
21209       s->tcptls_session = tcptls_session;
21210       return s->fd;
21211    /* 2.  Thread not found, if tcptls_session already exists, it once had a thread and is now terminated */
21212    } else if (s->tcptls_session) {
21213       return s->fd; /* XXX whether reconnection is ever necessary here needs to be investigated further */
21214    }
21215 
21216    /* 3.  Create a new TCP/TLS client connection */
21217    /* create new session arguments for the client connection */
21218    if (!(ca = ao2_alloc(sizeof(*ca), sip_tcptls_client_args_destructor)) ||
21219       !(ca->name = ast_strdup(name))) {
21220       goto create_tcptls_session_fail;
21221    }
21222    ca->accept_fd = -1;
21223    ca->remote_address = *(sip_real_dst(p));
21224    /* if type is TLS, we need to create a tls cfg for this session arg */
21225    if (s->type == SIP_TRANSPORT_TLS) {
21226       if (!(ca->tls_cfg = ast_calloc(1, sizeof(*ca->tls_cfg)))) {
21227          goto create_tcptls_session_fail;
21228       }
21229       memcpy(ca->tls_cfg, &default_tls_cfg, sizeof(*ca->tls_cfg));
21230 
21231       if (!(ca->tls_cfg->certfile = ast_strdup(default_tls_cfg.certfile)) ||
21232          !(ca->tls_cfg->cipher = ast_strdup(default_tls_cfg.cipher)) ||
21233          !(ca->tls_cfg->cafile = ast_strdup(default_tls_cfg.cafile)) ||
21234          !(ca->tls_cfg->capath = ast_strdup(default_tls_cfg.capath))) {
21235 
21236          goto create_tcptls_session_fail;
21237       }
21238 
21239       /* this host is used as the common name in ssl/tls */
21240       if (!ast_strlen_zero(p->tohost)) {
21241          ast_copy_string(ca->hostname, p->tohost, sizeof(ca->hostname));
21242       }
21243    }
21244    /* Create a client connection for address, this does not start the connection, just sets it up. */
21245    if (!(s->tcptls_session = ast_tcptls_client_create(ca))) {
21246       goto create_tcptls_session_fail;
21247    }
21248 
21249    s->fd = s->tcptls_session->fd;
21250 
21251    /* client connections need to have the sip_threadinfo object created before
21252     * the thread is detached.  This ensures the alert_pipe is up before it will
21253     * be used.  Note that this function links the new threadinfo object into the
21254     * threadt container. */
21255    if (!(th = sip_threadinfo_create(s->tcptls_session, s->type))) {
21256       goto create_tcptls_session_fail;
21257 
21258    }
21259 
21260    /* Give the new thread a reference to the tcptls_session */
21261    ao2_ref(s->tcptls_session, +1);
21262 
21263    if (ast_pthread_create_background(&ca->master, NULL, sip_tcp_worker_fn, s->tcptls_session)) {
21264       ast_debug(1, "Unable to launch '%s'.", ca->name);
21265       ao2_ref(s->tcptls_session, -1); /* take away the thread ref we just gave it */
21266       goto create_tcptls_session_fail;
21267    }
21268 
21269    return s->fd;
21270 
21271 create_tcptls_session_fail:
21272    if (ca) {
21273       ao2_t_ref(ca, -1, "failed to create client, getting rid of client tcptls_session arguments");
21274    }
21275    if (s->tcptls_session) {
21276       close(tcptls_session->fd);
21277       s->fd = tcptls_session->fd = -1;
21278       ao2_ref(s->tcptls_session, -1);
21279       s->tcptls_session = NULL;
21280    }
21281    if (th) {
21282       ao2_t_unlink(threadt, th, "Removing tcptls thread info object, thread failed to open");
21283    }
21284 
21285    return -1;
21286 }

static char * sip_prune_realtime ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Remove temporary realtime objects from memory (CLI).

Todo:
XXXX Propably needs an overhaul after removal of the devices

Definition at line 14259 of file chan_sip.c.

References sip_peer::addr, ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock(), ao2_t_callback, ao2_t_find, ao2_t_iterator_next, ao2_t_link, ao2_t_unlink, ao2_unlock(), ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_peer(), FALSE, ast_cli_args::fd, sip_peer::flags, ast_cli_args::line, ast_cli_args::n, sip_peer::name, name, OBJ_MULTIPLE, OBJ_NODATA, OBJ_POINTER, OBJ_UNLINK, peer_is_marked(), peers, peers_by_ip, ast_cli_args::pos, SIP_PAGE2_RTCACHEFRIENDS, strcasestr(), sip_peer::the_mark, TRUE, unref_peer(), ast_cli_entry::usage, and ast_cli_args::word.

14260 {
14261    struct sip_peer *peer, *pi;
14262    int prunepeer = FALSE;
14263    int multi = FALSE;
14264    char *name = NULL;
14265    regex_t regexbuf;
14266    struct ao2_iterator i;
14267    
14268    if (cmd == CLI_INIT) {
14269       e->command = "sip prune realtime [peer|all] [all|like]";
14270       e->usage =
14271          "Usage: sip prune realtime [peer [<name>|all|like <pattern>]|all]\n"
14272          "       Prunes object(s) from the cache.\n"
14273          "       Optional regular expression pattern is used to filter the objects.\n";
14274       return NULL;
14275    } else if (cmd == CLI_GENERATE) {
14276       if (a->pos == 4) {
14277          if (strcasestr(a->line, "realtime peer"))
14278             return complete_sip_peer(a->word, a->n, SIP_PAGE2_RTCACHEFRIENDS);
14279       }
14280       return NULL;
14281    }
14282    switch (a->argc) {
14283    case 4:
14284       name = a->argv[3];
14285       /* we accept a name in position 3, but keywords are not good. */
14286       if (!strcasecmp(name, "peer") || !strcasecmp(name, "like"))
14287          return CLI_SHOWUSAGE;
14288       prunepeer = TRUE;
14289       if (!strcasecmp(name, "all")) {
14290          multi = TRUE;
14291          name = NULL;
14292       }
14293       /* else a single name, already set */
14294       break;
14295    case 5:
14296       /* sip prune realtime {peer|like} name */
14297       name = a->argv[4];
14298       if (!strcasecmp(a->argv[3], "peer"))
14299          prunepeer = TRUE;
14300       else if (!strcasecmp(a->argv[3], "like")) {
14301          prunepeer = TRUE;
14302          multi = TRUE;
14303       } else
14304          return CLI_SHOWUSAGE;
14305       if (!strcasecmp(a->argv[4], "like"))
14306          return CLI_SHOWUSAGE;
14307       if (!multi && !strcasecmp(a->argv[4], "all")) {
14308          multi = TRUE;
14309          name = NULL;
14310       }
14311       break;
14312    case 6:
14313       name = a->argv[5];
14314       multi = TRUE;
14315       /* sip prune realtime {peer} like name */
14316       if (strcasecmp(a->argv[4], "like"))
14317          return CLI_SHOWUSAGE;
14318       if (!strcasecmp(a->argv[3], "peer")) {
14319          prunepeer = TRUE;
14320       } else
14321          return CLI_SHOWUSAGE;
14322       break;
14323    default:
14324       return CLI_SHOWUSAGE;
14325    }
14326 
14327    if (multi && name) {
14328       if (regcomp(&regexbuf, name, REG_EXTENDED | REG_NOSUB))
14329          return CLI_SHOWUSAGE;
14330    }
14331 
14332    if (multi) {
14333       if (prunepeer) {
14334          int pruned = 0;
14335          
14336          i = ao2_iterator_init(peers, 0);
14337          while ((pi = ao2_t_iterator_next(&i, "iterate thru peers table"))) {
14338             ao2_lock(pi);
14339             if (name && regexec(&regexbuf, pi->name, 0, NULL, 0)) {
14340                unref_peer(pi, "toss iterator peer ptr before continue");
14341                ao2_unlock(pi);
14342                continue;
14343             };
14344             if (ast_test_flag(&pi->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
14345                pi->the_mark = 1;
14346                pruned++;
14347             }
14348             ao2_unlock(pi);
14349             unref_peer(pi, "toss iterator peer ptr");
14350          }
14351          ao2_iterator_destroy(&i);
14352          if (pruned) {
14353             ao2_t_callback(peers, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, peer_is_marked, 0, 
14354                   "initiating callback to remove marked peers");
14355             ast_cli(a->fd, "%d peers pruned.\n", pruned);
14356          } else
14357             ast_cli(a->fd, "No peers found to prune.\n");
14358       }
14359    } else {
14360       if (prunepeer) {
14361          struct sip_peer tmp;
14362          ast_copy_string(tmp.name, name, sizeof(tmp.name));
14363          if ((peer = ao2_t_find(peers, &tmp, OBJ_POINTER | OBJ_UNLINK, "finding to unlink from peers"))) {
14364             if (peer->addr.sin_addr.s_addr) {
14365                ao2_t_unlink(peers_by_ip, peer, "unlinking peer from peers_by_ip also");
14366             }
14367             if (!ast_test_flag(&peer->flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
14368                ast_cli(a->fd, "Peer '%s' is not a Realtime peer, cannot be pruned.\n", name);
14369                /* put it back! */
14370                ao2_t_link(peers, peer, "link peer into peer table");
14371                if (peer->addr.sin_addr.s_addr) {
14372                   ao2_t_link(peers_by_ip, peer, "link peer into peers_by_ip table");
14373                }
14374                
14375             } else
14376                ast_cli(a->fd, "Peer '%s' pruned.\n", name);
14377             unref_peer(peer, "sip_prune_realtime: unref_peer: tossing temp peer ptr");
14378          } else
14379             ast_cli(a->fd, "Peer '%s' not found.\n", name);
14380       }
14381    }
14382 
14383    return CLI_SUCCESS;
14384 }

static char * sip_qualify_peer ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Send an OPTIONS packet to a SIP peer.

Definition at line 14538 of file chan_sip.c.

References _sip_qualify_peer(), ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, complete_sip_show_peer(), ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

14539 {
14540    switch (cmd) {
14541    case CLI_INIT:
14542       e->command = "sip qualify peer";
14543       e->usage =
14544          "Usage: sip qualify peer <name> [load]\n"
14545          "       Requests a response from one SIP peer and the current status.\n"
14546          "       Option \"load\" forces lookup of peer in realtime storage.\n";
14547       return NULL;
14548    case CLI_GENERATE:
14549       return complete_sip_show_peer(a->line, a->word, a->pos, a->n);
14550    }
14551    return _sip_qualify_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv);
14552 }

static int sip_queryoption ( struct ast_channel chan,
int  option,
void *  data,
int *  datalen 
) [static]

Query an option on a SIP dialog.

Definition at line 3885 of file chan_sip.c.

References ast_log(), AST_OPTION_T38_STATE, ast_test_flag, chan, sip_pvt::flags, LOG_ERROR, SIP_PAGE2_T38SUPPORT, sip_pvt_lock, sip_pvt_unlock, t38properties::state, sip_pvt::t38, T38_ENABLED, T38_LOCAL_REINVITE, T38_PEER_REINVITE, T38_STATE_NEGOTIATED, T38_STATE_NEGOTIATING, T38_STATE_UNAVAILABLE, T38_STATE_UNKNOWN, and ast_channel::tech_pvt.

03886 {
03887    int res = -1;
03888    enum ast_t38_state state = T38_STATE_UNAVAILABLE;
03889    struct sip_pvt *p = (struct sip_pvt *) chan->tech_pvt;
03890 
03891    switch (option) {
03892    case AST_OPTION_T38_STATE:
03893       /* Make sure we got an ast_t38_state enum passed in */
03894       if (*datalen != sizeof(enum ast_t38_state)) {
03895          ast_log(LOG_ERROR, "Invalid datalen for AST_OPTION_T38_STATE option. Expected %d, got %d\n", (int)sizeof(enum ast_t38_state), *datalen);
03896          return -1;
03897       }
03898 
03899       sip_pvt_lock(p);
03900 
03901       /* Now if T38 support is enabled we need to look and see what the current state is to get what we want to report back */
03902       if (ast_test_flag(&p->flags[1], SIP_PAGE2_T38SUPPORT)) {
03903          switch (p->t38.state) {
03904          case T38_LOCAL_REINVITE:
03905          case T38_PEER_REINVITE:
03906             state = T38_STATE_NEGOTIATING;
03907             break;
03908          case T38_ENABLED:
03909             state = T38_STATE_NEGOTIATED;
03910             break;
03911          default:
03912             state = T38_STATE_UNKNOWN;
03913          }
03914       }
03915 
03916       sip_pvt_unlock(p);
03917 
03918       *((enum ast_t38_state *) data) = state;
03919       res = 0;
03920 
03921       break;
03922    default:
03923       break;
03924    }
03925 
03926    return res;
03927 }

static struct ast_frame * sip_read ( struct ast_channel ast  )  [static]

Read SIP RTP from channel.

Definition at line 6631 of file chan_sip.c.

References ast_channel::_state, ast_async_goto(), ast_channel_lock, ast_channel_unlock, ast_exists_extension(), AST_FRAME_VOICE, ast_log(), ast_null_frame, AST_STATE_UP, ast_test_flag, ast_verbose, FALSE, sip_pvt::flags, ast_frame::frametype, INV_EARLY_MEDIA, sip_pvt::invitestate, sip_pvt::lastrtprx, LOG_NOTICE, pbx_builtin_setvar_helper(), S_OR, SIP_PAGE2_FAX_DETECT, sip_pvt_lock, sip_pvt_unlock, sip_rtp_read(), ast_channel::tech_pvt, and VERBOSE_PREFIX_2.

06632 {
06633    struct ast_frame *fr;
06634    struct sip_pvt *p = ast->tech_pvt;
06635    int faxdetected = FALSE;
06636 
06637    sip_pvt_lock(p);
06638    fr = sip_rtp_read(ast, p, &faxdetected);
06639    p->lastrtprx = time(NULL);
06640 
06641    /* If we detect a CNG tone and fax detection is enabled then send us off to the fax extension */
06642    if (faxdetected && ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT)) {
06643       ast_channel_lock(ast);
06644       if (strcmp(ast->exten, "fax")) {
06645          const char *target_context = S_OR(ast->macrocontext, ast->context);
06646          ast_channel_unlock(ast);
06647          if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
06648             ast_verbose(VERBOSE_PREFIX_2 "Redirecting '%s' to fax extension\n", ast->name);
06649             pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
06650             if (ast_async_goto(ast, target_context, "fax", 1)) {
06651                ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
06652             }
06653             fr = &ast_null_frame;
06654          } else {
06655             ast_log(LOG_NOTICE, "Fax detected but no fax extension\n");
06656                         }
06657       } else {
06658          ast_channel_unlock(ast);
06659                 }
06660         }
06661 
06662    /* Only allow audio through if they sent progress with SDP, or if the channel is actually answered */
06663    if (fr && fr->frametype == AST_FRAME_VOICE && p->invitestate != INV_EARLY_MEDIA && ast->_state != AST_STATE_UP) {
06664       fr = &ast_null_frame;
06665    }
06666 
06667    sip_pvt_unlock(p);
06668 
06669    return fr;
06670 }

static struct sockaddr_in * sip_real_dst ( const struct sip_pvt p  )  [static]

The real destination address for a write.

Definition at line 3078 of file chan_sip.c.

References ast_test_flag, sip_pvt::flags, sip_proxy::ip, sip_pvt::outboundproxy, sip_pvt::recv, sip_pvt::sa, SIP_NAT, and SIP_NAT_ROUTE.

Referenced by __sip_xmit(), check_via(), retrans_pkt(), send_response(), show_channels_cb(), sip_debug_test_pvt(), and sip_prepare_socket().

03079 {
03080    if (p->outboundproxy)
03081       return &p->outboundproxy->ip;
03082 
03083    return ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE ? &p->recv : &p->sa;
03084 }

static int sip_refer_allocate ( struct sip_pvt p  )  [static]

Allocate SIP refer structure.

Definition at line 11031 of file chan_sip.c.

References ast_calloc, and sip_pvt::refer.

Referenced by get_also_info(), handle_request_invite(), handle_request_refer(), and transmit_refer().

11032 {
11033    p->refer = ast_calloc(1, sizeof(struct sip_refer)); 
11034    return p->refer ? 1 : 0;
11035 }

static int sip_reg_timeout ( const void *  data  )  [static]

Registration timeout, register again Registered as a timeout handler during transmit_register(), to retransmit the packet if a reply does not come back. This is called by the scheduler so the event is not pending anymore when we are called.

Definition at line 10715 of file chan_sip.c.

References __sip_pretend_ack(), ast_dnsmgr_refresh(), ast_log(), sip_registry::call, dialog_unref(), sip_registry::dnsmgr, EVENT_FLAG_SYSTEM, sip_registry::hostname, LOG_NOTICE, manager_event, sip_pvt::needdestroy, REG_STATE_FAILED, REG_STATE_UNREGISTERED, sip_registry::regattempts, sip_pvt::registry, registry_unref(), sip_registry::regstate, regstate2str(), sip_pvt_lock, sip_pvt_unlock, SIP_REGISTER, sip_registry::timeout, transmit_register(), and sip_registry::username.

Referenced by sip_show_sched(), and transmit_register().

10716 {
10717 
10718    /* if we are here, our registration timed out, so we'll just do it over */
10719    struct sip_registry *r = (struct sip_registry *)data; /* the ref count should have been bumped when the sched item was added */
10720    struct sip_pvt *p;
10721    int res;
10722 
10723    /* if we couldn't get a reference to the registry object, punt */
10724    if (!r)
10725       return 0;
10726 
10727    if (r->dnsmgr) {
10728       /* If the registration has timed out, maybe the IP changed.  Force a refresh. */
10729       ast_dnsmgr_refresh(r->dnsmgr);
10730    }
10731 
10732    ast_log(LOG_NOTICE, "   -- Registration for '%s@%s' timed out, trying again (Attempt #%d)\n", r->username, r->hostname, r->regattempts); 
10733    /* If the initial tranmission failed, we may not have an existing dialog,
10734     * so it is possible that r->call == NULL.
10735     * Otherwise destroy it, as we have a timeout so we don't want it.
10736     */
10737    if (r->call) {
10738       /* Unlink us, destroy old call.  Locking is not relevant here because all this happens
10739          in the single SIP manager thread. */
10740       p = r->call;
10741       sip_pvt_lock(p);
10742       p->needdestroy = 1;
10743       /* Pretend to ACK anything just in case */
10744       __sip_pretend_ack(p);
10745       sip_pvt_unlock(p);
10746 
10747       /* decouple the two objects */
10748       /* p->registry == r, so r has 2 refs, and the unref won't take the object away */
10749       if (p->registry)
10750          p->registry = registry_unref(p->registry, "p->registry unreffed");
10751       r->call = dialog_unref(r->call, "unrefing r->call");
10752    }
10753    /* If we have a limit, stop registration and give up */
10754    r->timeout = -1;
10755    if (global_regattempts_max && r->regattempts > global_regattempts_max) {
10756       /* Ok, enough is enough. Don't try any more */
10757       /* We could add an external notification here... 
10758          steal it from app_voicemail :-) */
10759       ast_log(LOG_NOTICE, "   -- Giving up forever trying to register '%s@%s'\n", r->username, r->hostname);
10760       r->regstate = REG_STATE_FAILED;
10761    } else {
10762       r->regstate = REG_STATE_UNREGISTERED;
10763       res=transmit_register(r, SIP_REGISTER, NULL, NULL);
10764    }
10765    manager_event(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: SIP\r\nUsername: %s\r\nDomain: %s\r\nStatus: %s\r\n", r->username, r->hostname, regstate2str(r->regstate));
10766    registry_unref(r, "unreffing registry_unref r");
10767    return 0;
10768 }

static int sip_register ( const char *  value,
int  lineno 
) [static]

Parse register=> line in sip.conf and add to registry.

Definition at line 7058 of file chan_sip.c.

References ast_atomic_fetchadd_int(), ast_calloc, ast_copy_string(), ast_free, ast_log(), ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ASTOBJ_CONTAINER_LINK, ASTOBJ_INIT, sip_registry::authuser, buf, sip_registry::callback, FALSE, hostname, INITIAL_CSEQ, LOG_ERROR, LOG_WARNING, sip_registry::peername, registry_unref(), regl, secret, sip_parse_host(), SIP_TRANSPORT_UDP, sip_registry::transport, and sip_registry::username.

Referenced by build_peer().

07059 {
07060    struct sip_registry *reg;
07061    int portnum = 0;
07062    enum sip_transport transport = SIP_TRANSPORT_UDP;
07063    char buf[256] = "";
07064    char *username = NULL;
07065    char *hostname=NULL, *secret=NULL, *authuser=NULL, *expire=NULL, *tmp=NULL;
07066    char *callback=NULL, *peername=NULL;
07067 
07068    if (!value)
07069       return -1;
07070    ast_copy_string(buf, value, sizeof(buf));
07071    tmp = strrchr(buf, '@');
07072 
07073    /* split [/extension][~expiry] */
07074    expire = strchr(tmp, '~');
07075    if (expire)
07076       *expire++ = '\0';
07077    callback = strrchr(tmp, '/');
07078    if (callback)
07079       *callback++ = '\0';
07080    if (ast_strlen_zero(callback))
07081       callback = "s";
07082 
07083    /* split [peername?][transport://] */
07084    tmp = strchr(buf, '?');
07085    if (tmp) {
07086       *tmp++ = '\0';
07087       peername = buf;
07088    } else {
07089       tmp = buf;
07090    }
07091    /* tmp is set at the beginning of [transport://] */
07092    sip_parse_host(tmp, lineno, &username, &portnum, &transport);
07093 
07094    /* First split around the last '@' then parse the two components. */
07095    hostname = strrchr(username, '@'); /* allow @ in the first part */
07096    if (hostname)
07097       *hostname++ = '\0';
07098    if (ast_strlen_zero(username) || ast_strlen_zero(hostname)) {
07099       ast_log(LOG_WARNING, "Format for registration is [transport://]user[@domain][:secret[:authuser]]@host[:port][/extension][~expiry] at line %d\n", lineno);
07100       return -1;
07101    }
07102    /* split user[:secret[:authuser]] */
07103    secret = strchr(username, ':');
07104    if (secret) {
07105       *secret++ = '\0';
07106       authuser = strchr(secret, ':');
07107       if (authuser)
07108          *authuser++ = '\0';
07109    }
07110 
07111    if (!(reg = ast_calloc(1, sizeof(*reg)))) {
07112       ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry entry\n");
07113       return -1;
07114    }
07115 
07116    if (ast_string_field_init(reg, 256)) {
07117       ast_log(LOG_ERROR, "Out of memory. Can't allocate SIP registry strings\n");
07118       ast_free(reg);
07119       return -1;
07120    }
07121 
07122    ast_atomic_fetchadd_int(&regobjs, 1);
07123    ASTOBJ_INIT(reg);
07124    ast_string_field_set(reg, callback, callback);
07125    if (!ast_strlen_zero(username))
07126       ast_string_field_set(reg, username, username);
07127    if (hostname)
07128       ast_string_field_set(reg, hostname, hostname);
07129    if (authuser)
07130       ast_string_field_set(reg, authuser, authuser);
07131    if (secret)
07132       ast_string_field_set(reg, secret, secret);
07133    if (peername) {
07134       ast_string_field_set(reg, peername, peername);
07135    }
07136    reg->transport = transport;
07137    reg->expire = -1;
07138    reg->configured_expiry = (expire ? atoi(expire) : default_expiry);
07139    reg->expiry = reg->configured_expiry;
07140    reg->timeout =  -1;
07141    reg->refresh = reg->expiry;
07142    reg->portno = portnum;
07143    reg->callid_valid = FALSE;
07144    reg->ocseq = INITIAL_CSEQ;
07145    ASTOBJ_CONTAINER_LINK(&regl, reg); /* Add the new registry entry to the list */
07146    registry_unref(reg, "unref the reg pointer");   /* release the reference given by ASTOBJ_INIT. The container has another reference */
07147    return 0;
07148 }

static void sip_registry_destroy ( struct sip_registry reg  )  [static]

Destroy registry object Objects created with the register= statement in static configuration.

Definition at line 5074 of file chan_sip.c.

References ast_atomic_fetchadd_int(), ast_debug, ast_dnsmgr_release(), ast_free, AST_SCHED_DEL, ast_string_field_free_memory, sip_registry::call, dialog_unlink_all(), dialog_unref(), sip_registry::dnsmgr, sip_registry::expire, sip_registry::hostname, sip_pvt::registry, registry_unref(), sched, sip_registry::timeout, TRUE, and sip_registry::username.

Referenced by registry_unref(), and unload_module().

05075 {
05076    /* Really delete */
05077    ast_debug(3, "Destroying registry entry for %s@%s\n", reg->username, reg->hostname);
05078 
05079    if (reg->call) {
05080       /* Clear registry before destroying to ensure
05081          we don't get reentered trying to grab the registry lock */
05082       reg->call->registry = registry_unref(reg->call->registry, "destroy reg->call->registry");
05083       ast_debug(3, "Destroying active SIP dialog for registry %s@%s\n", reg->username, reg->hostname);
05084       dialog_unlink_all(reg->call, TRUE, TRUE);
05085       reg->call = dialog_unref(reg->call, "unref reg->call");
05086       /* reg->call = sip_destroy(reg->call); */
05087    }
05088    AST_SCHED_DEL(sched, reg->expire);  
05089    AST_SCHED_DEL(sched, reg->timeout);
05090    
05091    ast_string_field_free_memory(reg);
05092    ast_atomic_fetchadd_int(&regobjs, -1);
05093    ast_dnsmgr_release(reg->dnsmgr);
05094    ast_free(reg);
05095 }

static int sip_reinvite_retry ( const void *  data  )  [static]

Reset the NEEDREINVITE flag after waiting when we get 491 on a Re-invite to avoid race conditions between asterisk servers. Called from the scheduler.

Definition at line 16818 of file chan_sip.c.

References ast_set_flag, check_pendings(), dialog_unref(), SIP_NEEDREINVITE, sip_pvt_lock, and sip_pvt_unlock.

Referenced by handle_response_invite(), and sip_show_sched().

16819 {
16820    struct sip_pvt *p = (struct sip_pvt *) data;
16821 
16822    sip_pvt_lock(p); /* called from schedule thread which requires a lock */
16823    ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
16824    p->waitid = -1;
16825    check_pendings(p);
16826    sip_pvt_unlock(p);
16827    dialog_unref(p, "unref the dialog ptr from sip_reinvite_retry, because it held a dialog ptr");
16828    return 0;
16829 }

static char * sip_reload ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Force reload of module from cli.

Definition at line 24619 of file chan_sip.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_verbose, CHANNEL_CLI_RELOAD, CHANNEL_MODULE_RELOAD, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, restart_monitor(), sip_reload_lock, TRUE, and ast_cli_entry::usage.

Referenced by reload().

24620 {
24621    
24622    switch (cmd) {
24623    case CLI_INIT:
24624       e->command = "sip reload";
24625       e->usage =
24626          "Usage: sip reload\n"
24627          "       Reloads SIP configuration from sip.conf\n";
24628       return NULL;
24629    case CLI_GENERATE:
24630       return NULL;
24631    }
24632 
24633    ast_mutex_lock(&sip_reload_lock);
24634    if (sip_reloading) 
24635       ast_verbose("Previous SIP reload not yet done\n");
24636    else {
24637       sip_reloading = TRUE;
24638       sip_reloadreason = (a && a->fd) ? CHANNEL_CLI_RELOAD : CHANNEL_MODULE_RELOAD;
24639    }
24640    ast_mutex_unlock(&sip_reload_lock);
24641    restart_monitor();
24642 
24643    return CLI_SUCCESS;
24644 }

static struct ast_channel * sip_request_call ( const char *  type,
int  format,
void *  data,
int *  cause 
) [static]

PBX interface function -build SIP pvt structure SIP calls initiated by the PBX arrive here.

 * 	SIP Dial string syntax
 *		SIP/exten@host!dnid
 *	or	SIP/host/exten!dnid
 *	or	SIP/host!dnid
 * 

Definition at line 22150 of file chan_sip.c.

References ao2_t_link, ao2_t_unlink, ast_calloc, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_SWITCH_CONGESTION, AST_CAUSE_UNREGISTERED, ast_copy_string(), ast_debug, AST_FORMAT_AUDIO_MASK, ast_getformatname(), ast_getformatname_multiple(), ast_log(), ast_sip_ouraddrfor(), AST_STATE_DOWN, ast_string_field_set, ast_strlen_zero(), ast_update_use_count(), build_callid_pvt(), build_via(), create_addr(), dialog_unlink_all(), dialog_unref(), dialogs, EVENT_FLAG_SYSTEM, ext, LOG_ERROR, LOG_NOTICE, LOG_WARNING, manager_event, sip_pvt::options, sip_pvt::outgoing_call, sip_pvt::peername, restart_monitor(), secret, set_socket_transport(), sip_alloc(), SIP_INVITE, sip_new(), sip_pvt_lock, sip_pvt_unlock, SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, SIP_TRANSPORT_UDP, sip_pvt::socket, and TRUE.

22151 {
22152    struct sip_pvt *p;
22153    struct ast_channel *tmpc = NULL;
22154    char *ext = NULL, *host;
22155    char tmp[256];
22156    char *dest = data;
22157    char *dnid;
22158    char *secret = NULL;
22159    char *md5secret = NULL;
22160    char *authname = NULL;
22161    char *trans = NULL;
22162    enum sip_transport transport = 0;
22163    int oldformat = format;
22164 
22165    /* mask request with some set of allowed formats.
22166     * XXX this needs to be fixed.
22167     * The original code uses AST_FORMAT_AUDIO_MASK, but it is
22168     * unclear what to use here. We have global_capabilities, which is
22169     * configured from sip.conf, and sip_tech.capabilities, which is
22170     * hardwired to all audio formats.
22171     */
22172    format &= AST_FORMAT_AUDIO_MASK;
22173    if (!format) {
22174       ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format %s while capability is %s\n", ast_getformatname(oldformat), ast_getformatname(global_capability));
22175       *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;   /* Can't find codec to connect to host */
22176       return NULL;
22177    }
22178    ast_debug(1, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat));
22179 
22180    if (!(p = sip_alloc(NULL, NULL, 0, SIP_INVITE, NULL))) {
22181       ast_log(LOG_ERROR, "Unable to build sip pvt data for '%s' (Out of memory or socket error)\n", dest);
22182       *cause = AST_CAUSE_SWITCH_CONGESTION;
22183       return NULL;
22184    }
22185 
22186    p->outgoing_call = TRUE;
22187 
22188    if (!(p->options = ast_calloc(1, sizeof(*p->options)))) {
22189       dialog_unlink_all(p, TRUE, TRUE);
22190       dialog_unref(p, "unref dialog p from mem fail");
22191       /* sip_destroy(p); */
22192       ast_log(LOG_ERROR, "Unable to build option SIP data structure - Out of memory\n");
22193       *cause = AST_CAUSE_SWITCH_CONGESTION;
22194       return NULL;
22195    }
22196 
22197    /* Save the destination, the SIP dial string */
22198    ast_copy_string(tmp, dest, sizeof(tmp));
22199 
22200 
22201    /* Find DNID and take it away */
22202    dnid = strchr(tmp, '!');
22203    if (dnid != NULL) {
22204       *dnid++ = '\0';
22205       ast_string_field_set(p, todnid, dnid);
22206    }
22207 
22208    /* Find at sign - @ */
22209    host = strchr(tmp, '@');
22210    if (host) {
22211       *host++ = '\0';
22212       ext = tmp;
22213       secret = strchr(ext, ':');
22214    }
22215    if (secret) {
22216       *secret++ = '\0';
22217       md5secret = strchr(secret, ':');
22218    }
22219    if (md5secret) {
22220       *md5secret++ = '\0';
22221       authname = strchr(md5secret, ':');
22222    }
22223    if (authname) {
22224       *authname++ = '\0';
22225       trans = strchr(authname, ':');
22226    }
22227    if (trans) {
22228       *trans++ = '\0';
22229       if (!strcasecmp(trans, "tcp"))
22230          transport = SIP_TRANSPORT_TCP;
22231       else if (!strcasecmp(trans, "tls"))
22232          transport = SIP_TRANSPORT_TLS;
22233       else {
22234          if (strcasecmp(trans, "udp"))
22235             ast_log(LOG_WARNING, "'%s' is not a valid transport option to Dial() for SIP calls, using udp by default.\n", trans);
22236          transport = SIP_TRANSPORT_UDP;
22237       }
22238    } else { /* use default */
22239       transport = SIP_TRANSPORT_UDP;
22240    }
22241 
22242    if (!host) {
22243       ext = strchr(tmp, '/');
22244       if (ext) 
22245          *ext++ = '\0';
22246       host = tmp;
22247    }
22248 
22249    set_socket_transport(&p->socket, transport);
22250 
22251    /* We now have 
22252       host = peer name, DNS host name or DNS domain (for SRV) 
22253       ext = extension (user part of URI)
22254       dnid = destination of the call (applies to the To: header)
22255    */
22256    if (create_addr(p, host, NULL, 1)) {
22257       *cause = AST_CAUSE_UNREGISTERED;
22258       ast_debug(3, "Cant create SIP call - target device not registered\n");
22259       dialog_unlink_all(p, TRUE, TRUE);
22260       dialog_unref(p, "unref dialog p UNREGISTERED");
22261       /* sip_destroy(p); */
22262       return NULL;
22263    }
22264    if (ast_strlen_zero(p->peername) && ext)
22265       ast_string_field_set(p, peername, ext);
22266    /* Recalculate our side, and recalculate Call ID */
22267    ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip, p);
22268    build_via(p);
22269    ao2_t_unlink(dialogs, p, "About to change the callid -- remove the old name");
22270    build_callid_pvt(p);
22271    ao2_t_link(dialogs, p, "Linking in under new name");
22272    
22273    /* We have an extension to call, don't use the full contact here */
22274    /* This to enable dialing registered peers with extension dialling,
22275       like SIP/peername/extension   
22276       SIP/peername will still use the full contact 
22277     */
22278    if (ext) {
22279       ast_string_field_set(p, username, ext);
22280       ast_string_field_set(p, fullcontact, NULL);
22281    }
22282    if (secret && !ast_strlen_zero(secret))
22283       ast_string_field_set(p, peersecret, secret);
22284 
22285    if (md5secret && !ast_strlen_zero(md5secret))
22286       ast_string_field_set(p, peermd5secret, md5secret);
22287 
22288    if (authname && !ast_strlen_zero(authname))
22289       ast_string_field_set(p, authname, authname);
22290 #if 0
22291    printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
22292 #endif
22293    p->prefcodec = oldformat;           /* Format for this call */
22294    p->jointcapability = oldformat;
22295    sip_pvt_lock(p);
22296    tmpc = sip_new(p, AST_STATE_DOWN, host);  /* Place the call */
22297    if (global_callevents)
22298       manager_event(EVENT_FLAG_SYSTEM, "ChannelUpdate",
22299          "Channel: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\nPeername: %s\r\n",
22300          p->owner? p->owner->name : "", "SIP", p->callid, p->fullcontact, p->peername);
22301    sip_pvt_unlock(p);
22302    if (!tmpc) {
22303       dialog_unlink_all(p, TRUE, TRUE);
22304       /* sip_destroy(p); */
22305    }
22306    dialog_unref(p, "toss pvt ptr at end of sip_request_call");
22307    ast_update_use_count();
22308    restart_monitor();
22309    return tmpc;
22310 }

static int sip_reregister ( const void *  data  )  [static]

Update registration with SIP Proxy. Called from the scheduler when the previous registration expires, so we don't have to cancel the pending event. We assume the reference so the sip_registry is valid, since it is stored in the scheduled event anyways.

Definition at line 10677 of file chan_sip.c.

References __sip_do_register(), append_history, ast_log(), sip_registry::call, sip_registry::configured_expiry, sip_pvt::do_history, sip_registry::expire, sip_registry::expiry, sip_registry::hostname, LOG_NOTICE, registry_unref(), and sip_registry::username.

Referenced by handle_response_register(), sip_send_all_registers(), and sip_show_sched().

10678 {
10679    /* if we are here, we know that we need to reregister. */
10680    struct sip_registry *r= (struct sip_registry *) data;
10681 
10682    /* if we couldn't get a reference to the registry object, punt */
10683    if (!r)
10684       return 0;
10685 
10686    if (r->call && r->call->do_history)
10687       append_history(r->call, "RegistryRenew", "Account: %s@%s", r->username, r->hostname);
10688    /* Since registry's are only added/removed by the the monitor thread, this
10689       may be overkill to reference/dereference at all here */
10690    if (sipdebug)
10691       ast_log(LOG_NOTICE, "   -- Re-registration for  %s@%s\n", r->username, r->hostname);
10692 
10693    r->expire = -1;
10694    r->expiry = r->configured_expiry;
10695    __sip_do_register(r);
10696    registry_unref(r, "unref the re-register scheduled event");
10697    return 0;
10698 }

static struct ast_frame * sip_rtp_read ( struct ast_channel ast,
struct sip_pvt p,
int *  faxdetect 
) [static]

Read RTP from network.

Definition at line 6541 of file chan_sip.c.

References ast_debug, ast_dsp_free(), ast_dsp_process(), ast_dsp_set_features(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_getformatname(), ast_log(), ast_null_frame, ast_rtcp_read(), ast_rtp_read(), ast_set_read_format(), ast_set_write_format(), ast_test_flag, ast_udptl_read(), ast_verbose, sip_pvt::dsp, DSP_FEATURE_DIGIT_DETECT, f, ast_channel::fdno, sip_pvt::flags, sip_pvt::jointcapability, LOG_DEBUG, ast_channel::name, ast_channel::nativeformats, option_debug, sip_pvt::owner, ast_channel::readformat, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, SIP_PAGE2_FAX_DETECT, sip_pvt::trtp, sip_pvt::udptl, sip_pvt::vrtp, and ast_channel::writeformat.

Referenced by sip_read().

06542 {
06543    /* Retrieve audio/etc from channel.  Assumes p->lock is already held. */
06544    struct ast_frame *f;
06545    
06546    if (!p->rtp) {
06547       /* We have no RTP allocated for this channel */
06548       return &ast_null_frame;
06549    }
06550 
06551    switch(ast->fdno) {
06552    case 0:
06553       f = ast_rtp_read(p->rtp);  /* RTP Audio */
06554       break;
06555    case 1:
06556       f = ast_rtcp_read(p->rtp); /* RTCP Control Channel */
06557       break;
06558    case 2:
06559       f = ast_rtp_read(p->vrtp); /* RTP Video */
06560       break;
06561    case 3:
06562       f = ast_rtcp_read(p->vrtp);   /* RTCP Control Channel for video */
06563       break;
06564    case 4:
06565       f = ast_rtp_read(p->trtp); /* RTP Text */
06566       if (sipdebug_text) {
06567          int i;
06568          unsigned char* arr = f->data.ptr;
06569          for (i=0; i < f->datalen; i++)
06570             ast_verbose("%c", (arr[i] > ' ' && arr[i] < '}') ? arr[i] : '.');
06571          ast_verbose(" -> ");
06572          for (i=0; i < f->datalen; i++)
06573             ast_verbose("%02X ", arr[i]);
06574          ast_verbose("\n");
06575       }
06576       break;
06577    case 5:
06578       f = ast_udptl_read(p->udptl); /* UDPTL for T.38 */
06579       break;
06580    default:
06581       f = &ast_null_frame;
06582    }
06583    /* Don't forward RFC2833 if we're not supposed to */
06584    if (f && (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) &&
06585        (ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_RFC2833)) {
06586       ast_debug(1, "Ignoring DTMF (%c) RTP frame because dtmfmode is not RFC2833\n", f->subclass);
06587       return &ast_null_frame;
06588    }
06589 
06590    /* We already hold the channel lock */
06591    if (!p->owner || (f && f->frametype != AST_FRAME_VOICE))
06592       return f;
06593 
06594    if (f && f->subclass != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) {
06595       if (!(f->subclass & p->jointcapability)) {
06596          ast_debug(1, "Bogus frame of format '%s' received from '%s'!\n",
06597             ast_getformatname(f->subclass), p->owner->name);
06598          return &ast_null_frame;
06599       }
06600       ast_debug(1, "Oooh, format changed to %d %s\n",
06601          f->subclass, ast_getformatname(f->subclass));
06602       p->owner->nativeformats = (p->owner->nativeformats & (AST_FORMAT_VIDEO_MASK | AST_FORMAT_TEXT_MASK)) | f->subclass;
06603       ast_set_read_format(p->owner, p->owner->readformat);
06604       ast_set_write_format(p->owner, p->owner->writeformat);
06605    }
06606 
06607    if (f && ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) || ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT)) && p->dsp) {
06608       f = ast_dsp_process(p->owner, p->dsp, f);
06609                 if (f && f->frametype == AST_FRAME_DTMF) {
06610          if (f->subclass == 'f') {
06611                                 if (option_debug)
06612                                         ast_log(LOG_DEBUG, "Fax CNG detected on %s\n", ast->name);
06613                                 *faxdetect = 1;
06614             /* If we only needed this DSP for fax detection purposes we can just drop it now */
06615             if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_INBAND) {
06616                ast_dsp_set_features(p->dsp, DSP_FEATURE_DIGIT_DETECT);
06617             } else {
06618                ast_dsp_free(p->dsp);
06619                p->dsp = NULL;
06620             }
06621          } else {
06622             ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass);
06623          }
06624       }
06625    }
06626    
06627    return f;
06628 }

static void sip_scheddestroy ( struct sip_pvt p,
int  ms 
) [static]

Schedule destruction of SIP dialog.

Definition at line 3607 of file chan_sip.c.

References __sip_autodestruct(), append_history, ast_log(), ast_sched_add(), ast_verbose, sip_pvt::autokillid, sip_pvt::callid, dialog_ref(), sip_pvt::do_history, LOG_WARNING, sip_pvt::method, sched, sip_cancel_destroy(), sip_debug_test_pvt(), sip_methods, sip_st_dlg::st_active, sip_st_dlg::st_schedid, sip_pvt::stimer, stop_session_timer(), sip_pvt::timer_b, sip_pvt::timer_t1, and TRUE.

Referenced by __sip_autodestruct(), auto_congest(), cb_extensionstate(), check_auth(), check_pendings(), handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_cancel(), handle_request_info(), handle_request_invite(), handle_request_notify(), handle_request_options(), handle_request_register(), handle_request_subscribe(), handle_response_invite(), handle_response_register(), manager_sipnotify(), receive_message(), sip_cli_notify(), sip_hangup(), sip_send_mwi_to_peer(), sip_sipredirect(), and transmit_fake_auth_response().

03608 {
03609    if (ms < 0) {
03610       if (p->timer_t1 == 0) {
03611          p->timer_t1 = global_t1;   /* Set timer T1 if not set (RFC 3261) */
03612          p->timer_b = global_timer_b;  /* Set timer B if not set (RFC 3261) */
03613       }
03614       ms = p->timer_t1 * 64;
03615    }
03616    if (sip_debug_test_pvt(p))
03617       ast_verbose("Scheduling destruction of SIP dialog '%s' in %d ms (Method: %s)\n", p->callid, ms, sip_methods[p->method].text);
03618    if (sip_cancel_destroy(p))
03619       ast_log(LOG_WARNING, "Unable to cancel SIP destruction.  Expect bad things.\n");
03620 
03621    if (p->do_history)
03622       append_history(p, "SchedDestroy", "%d ms", ms);
03623    p->autokillid = ast_sched_add(sched, ms, __sip_autodestruct, dialog_ref(p, "setting ref as passing into ast_sched_add for __sip_autodestruct"));
03624 
03625    if (p->stimer && p->stimer->st_active == TRUE && p->stimer->st_schedid > 0)
03626       stop_session_timer(p);
03627 }

static void sip_send_all_registers ( void   )  [static]

Send all known registrations.

Definition at line 24567 of file chan_sip.c.

References AST_SCHED_REPLACE_UNREF, ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_UNLOCK, ASTOBJ_WRLOCK, registry_addref(), registry_unref(), regl, sched, and sip_reregister().

Referenced by load_module(), and sip_do_reload().

24568 {
24569    int ms;
24570    int regspacing;
24571    if (!regobjs)
24572       return;
24573    regspacing = default_expiry * 1000/regobjs;
24574    if (regspacing > 100)
24575       regspacing = 100;
24576    ms = regspacing;
24577    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
24578       ASTOBJ_WRLOCK(iterator);
24579       ms += regspacing;
24580       AST_SCHED_REPLACE_UNREF(iterator->expire, sched, ms, sip_reregister, iterator, 
24581                         registry_unref(_data, "REPLACE sched del decs the refcount"),
24582                         registry_unref(iterator, "REPLACE sched add failure decs the refcount"),
24583                         registry_addref(iterator, "REPLACE sched add incs the refcount"));
24584       ASTOBJ_UNLOCK(iterator);
24585    } while (0)
24586    );
24587 }

static int sip_send_mwi_to_peer ( struct sip_peer peer,
const struct ast_event event,
int  cache_only 
) [static]

Send message waiting indication to alert peer that they've got voicemail.

Definition at line 21363 of file chan_sip.c.

References sip_peer::addr, ao2_t_link, ao2_t_unlink, ast_app_inboxcount(), ast_event_get_ie_uint(), AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_OLDMSGS, ast_set_flag, ast_sip_ouraddrfor(), ast_str_alloca, ast_test_flag, build_callid_pvt(), build_via(), create_addr_from_peer(), sip_peer::defaddr, DEFAULT_TRANS_TIMEOUT, dialog_ref(), dialog_unlink_all(), dialog_unref(), dialogs, sip_pvt::flags, sip_peer::flags, get_cached_mwi(), sip_peer::mwipvt, sip_pvt::ourip, peer_mailboxes_to_str(), sip_pvt::sa, set_socket_transport(), sip_alloc(), SIP_NOTIFY, SIP_OUTGOING, SIP_PAGE2_SUBSCRIBEMWIONLY, sip_scheddestroy(), sip_pvt::socket, ast_str::str, transmit_notify_with_mwi(), TRUE, and sip_peer::vmexten.

Referenced by build_peer(), handle_request_subscribe(), and mwi_event_cb().

21364 {
21365    /* Called with peerl lock, but releases it */
21366    struct sip_pvt *p;
21367    int newmsgs = 0, oldmsgs = 0;
21368 
21369    if (ast_test_flag((&peer->flags[1]), SIP_PAGE2_SUBSCRIBEMWIONLY) && !peer->mwipvt)
21370       return 0;
21371 
21372    /* Do we have an IP address? If not, skip this peer */
21373    if (!peer->addr.sin_addr.s_addr && !peer->defaddr.sin_addr.s_addr) 
21374       return 0;
21375 
21376    if (event) {
21377       newmsgs = ast_event_get_ie_uint(event, AST_EVENT_IE_NEWMSGS);
21378       oldmsgs = ast_event_get_ie_uint(event, AST_EVENT_IE_OLDMSGS);
21379    } else if (!get_cached_mwi(peer, &newmsgs, &oldmsgs)) {
21380       /* got it!  Don't keep looking. */
21381    } else if (cache_only) {
21382       return 0;
21383    } else { /* Fall back to manually checking the mailbox */
21384       struct ast_str *mailbox_str = ast_str_alloca(512);
21385       peer_mailboxes_to_str(&mailbox_str, peer);
21386       ast_app_inboxcount(mailbox_str->str, &newmsgs, &oldmsgs);
21387    }
21388    
21389    if (peer->mwipvt) {
21390       /* Base message on subscription */
21391       p = dialog_ref(peer->mwipvt, "sip_send_mwi_to_peer: Setting dialog ptr p from peer->mwipvt-- should this be done?");
21392    } else {
21393       /* Build temporary dialog for this message */
21394       if (!(p = sip_alloc(NULL, NULL, 0, SIP_NOTIFY, NULL))) 
21395          return -1;
21396       /* If we don't set the socket type to 0, then create_addr_from_peer will fail immediately if the peer
21397        * uses any transport other than UDP. We set the type to 0 here and then let create_addr_from_peer copy 
21398        * the peer's socket information to the sip_pvt we just allocated
21399        */
21400       set_socket_transport(&p->socket, 0);
21401       if (create_addr_from_peer(p, peer)) {
21402          /* Maybe they're not registered, etc. */
21403          dialog_unlink_all(p, TRUE, TRUE);
21404          dialog_unref(p, "unref dialog p just created via sip_alloc");
21405          /* sip_destroy(p); */
21406          return 0;
21407       }
21408       /* Recalculate our side, and recalculate Call ID */
21409       ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip, p);
21410       build_via(p);
21411       ao2_t_unlink(dialogs, p, "About to change the callid -- remove the old name");
21412       build_callid_pvt(p);
21413       ao2_t_link(dialogs, p, "Linking in under new name");
21414       /* Destroy this session after 32 secs */
21415       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
21416    }
21417 
21418    /* Send MWI */
21419    ast_set_flag(&p->flags[0], SIP_OUTGOING);
21420    /* the following will decrement the refcount on p as it finishes */
21421    transmit_notify_with_mwi(p, newmsgs, oldmsgs, peer->vmexten);
21422    dialog_unref(p, "unref dialog ptr p just before it goes out of scope at the end of sip_send_mwi_to_peer.");
21423    return 0;
21424 }

static int sip_senddigit_begin ( struct ast_channel ast,
char  digit 
) [static]

Definition at line 5950 of file chan_sip.c.

References ast_rtp_senddigit_begin(), ast_test_flag, sip_pvt::flags, sip_pvt::rtp, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_RFC2833, sip_pvt_lock, sip_pvt_unlock, and ast_channel::tech_pvt.

05951 {
05952    struct sip_pvt *p = ast->tech_pvt;
05953    int res = 0;
05954 
05955    sip_pvt_lock(p);
05956    switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
05957    case SIP_DTMF_INBAND:
05958       res = -1; /* Tell Asterisk to generate inband indications */
05959       break;
05960    case SIP_DTMF_RFC2833:
05961       if (p->rtp)
05962          ast_rtp_senddigit_begin(p->rtp, digit);
05963       break;
05964    default:
05965       break;
05966    }
05967    sip_pvt_unlock(p);
05968 
05969    return res;
05970 }

static int sip_senddigit_end ( struct ast_channel ast,
char  digit,
unsigned int  duration 
) [static]

Send DTMF character on SIP channel within one call, we're able to transmit in many methods simultaneously.

Definition at line 5974 of file chan_sip.c.

References ast_rtp_senddigit_end(), ast_test_flag, sip_pvt::flags, SIP_DTMF, SIP_DTMF_INBAND, SIP_DTMF_INFO, SIP_DTMF_RFC2833, SIP_DTMF_SHORTINFO, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, and transmit_info_with_digit().

05975 {
05976    struct sip_pvt *p = ast->tech_pvt;
05977    int res = 0;
05978 
05979    sip_pvt_lock(p);
05980    switch (ast_test_flag(&p->flags[0], SIP_DTMF)) {
05981    case SIP_DTMF_INFO:
05982    case SIP_DTMF_SHORTINFO:
05983       transmit_info_with_digit(p, digit, duration);
05984       break;
05985    case SIP_DTMF_RFC2833:
05986       if (p->rtp)
05987          ast_rtp_senddigit_end(p->rtp, digit);
05988       break;
05989    case SIP_DTMF_INBAND:
05990       res = -1; /* Tell Asterisk to stop inband indications */
05991       break;
05992    }
05993    sip_pvt_unlock(p);
05994 
05995    return res;
05996 }

static int sip_sendhtml ( struct ast_channel chan,
int  subclass,
const char *  data,
int  datalen 
) [static]

Send message with Access-URL header, if this is an HTML URL only!

Definition at line 4091 of file chan_sip.c.

References ast_channel::_state, ast_debug, AST_HTML_URL, ast_log(), ast_set_flag, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_string_field_build, ast_test_flag, chan, FALSE, sip_pvt::flags, sip_pvt::initreq, LOG_WARNING, sip_pvt::pendinginvite, sip_debug_test_pvt(), SIP_NEEDREINVITE, SIP_PENDINGBYE, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), transmit_response(), and url.

04092 {
04093    struct sip_pvt *p = chan->tech_pvt;
04094 
04095    if (subclass != AST_HTML_URL)
04096       return -1;
04097 
04098    ast_string_field_build(p, url, "<%s>;mode=active", data);
04099 
04100    if (sip_debug_test_pvt(p))
04101       ast_debug(1, "Send URL %s, state = %d!\n", data, chan->_state);
04102 
04103    switch (chan->_state) {
04104    case AST_STATE_RING:
04105       transmit_response(p, "100 Trying", &p->initreq);
04106       break;
04107    case AST_STATE_RINGING:
04108       transmit_response(p, "180 Ringing", &p->initreq);
04109       break;
04110    case AST_STATE_UP:
04111       if (!p->pendinginvite) {      /* We are up, and have no outstanding invite */
04112          transmit_reinvite_with_sdp(p, FALSE, FALSE);
04113       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
04114          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);   
04115       }  
04116       break;
04117    default:
04118       ast_log(LOG_WARNING, "Don't know how to send URI when state is %d!\n", chan->_state);
04119    }
04120 
04121    return 0;
04122 }

static int sip_sendtext ( struct ast_channel ast,
const char *  text 
) [static]

Send SIP MESSAGE text within a call Called from PBX core sendtext() application.

Definition at line 4132 of file chan_sip.c.

References ast_verbose, sip_request::debug, ast_channel::name, sip_debug_test_pvt(), ast_channel::tech_pvt, and transmit_message_with_text().

04133 {
04134    struct sip_pvt *p = ast->tech_pvt;
04135    int debug = sip_debug_test_pvt(p);
04136 
04137    if (debug)
04138       ast_verbose("Sending text %s on %s\n", text, ast->name);
04139    if (!p)
04140       return -1;
04141    /* NOT ast_strlen_zero, because a zero-length message is specifically
04142     * allowed by RFC 3428 (See section 10, Examples) */
04143    if (!text)
04144       return 0;
04145    if (debug)
04146       ast_verbose("Really sending text %s on %s\n", text, ast->name);
04147    transmit_message_with_text(p, text);
04148    return 0;   
04149 }

static char * sip_set_history ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Enable/Disable SIP History logging (CLI).

Definition at line 16181 of file chan_sip.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, TRUE, and ast_cli_entry::usage.

16182 {
16183    switch (cmd) {
16184    case CLI_INIT:
16185       e->command = "sip set history {on|off}";
16186       e->usage =
16187          "Usage: sip set history {on|off}\n"
16188          "       Enables/Disables recording of SIP dialog history for debugging purposes.\n"
16189          "       Use 'sip show history' to view the history of a call number.\n";
16190       return NULL;
16191    case CLI_GENERATE:
16192       return NULL;
16193    }
16194 
16195    if (a->argc != e->args)
16196       return CLI_SHOWUSAGE;
16197 
16198    if (!strncasecmp(a->argv[e->args - 1], "on", 2)) {
16199       recordhistory = TRUE;
16200       ast_cli(a->fd, "SIP History Recording Enabled (use 'sip show history')\n");
16201    } else if (!strncasecmp(a->argv[e->args - 1], "off", 3)) {
16202       recordhistory = FALSE;
16203       ast_cli(a->fd, "SIP History Recording Disabled\n");
16204    } else {
16205       return CLI_SHOWUSAGE;
16206    }
16207    return CLI_SUCCESS;
16208 }

static void sip_set_redirstr ( struct sip_pvt p,
char *  reason 
) [static]

Translate referring cause.

Definition at line 12386 of file chan_sip.c.

References ast_string_field_set.

Referenced by get_rdnis().

12386                                                               {
12387 
12388    if (!strcmp(reason, "unknown")) {
12389       ast_string_field_set(p, redircause, "UNKNOWN");
12390    } else if (!strcmp(reason, "user-busy")) {
12391       ast_string_field_set(p, redircause, "BUSY");
12392    } else if (!strcmp(reason, "no-answer")) {
12393       ast_string_field_set(p, redircause, "NOANSWER");
12394    } else if (!strcmp(reason, "unavailable")) {
12395       ast_string_field_set(p, redircause, "UNREACHABLE");
12396    } else if (!strcmp(reason, "unconditional")) {
12397       ast_string_field_set(p, redircause, "UNCONDITIONAL");
12398    } else if (!strcmp(reason, "time-of-day")) {
12399       ast_string_field_set(p, redircause, "UNKNOWN");
12400    } else if (!strcmp(reason, "do-not-disturb")) {
12401       ast_string_field_set(p, redircause, "UNKNOWN");
12402    } else if (!strcmp(reason, "deflection")) {
12403       ast_string_field_set(p, redircause, "UNKNOWN");
12404    } else if (!strcmp(reason, "follow-me")) {
12405       ast_string_field_set(p, redircause, "UNKNOWN");
12406    } else if (!strcmp(reason, "out-of-service")) {
12407       ast_string_field_set(p, redircause, "UNREACHABLE");
12408    } else if (!strcmp(reason, "away")) {
12409       ast_string_field_set(p, redircause, "UNREACHABLE");
12410    } else {
12411       ast_string_field_set(p, redircause, "UNKNOWN");
12412    }
12413 }

static int sip_set_rtp_peer ( struct ast_channel chan,
struct ast_rtp rtp,
struct ast_rtp vrtp,
struct ast_rtp trtp,
int  codecs,
int  nat_active 
) [static]

Set the RTP peer for this call.

Definition at line 24289 of file chan_sip.c.

References ast_channel::_state, sip_pvt::alreadygone, append_history, ast_bridged_channel(), ast_debug, ast_inet_ntoa(), ast_rtp_get_peer(), ast_set_flag, AST_STATE_UP, ast_test_flag, sip_pvt::callid, chan, sip_pvt::do_history, FALSE, sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::ourip, sip_pvt::pendinginvite, sip_pvt::redircodecs, sip_pvt::redirip, sip_pvt::rtp, SIP_CAN_REINVITE_NAT, SIP_DEFER_BYE_ON_TRANSFER, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), sip_pvt::tredirip, sip_pvt::trtp, sip_pvt::vredirip, and sip_pvt::vrtp.

Referenced by sip_fixup().

24290 {
24291    struct sip_pvt *p;
24292    int changed = 0;
24293 
24294    p = chan->tech_pvt;
24295    if (!p) 
24296       return -1;
24297 
24298    /* Disable early RTP bridge  */
24299    if (!ast_bridged_channel(chan) && !global_directrtpsetup)   /* We are in early state */
24300       return 0;
24301 
24302    sip_pvt_lock(p);
24303    if (p->alreadygone) {
24304       /* If we're destroyed, don't bother */
24305       sip_pvt_unlock(p);
24306       return 0;
24307    }
24308 
24309    /* if this peer cannot handle reinvites of the media stream to devices
24310       that are known to be behind a NAT, then stop the process now
24311    */
24312    if (nat_active && !ast_test_flag(&p->flags[0], SIP_CAN_REINVITE_NAT)) {
24313       sip_pvt_unlock(p);
24314       return 0;
24315    }
24316 
24317    if (rtp) {
24318       changed |= ast_rtp_get_peer(rtp, &p->redirip);
24319    } else if (p->redirip.sin_addr.s_addr || ntohs(p->redirip.sin_port) != 0) {
24320       memset(&p->redirip, 0, sizeof(p->redirip));
24321       changed = 1;
24322    }
24323    if (vrtp) {
24324       changed |= ast_rtp_get_peer(vrtp, &p->vredirip);
24325    } else if (p->vredirip.sin_addr.s_addr || ntohs(p->vredirip.sin_port) != 0) {
24326       memset(&p->vredirip, 0, sizeof(p->vredirip));
24327       changed = 1;
24328    }
24329    if (trtp) {
24330       changed |= ast_rtp_get_peer(trtp, &p->tredirip);
24331    } else if (p->tredirip.sin_addr.s_addr || ntohs(p->tredirip.sin_port) != 0) {
24332       memset(&p->tredirip, 0, sizeof(p->tredirip));
24333       changed = 1;
24334    }
24335    if (codecs && (p->redircodecs != codecs)) {
24336       p->redircodecs = codecs;
24337       changed = 1;
24338    }
24339    if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
24340       if (chan->_state != AST_STATE_UP) { /* We are in early state */
24341          if (p->do_history)
24342             append_history(p, "ExtInv", "Initial invite sent with remote bridge proposal.");
24343          ast_debug(1, "Early remote bridge setting SIP '%s' - Sending media to %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip.sin_addr));
24344       } else if (!p->pendinginvite) {     /* We are up, and have no outstanding invite */
24345          ast_debug(3, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip.sin_addr));
24346          transmit_reinvite_with_sdp(p, FALSE, FALSE);
24347       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
24348          ast_debug(3, "Deferring reinvite on SIP '%s' - It's audio will be redirected to IP %s\n", p->callid, ast_inet_ntoa(rtp ? p->redirip.sin_addr : p->ourip.sin_addr));
24349          /* We have a pending Invite. Send re-invite when we're done with the invite */
24350          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);   
24351       }
24352    }
24353    /* Reset lastrtprx timer */
24354    p->lastrtprx = p->lastrtptx = time(NULL);
24355    sip_pvt_unlock(p);
24356    return 0;
24357 }

static int sip_set_udptl_peer ( struct ast_channel chan,
struct ast_udptl udptl 
) [static]

Definition at line 24182 of file chan_sip.c.

References ast_debug, ast_inet_ntoa(), ast_set_flag, ast_test_flag, ast_udptl_get_peer(), sip_pvt::callid, chan, FALSE, sip_pvt::flags, sip_pvt::lastrtprx, sip_pvt::lastrtptx, sip_pvt::ourip, sip_pvt::pendinginvite, SIP_GOTREFER, SIP_NEEDREINVITE, SIP_PENDINGBYE, sip_pvt_lock, sip_pvt_unlock, ast_channel::tech_pvt, transmit_reinvite_with_sdp(), TRUE, sip_pvt::udptl, and sip_pvt::udptlredirip.

24183 {
24184    struct sip_pvt *p;
24185    
24186    p = chan->tech_pvt;
24187    if (!p)
24188       return -1;
24189    sip_pvt_lock(p);
24190    if (udptl)
24191       ast_udptl_get_peer(udptl, &p->udptlredirip);
24192    else
24193       memset(&p->udptlredirip, 0, sizeof(p->udptlredirip));
24194    if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
24195       if (!p->pendinginvite) {
24196          ast_debug(3, "Sending reinvite on SIP '%s' - It's UDPTL soon redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : p->ourip.sin_addr), udptl ? ntohs(p->udptlredirip.sin_port) : 0);
24197          transmit_reinvite_with_sdp(p, TRUE, FALSE);
24198       } else if (!ast_test_flag(&p->flags[0], SIP_PENDINGBYE)) {
24199          ast_debug(3, "Deferring reinvite on SIP '%s' - It's UDPTL will be redirected to IP %s:%d\n", p->callid, ast_inet_ntoa(udptl ? p->udptlredirip.sin_addr : p->ourip.sin_addr), udptl ? ntohs(p->udptlredirip.sin_port) : 0);
24200          ast_set_flag(&p->flags[0], SIP_NEEDREINVITE);
24201       }
24202    }
24203    /* Reset lastrtprx timer */
24204    p->lastrtprx = p->lastrtptx = time(NULL);
24205    sip_pvt_unlock(p);
24206    return 0;
24207 }

static char * sip_show_channel ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Show details of one active dialog.

Definition at line 15607 of file chan_sip.c.

References sip_pvt::allowtransfer, ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ast_cli_args::argc, ast_cli_args::argv, ARRAY_LEN, ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), ast_strlen_zero(), ast_test_flag, sip_pvt::callid, sip_pvt::capability, sip_pvt::cid_num, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, cli_yesno(), ast_cli_entry::command, complete_sipch(), dialogs, dtmfmode2str(), ast_cli_args::fd, sip_pvt::flags, sip_route::hop, cfsip_options::id, sip_pvt::jointcapability, sip_pvt::lastmsg, ast_cli_args::line, sip_pvt::maxcallbitrate, ast_cli_args::n, ast_channel::name, nat2str(), ast_channel::nativeformats, sip_pvt::needdestroy, sip_pvt::noncodeccapability, NONE, sip_pvt::ourip, sip_pvt::owner, sip_pvt::peercapability, sip_pvt::peername, ast_cli_args::pos, sip_pvt::recv, sip_pvt::redirip, sip_pvt::route, sip_pvt::sa, SIP_DTMF, SIP_NAT, sip_options, SIP_OUTGOING, SIP_PROMISCREDIR, sip_pvt_lock, sip_pvt_unlock, SIPBUFSIZE, sip_pvt::sipoptions, sip_st_dlg::st_active, sip_st_dlg::st_active_peer_ua, sip_st_dlg::st_cached_max_se, sip_st_dlg::st_cached_min_se, sip_st_dlg::st_cached_mode, sip_st_dlg::st_cached_ref, sip_st_dlg::st_expirys, sip_st_dlg::st_interval, sip_st_dlg::st_ref, sip_st_dlg::st_schedid, sip_pvt::stimer, stmode2str(), strefresher2str(), sip_pvt::subscribed, subscription_type2str(), sip_pvt::tag, cfsip_options::text, sip_pvt::theirtag, transfermode2str(), TRUE, sip_pvt::udptl, sip_pvt::uri, ast_cli_entry::usage, sip_pvt::useragent, sip_pvt::username, sip_pvt::vrtp, and ast_cli_args::word.

15608 {
15609    struct sip_pvt *cur;
15610    size_t len;
15611    int found = 0;
15612    struct ao2_iterator i;
15613 
15614    switch (cmd) {
15615    case CLI_INIT:
15616       e->command = "sip show channel";
15617       e->usage =
15618          "Usage: sip show channel <call-id>\n"
15619          "       Provides detailed status on a given SIP dialog (identified by SIP call-id).\n";
15620       return NULL;
15621    case CLI_GENERATE:
15622       return complete_sipch(a->line, a->word, a->pos, a->n);
15623    }
15624 
15625    if (a->argc != 4)
15626       return CLI_SHOWUSAGE;
15627    len = strlen(a->argv[3]);
15628    
15629    i = ao2_iterator_init(dialogs, 0);
15630    while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
15631       sip_pvt_lock(cur);
15632 
15633       if (!strncasecmp(cur->callid, a->argv[3], len)) {
15634          char formatbuf[SIPBUFSIZE/2];
15635          ast_cli(a->fd, "\n");
15636          if (cur->subscribed != NONE)
15637             ast_cli(a->fd, "  * Subscription (type: %s)\n", subscription_type2str(cur->subscribed));
15638          else
15639             ast_cli(a->fd, "  * SIP Call\n");
15640          ast_cli(a->fd, "  Curr. trans. direction:  %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming");
15641          ast_cli(a->fd, "  Call-ID:                %s\n", cur->callid);
15642          ast_cli(a->fd, "  Owner channel ID:       %s\n", cur->owner ? cur->owner->name : "<none>");
15643          ast_cli(a->fd, "  Our Codec Capability:   %d\n", cur->capability);
15644          ast_cli(a->fd, "  Non-Codec Capability (DTMF):   %d\n", cur->noncodeccapability);
15645          ast_cli(a->fd, "  Their Codec Capability:   %d\n", cur->peercapability);
15646          ast_cli(a->fd, "  Joint Codec Capability:   %d\n", cur->jointcapability);
15647          ast_cli(a->fd, "  Format:                 %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) );
15648          ast_cli(a->fd, "  T.38 support            %s\n", cli_yesno(cur->udptl != NULL));
15649          ast_cli(a->fd, "  Video support           %s\n", cli_yesno(cur->vrtp != NULL));
15650          ast_cli(a->fd, "  MaxCallBR:              %d kbps\n", cur->maxcallbitrate);
15651          ast_cli(a->fd, "  Theoretical Address:    %s:%d\n", ast_inet_ntoa(cur->sa.sin_addr), ntohs(cur->sa.sin_port));
15652          ast_cli(a->fd, "  Received Address:       %s:%d\n", ast_inet_ntoa(cur->recv.sin_addr), ntohs(cur->recv.sin_port));
15653          ast_cli(a->fd, "  SIP Transfer mode:      %s\n", transfermode2str(cur->allowtransfer));
15654          ast_cli(a->fd, "  NAT Support:            %s\n", nat2str(ast_test_flag(&cur->flags[0], SIP_NAT)));
15655          ast_cli(a->fd, "  Audio IP:               %s %s\n", ast_inet_ntoa(cur->redirip.sin_addr.s_addr ? cur->redirip.sin_addr : cur->ourip.sin_addr), cur->redirip.sin_addr.s_addr ? "(Outside bridge)" : "(local)" );
15656          ast_cli(a->fd, "  Our Tag:                %s\n", cur->tag);
15657          ast_cli(a->fd, "  Their Tag:              %s\n", cur->theirtag);
15658          ast_cli(a->fd, "  SIP User agent:         %s\n", cur->useragent);
15659          if (!ast_strlen_zero(cur->username))
15660             ast_cli(a->fd, "  Username:               %s\n", cur->username);
15661          if (!ast_strlen_zero(cur->peername))
15662             ast_cli(a->fd, "  Peername:               %s\n", cur->peername);
15663          if (!ast_strlen_zero(cur->uri))
15664             ast_cli(a->fd, "  Original uri:           %s\n", cur->uri);
15665          if (!ast_strlen_zero(cur->cid_num))
15666             ast_cli(a->fd, "  Caller-ID:              %s\n", cur->cid_num);
15667          ast_cli(a->fd, "  Need Destroy:           %s\n", cli_yesno(cur->needdestroy));
15668          ast_cli(a->fd, "  Last Message:           %s\n", cur->lastmsg);
15669          ast_cli(a->fd, "  Promiscuous Redir:      %s\n", cli_yesno(ast_test_flag(&cur->flags[0], SIP_PROMISCREDIR)));
15670          ast_cli(a->fd, "  Route:                  %s\n", cur->route ? cur->route->hop : "N/A");
15671          ast_cli(a->fd, "  DTMF Mode:              %s\n", dtmfmode2str(ast_test_flag(&cur->flags[0], SIP_DTMF)));
15672          ast_cli(a->fd, "  SIP Options:            ");
15673          if (cur->sipoptions) {
15674             int x;
15675             for (x = 0 ; x < ARRAY_LEN(sip_options); x++) {
15676                if (cur->sipoptions & sip_options[x].id)
15677                   ast_cli(a->fd, "%s ", sip_options[x].text);
15678             }
15679             ast_cli(a->fd, "\n");
15680          } else
15681             ast_cli(a->fd, "(none)\n");
15682 
15683          if (!cur->stimer)
15684             ast_cli(a->fd, "  Session-Timer:          Uninitiallized\n");
15685          else {
15686             ast_cli(a->fd, "  Session-Timer:          %s\n", cur->stimer->st_active ? "Active" : "Inactive");
15687             if (cur->stimer->st_active == TRUE) {
15688                ast_cli(a->fd, "  S-Timer Interval:       %d\n", cur->stimer->st_interval);
15689                ast_cli(a->fd, "  S-Timer Refresher:      %s\n", strefresher2str(cur->stimer->st_ref));
15690                ast_cli(a->fd, "  S-Timer Expirys:        %d\n", cur->stimer->st_expirys);
15691                ast_cli(a->fd, "  S-Timer Sched Id:       %d\n", cur->stimer->st_schedid);
15692                ast_cli(a->fd, "  S-Timer Peer Sts:       %s\n", cur->stimer->st_active_peer_ua ? "Active" : "Inactive");
15693                ast_cli(a->fd, "  S-Timer Cached Min-SE:  %d\n", cur->stimer->st_cached_min_se);
15694                ast_cli(a->fd, "  S-Timer Cached SE:      %d\n", cur->stimer->st_cached_max_se);
15695                ast_cli(a->fd, "  S-Timer Cached Ref:     %s\n", strefresher2str(cur->stimer->st_cached_ref));
15696                ast_cli(a->fd, "  S-Timer Cached Mode:    %s\n", stmode2str(cur->stimer->st_cached_mode));
15697             }
15698          }
15699 
15700          ast_cli(a->fd, "\n\n");
15701 
15702          found++;
15703       }
15704 
15705       sip_pvt_unlock(cur);
15706 
15707       ao2_t_ref(cur, -1, "toss dialog ptr set by iterator_next");
15708    }
15709    ao2_iterator_destroy(&i);
15710 
15711    if (!found) 
15712       ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]);
15713 
15714    return CLI_SUCCESS;
15715 }

static char* sip_show_channels ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

CLI for show channels or subscriptions. This is a new-style CLI handler so a single function contains the prototype for the function, the 'generator' to produce multiple entries in case it is required, and the actual handler for the command.

Definition at line 15428 of file chan_sip.c.

References ao2_t_callback, ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dialogs, ESS, ast_cli_args::fd, __show_chan_arg::fd, FORMAT2, FORMAT3, __show_chan_arg::numchans, OBJ_NODATA, show_channels_cb(), __show_chan_arg::subscriptions, and ast_cli_entry::usage.

15429 {
15430    struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 };
15431 
15432 
15433    if (cmd == CLI_INIT) {
15434       e->command = "sip show {channels|subscriptions}";
15435       e->usage =
15436          "Usage: sip show channels\n"
15437          "       Lists all currently active SIP calls (dialogs).\n"
15438          "Usage: sip show subscriptions\n"
15439          "       Lists active SIP subscriptions.\n";
15440       return NULL;
15441    } else if (cmd == CLI_GENERATE)
15442       return NULL;
15443 
15444    if (a->argc != e->args)
15445       return CLI_SHOWUSAGE;
15446    arg.subscriptions = !strcasecmp(a->argv[e->args - 1], "subscriptions");
15447    if (!arg.subscriptions)
15448       ast_cli(arg.fd, FORMAT2, "Peer", "User/ANR", "Call ID", "Format", "Hold", "Last Message", "Expiry");
15449    else
15450       ast_cli(arg.fd, FORMAT3, "Peer", "User", "Call ID", "Extension", "Last state", "Type", "Mailbox", "Expiry");
15451 
15452    /* iterate on the container and invoke the callback on each item */
15453    ao2_t_callback(dialogs, OBJ_NODATA, show_channels_cb, &arg, "callback to show channels");
15454    
15455    /* print summary information */
15456    ast_cli(arg.fd, "%d active SIP %s%s\n", arg.numchans,
15457       (arg.subscriptions ? "subscription" : "dialog"),
15458       ESS(arg.numchans));  /* ESS(n) returns an "s" if n>1 */
15459    return CLI_SUCCESS;
15460 #undef FORMAT
15461 #undef FORMAT2
15462 #undef FORMAT3
15463 }

static char * sip_show_channelstats ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

SIP show channelstats CLI (main function).

Definition at line 15119 of file chan_sip.c.

References ao2_t_callback, ast_cli_args::argc, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dialogs, ast_cli_args::fd, __show_chan_arg::fd, FORMAT2, __show_chan_arg::numchans, OBJ_NODATA, show_chanstats_cb(), and ast_cli_entry::usage.

15120 {
15121    struct __show_chan_arg arg = { .fd = a->fd, .numchans = 0 };
15122 
15123    switch (cmd) {
15124    case CLI_INIT:
15125       e->command = "sip show channelstats";
15126       e->usage =
15127          "Usage: sip show channelstats\n"
15128          "       Lists all currently active SIP channel's RTCP statistics.\n"
15129          "       Note that calls in the much optimized RTP P2P bridge mode will not show any packets here.";
15130       return NULL;
15131    case CLI_GENERATE:
15132       return NULL;
15133    }
15134 
15135    if (a->argc != 3)
15136       return CLI_SHOWUSAGE;
15137 
15138    ast_cli(a->fd, FORMAT2, "Peer", "Call ID", "Duration", "Recv: Pack", "Lost", "Jitter", "Send: Pack", "Lost", "Jitter");
15139    /* iterate on the container and invoke the callback on each item */
15140    ao2_t_callback(dialogs, OBJ_NODATA, show_chanstats_cb, &arg, "callback to sip show chanstats");
15141    ast_cli(a->fd, "%d active SIP channel%s\n", arg.numchans, (arg.numchans != 1) ? "s" : ""); 
15142    return CLI_SUCCESS;
15143 }

static char * sip_show_domains ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

CLI command to list local domains.

Definition at line 14418 of file chan_sip.c.

References ast_cli(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, domain::context, domain::domain, domain_mode_to_text(), ast_cli_args::fd, FORMAT, domain::list, domain::mode, S_OR, and ast_cli_entry::usage.

14419 {
14420    struct domain *d;
14421 #define FORMAT "%-40.40s %-20.20s %-16.16s\n"
14422 
14423    switch (cmd) {
14424    case CLI_INIT:
14425       e->command = "sip show domains";
14426       e->usage =
14427          "Usage: sip show domains\n"
14428          "       Lists all configured SIP local domains.\n"
14429          "       Asterisk only responds to SIP messages to local domains.\n";
14430       return NULL;
14431    case CLI_GENERATE:
14432       return NULL;
14433    }
14434 
14435    if (AST_LIST_EMPTY(&domain_list)) {
14436       ast_cli(a->fd, "SIP Domain support not enabled.\n\n");
14437       return CLI_SUCCESS;
14438    } else {
14439       ast_cli(a->fd, FORMAT, "Our local SIP domains:", "Context", "Set by");
14440       AST_LIST_LOCK(&domain_list);
14441       AST_LIST_TRAVERSE(&domain_list, d, list)
14442          ast_cli(a->fd, FORMAT, d->domain, S_OR(d->context, "(default)"),
14443             domain_mode_to_text(d->mode));
14444       AST_LIST_UNLOCK(&domain_list);
14445       ast_cli(a->fd, "\n");
14446       return CLI_SUCCESS;
14447    }
14448 }

static char * sip_show_history ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Show history details of one dialog.

Definition at line 15718 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_TRAVERSE, sip_pvt::callid, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_show_history(), dialogs, sip_history::event, ast_cli_args::fd, sip_pvt::history, ast_cli_args::line, sip_history::list, ast_cli_args::n, NONE, ast_cli_args::pos, sip_pvt_lock, sip_pvt_unlock, sip_pvt::subscribed, ast_cli_entry::usage, and ast_cli_args::word.

15719 {
15720    struct sip_pvt *cur;
15721    size_t len;
15722    int found = 0;
15723    struct ao2_iterator i;
15724 
15725    switch (cmd) {
15726    case CLI_INIT:
15727       e->command = "sip show history";
15728       e->usage =
15729          "Usage: sip show history <call-id>\n"
15730          "       Provides detailed dialog history on a given SIP call (specified by call-id).\n";
15731       return NULL;
15732    case CLI_GENERATE:
15733       return complete_sip_show_history(a->line, a->word, a->pos, a->n);
15734    }
15735 
15736    if (a->argc != 4)
15737       return CLI_SHOWUSAGE;
15738 
15739    if (!recordhistory)
15740       ast_cli(a->fd, "\n***Note: History recording is currently DISABLED.  Use 'sip set history on' to ENABLE.\n");
15741 
15742    len = strlen(a->argv[3]);
15743 
15744    i = ao2_iterator_init(dialogs, 0);
15745    while ((cur = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
15746       sip_pvt_lock(cur);
15747       if (!strncasecmp(cur->callid, a->argv[3], len)) {
15748          struct sip_history *hist;
15749          int x = 0;
15750 
15751          ast_cli(a->fd, "\n");
15752          if (cur->subscribed != NONE)
15753             ast_cli(a->fd, "  * Subscription\n");
15754          else
15755             ast_cli(a->fd, "  * SIP Call\n");
15756          if (cur->history)
15757             AST_LIST_TRAVERSE(cur->history, hist, list)
15758                ast_cli(a->fd, "%d. %s\n", ++x, hist->event);
15759          if (x == 0)
15760             ast_cli(a->fd, "Call '%s' has no history\n", cur->callid);
15761          found++;
15762       }
15763       sip_pvt_unlock(cur);
15764       ao2_t_ref(cur, -1, "toss dialog ptr from iterator_next");
15765    }
15766    ao2_iterator_destroy(&i);
15767 
15768    if (!found) 
15769       ast_cli(a->fd, "No such SIP Call ID starting with '%s'\n", a->argv[3]);
15770 
15771    return CLI_SUCCESS;
15772 }

static char * sip_show_inuse ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

CLI Command to show calls within limits set by call_limit.

Definition at line 13502 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_lock(), ao2_t_iterator_next, ao2_unlock(), ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_copy_string(), sip_peer::call_limit, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, FALSE, ast_cli_args::fd, FORMAT, FORMAT2, sip_peer::inRinging, sip_peer::inUse, sip_peer::name, sip_peer::onHold, peers, TRUE, unref_peer(), and ast_cli_entry::usage.

13503 {
13504 #define FORMAT "%-25.25s %-15.15s %-15.15s \n"
13505 #define FORMAT2 "%-25.25s %-15.15s %-15.15s \n"
13506    char ilimits[40];
13507    char iused[40];
13508    int showall = FALSE;
13509    struct ao2_iterator i;
13510    struct sip_peer *peer;
13511    
13512    switch (cmd) {
13513    case CLI_INIT:
13514       e->command = "sip show inuse";
13515       e->usage =
13516          "Usage: sip show inuse [all]\n"
13517          "       List all SIP devices usage counters and limits.\n"
13518          "       Add option \"all\" to show all devices, not only those with a limit.\n";
13519       return NULL;
13520    case CLI_GENERATE:
13521       return NULL;
13522    }
13523 
13524    if (a->argc < 3) 
13525       return CLI_SHOWUSAGE;
13526 
13527    if (a->argc == 4 && !strcmp(a->argv[3], "all")) 
13528       showall = TRUE;
13529    
13530    ast_cli(a->fd, FORMAT, "* Peer name", "In use", "Limit");
13531 
13532    i = ao2_iterator_init(peers, 0);
13533    while ((peer = ao2_t_iterator_next(&i, "iterate thru peer table"))) {
13534       ao2_lock(peer);
13535       if (peer->call_limit)
13536          snprintf(ilimits, sizeof(ilimits), "%d", peer->call_limit);
13537       else 
13538          ast_copy_string(ilimits, "N/A", sizeof(ilimits));
13539       snprintf(iused, sizeof(iused), "%d/%d/%d", peer->inUse, peer->inRinging, peer->onHold);
13540       if (showall || peer->call_limit)
13541          ast_cli(a->fd, FORMAT2, peer->name, iused, ilimits);
13542       ao2_unlock(peer);
13543       unref_peer(peer, "toss iterator pointer");
13544    }
13545    ao2_iterator_destroy(&i);
13546 
13547    return CLI_SUCCESS;
13548 #undef FORMAT
13549 #undef FORMAT2
13550 }

static char * sip_show_objects ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

List all allocated SIP Objects (realtime or static).

Definition at line 14085 of file chan_sip.c.

References ao2_t_callback, ast_cli_args::argc, ast_cli(), ASTOBJ_CONTAINER_DUMP, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, dialog_dump_func(), dialogs, ast_cli_args::fd, OBJ_NODATA, peer_dump_func(), peers, regl, and ast_cli_entry::usage.

14086 {
14087    char tmp[256];
14088    
14089    switch (cmd) {
14090    case CLI_INIT:
14091       e->command = "sip show objects";
14092       e->usage =
14093          "Usage: sip show objects\n"
14094          "       Lists status of known SIP objects\n";
14095       return NULL;
14096    case CLI_GENERATE:
14097       return NULL;
14098    }  
14099 
14100    if (a->argc != 3)
14101       return CLI_SHOWUSAGE;
14102    ast_cli(a->fd, "-= Peer objects: %d static, %d realtime, %d autocreate =-\n\n", speerobjs, rpeerobjs, apeerobjs);
14103    ao2_t_callback(peers, OBJ_NODATA, peer_dump_func, &a->fd, "initiate ao2_callback to dump peers");
14104    ast_cli(a->fd, "-= Registry objects: %d =-\n\n", regobjs);
14105    ASTOBJ_CONTAINER_DUMP(a->fd, tmp, sizeof(tmp), &regl);
14106    ast_cli(a->fd, "-= Dialog objects:\n\n");
14107    ao2_t_callback(dialogs, OBJ_NODATA, dialog_dump_func, &a->fd, "initiate ao2_callback to dump dialogs");
14108    return CLI_SUCCESS;
14109 }

static char * sip_show_peer ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Show one peer in detail.

Definition at line 14479 of file chan_sip.c.

References _sip_show_peer(), ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, complete_sip_show_peer(), ast_cli_args::fd, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

14480 {
14481    switch (cmd) {
14482    case CLI_INIT:
14483       e->command = "sip show peer";
14484       e->usage =
14485          "Usage: sip show peer <name> [load]\n"
14486          "       Shows all details on one SIP peer and the current status.\n"
14487          "       Option \"load\" forces lookup of peer in realtime storage.\n";
14488       return NULL;
14489    case CLI_GENERATE:
14490       return complete_sip_show_peer(a->line, a->word, a->pos, a->n);
14491    }
14492    return _sip_show_peer(0, a->fd, NULL, NULL, a->argc, (const char **) a->argv);
14493 }

static char * sip_show_peers ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

CLI Show Peers command.

Definition at line 13861 of file chan_sip.c.

References _sip_show_peers(), ast_cli_args::argc, ast_cli_args::argv, CLI_GENERATE, CLI_INIT, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

13862 {
13863    switch (cmd) {
13864    case CLI_INIT:
13865       e->command = "sip show peers";
13866       e->usage =
13867          "Usage: sip show peers [like <pattern>]\n"
13868          "       Lists all known SIP peers.\n"
13869          "       Optional regular expression pattern is used to filter the peer list.\n";
13870       return NULL;
13871    case CLI_GENERATE:
13872       return NULL;
13873    }
13874 
13875    return _sip_show_peers(a->fd, NULL, NULL, NULL, a->argc, (const char **) a->argv);
13876 }

static char * sip_show_registry ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Show SIP Registry (registrations with other SIP proxies.

Definition at line 14977 of file chan_sip.c.

References ast_cli_args::argc, ast_cli(), ast_localtime(), ast_strftime(), ASTOBJ_CONTAINER_TRAVERSE, ASTOBJ_RDLOCK, ASTOBJ_UNLOCK, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, FORMAT, FORMAT2, regl, regstate2str(), STANDARD_SIP_PORT, and ast_cli_entry::usage.

14978 {
14979 #define FORMAT2 "%-30.30s %-6.6s %-12.12s  %8.8s %-20.20s %-25.25s\n"
14980 #define FORMAT  "%-30.30s %-6.6s %-12.12s  %8d %-20.20s %-25.25s\n"
14981    char host[80];
14982    char tmpdat[256];
14983    struct ast_tm tm;
14984    int counter = 0;
14985 
14986    switch (cmd) {
14987    case CLI_INIT:
14988       e->command = "sip show registry";
14989       e->usage =
14990          "Usage: sip show registry\n"
14991          "       Lists all registration requests and status.\n";
14992       return NULL;
14993    case CLI_GENERATE:
14994       return NULL;
14995    }
14996 
14997    if (a->argc != 3)
14998       return CLI_SHOWUSAGE;
14999    ast_cli(a->fd, FORMAT2, "Host", "dnsmgr", "Username", "Refresh", "State", "Reg.Time");
15000    
15001    ASTOBJ_CONTAINER_TRAVERSE(&regl, 1, do {
15002       ASTOBJ_RDLOCK(iterator);
15003       snprintf(host, sizeof(host), "%s:%d", iterator->hostname, iterator->portno ? iterator->portno : STANDARD_SIP_PORT);
15004       if (iterator->regtime.tv_sec) {
15005          ast_localtime(&iterator->regtime, &tm, NULL);
15006          ast_strftime(tmpdat, sizeof(tmpdat), "%a, %d %b %Y %T", &tm);
15007       } else 
15008          tmpdat[0] = '\0';
15009       ast_cli(a->fd, FORMAT, host, (iterator->dnsmgr) ? "Y" : "N", iterator->username, iterator->refresh, regstate2str(iterator->regstate), tmpdat);
15010       ASTOBJ_UNLOCK(iterator);
15011       counter++;
15012    } while(0));
15013    ast_cli(a->fd, "%d SIP registrations.\n", counter);
15014    return CLI_SUCCESS;
15015 #undef FORMAT
15016 #undef FORMAT2
15017 }

static char * sip_show_sched ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 14934 of file chan_sip.c.

References __sip_autodestruct(), ast_cli(), ast_sched_report(), ast_str_alloca, auto_congest(), CLI_GENERATE, CLI_INIT, CLI_SUCCESS, ast_cli_entry::command, expire_register(), ast_cli_args::fd, retrans_pkt(), sched, sip_poke_noanswer(), sip_poke_peer_s(), sip_reg_timeout(), sip_reinvite_retry(), sip_reregister(), ast_str::str, and ast_cli_entry::usage.

14935 {
14936    struct ast_str *cbuf;
14937    struct ast_cb_names cbnames = {9, { "retrans_pkt",
14938                                         "__sip_autodestruct",
14939                                         "expire_register",
14940                                         "auto_congest",
14941                                         "sip_reg_timeout",
14942                                         "sip_poke_peer_s",
14943                                         "sip_poke_noanswer",
14944                                         "sip_reregister",
14945                                         "sip_reinvite_retry"},
14946                            { retrans_pkt,
14947                                      __sip_autodestruct,
14948                                      expire_register,
14949                                      auto_congest,
14950                                      sip_reg_timeout,
14951                                      sip_poke_peer_s,
14952                                      sip_poke_noanswer,
14953                                      sip_reregister,
14954                                      sip_reinvite_retry}};
14955    
14956    switch (cmd) {
14957    case CLI_INIT:
14958       e->command = "sip show sched";
14959       e->usage =
14960          "Usage: sip show sched\n"
14961          "       Shows stats on what's in the sched queue at the moment\n";
14962       return NULL;
14963    case CLI_GENERATE:
14964       return NULL;
14965    }
14966 
14967    cbuf = ast_str_alloca(2048);
14968 
14969    ast_cli(a->fd, "\n");
14970    ast_sched_report(sched, &cbuf, &cbnames);
14971    ast_cli(a->fd, "%s", cbuf->str);
14972 
14973    return CLI_SUCCESS;
14974 }

static char * sip_show_settings ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

List global settings for the SIP channel.

Definition at line 15148 of file chan_sip.c.

References ast_cli_args::argc, ast_check_realtime(), ast_cli(), ast_getformatname_multiple(), ast_inet_ntoa(), AST_JB_ENABLED, AST_JB_FORCED, AST_JB_LOG, AST_LIST_EMPTY, ast_strlen_zero(), ast_test_flag, ast_tos2str(), authl, buf, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, cli_yesno(), ast_cli_entry::command, default_prefs, default_tls_cfg, dtmfmode2str(), ast_tls_config::enabled, FALSE, faxec2str(), ast_cli_args::fd, sip_proxy::force, global_flags, global_jbconf, global_outboundproxy, sip_settings::ignore_regexpire, ast_jb_conf::impl, ast_tcptls_session_args::local_address, localaddr, ast_jb_conf::max_size, msg, sip_proxy::name, nat2str(), ast_ha::netaddr, ast_ha::netmask, ast_ha::next, sip_settings::peer_rtupdate, prefix, print_codec_to_cli(), ast_jb_conf::resync_threshold, sip_settings::rtsave_sysname, S_OR, sip_cfg, SIP_DTMF, SIP_NAT, SIP_PAGE2_ALLOWOVERLAP, SIP_PAGE2_ALLOWSUBSCRIBE, SIP_PAGE2_IGNORESDPVERSION, SIP_PAGE2_RFC2833_COMPENSATE, SIP_PAGE2_RTCACHEFRIENDS, SIP_PAGE2_T38SUPPORT, SIP_PAGE2_TEXTSUPPORT, SIP_PAGE2_VIDEOSUPPORT, SIP_PROG_INBAND, SIP_PROG_INBAND_NEVER, SIP_PROG_INBAND_NO, SIP_PROMISCREDIR, sip_tcp_desc, sip_tls_desc, SIP_USECLIENTCODE, SIP_USEREQPHONE, SIPBUFSIZE, stmode2str(), strefresher2str(), transfermode2str(), and ast_cli_entry::usage.

15149 {
15150    int realtimepeers;
15151    int realtimeregs;
15152    char codec_buf[SIPBUFSIZE];
15153    const char *msg;  /* temporary msg pointer */
15154 
15155    switch (cmd) {
15156    case CLI_INIT:
15157       e->command = "sip show settings";
15158       e->usage =
15159          "Usage: sip show settings\n"
15160          "       Provides detailed list of the configuration of the SIP channel.\n";
15161       return NULL;
15162    case CLI_GENERATE:
15163       return NULL;
15164    }
15165 
15166 
15167    realtimepeers = ast_check_realtime("sippeers");
15168    realtimeregs = ast_check_realtime("sipregs");
15169 
15170    if (a->argc != 3)
15171       return CLI_SHOWUSAGE;
15172    ast_cli(a->fd, "\n\nGlobal Settings:\n");
15173    ast_cli(a->fd, "----------------\n");
15174    ast_cli(a->fd, "  UDP SIP Port:           %d\n", ntohs(bindaddr.sin_port));
15175    ast_cli(a->fd, "  UDP Bindaddress:        %s\n", ast_inet_ntoa(bindaddr.sin_addr));
15176    ast_cli(a->fd, "  TCP SIP Port:           ");
15177    if (sip_tcp_desc.local_address.sin_family == AF_INET) {
15178       ast_cli(a->fd, "%d\n", ntohs(sip_tcp_desc.local_address.sin_port));
15179       ast_cli(a->fd, "  TCP Bindaddress:        %s\n", ast_inet_ntoa(sip_tcp_desc.local_address.sin_addr));
15180    } else {
15181       ast_cli(a->fd, "Disabled\n");
15182    }
15183    ast_cli(a->fd, "  TLS SIP Port:           ");
15184    if (default_tls_cfg.enabled != FALSE) {
15185       ast_cli(a->fd, "%d\n", ntohs(sip_tls_desc.local_address.sin_port));
15186       ast_cli(a->fd, "  TLS Bindaddress:        %s\n", ast_inet_ntoa(sip_tls_desc.local_address.sin_addr));
15187    } else {
15188       ast_cli(a->fd, "Disabled\n");
15189    }
15190    ast_cli(a->fd, "  Videosupport:           %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_VIDEOSUPPORT)));
15191    ast_cli(a->fd, "  Textsupport:            %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_TEXTSUPPORT)));
15192    ast_cli(a->fd, "  AutoCreate Peer:        %s\n", cli_yesno(autocreatepeer));
15193    ast_cli(a->fd, "  Ignore SDP sess. ver.:  %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_IGNORESDPVERSION)));
15194    ast_cli(a->fd, "  Match Auth Username:    %s\n", cli_yesno(global_match_auth_username));
15195    ast_cli(a->fd, "  Allow unknown access:   %s\n", cli_yesno(global_allowguest));
15196    ast_cli(a->fd, "  Allow subscriptions:    %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)));
15197    ast_cli(a->fd, "  Allow overlap dialing:  %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP)));
15198    ast_cli(a->fd, "  Allow promsic. redir:   %s\n", cli_yesno(ast_test_flag(&global_flags[0], SIP_PROMISCREDIR)));
15199    ast_cli(a->fd, "  Enable call counters:   %s\n", cli_yesno(global_callcounter));
15200    ast_cli(a->fd, "  SIP domain support:     %s\n", cli_yesno(!AST_LIST_EMPTY(&domain_list)));
15201    ast_cli(a->fd, "  Realm. auth:            %s\n", cli_yesno(authl != NULL));
15202    ast_cli(a->fd, "  Our auth realm          %s\n", global_realm);
15203    ast_cli(a->fd, "  Call to non-local dom.: %s\n", cli_yesno(allow_external_domains));
15204    ast_cli(a->fd, "  URI user is phone no:   %s\n", cli_yesno(ast_test_flag(&global_flags[0], SIP_USEREQPHONE)));
15205    ast_cli(a->fd, "  Always auth rejects:    %s\n", cli_yesno(global_alwaysauthreject));
15206    ast_cli(a->fd, "  Direct RTP setup:       %s\n", cli_yesno(global_directrtpsetup));
15207    ast_cli(a->fd, "  User Agent:             %s\n", global_useragent);
15208    ast_cli(a->fd, "  SDP Session Name:       %s\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession);
15209    ast_cli(a->fd, "  SDP Owner Name:         %s\n", ast_strlen_zero(global_sdpowner) ? "-" : global_sdpowner);
15210    ast_cli(a->fd, "  Reg. context:           %s\n", S_OR(global_regcontext, "(not set)"));
15211    ast_cli(a->fd, "  Regexten on Qualify:    %s\n", cli_yesno(global_regextenonqualify));
15212    ast_cli(a->fd, "  Caller ID:              %s\n", default_callerid);
15213    ast_cli(a->fd, "  From: Domain:           %s\n", default_fromdomain);
15214    ast_cli(a->fd, "  Record SIP history:     %s\n", recordhistory ? "On" : "Off");
15215    ast_cli(a->fd, "  Call Events:            %s\n", global_callevents ? "On" : "Off");
15216    ast_cli(a->fd, "  Auth. Failure Events:   %s\n", global_authfailureevents ? "On" : "Off");
15217 
15218    ast_cli(a->fd, "  T.38 support:           %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT)));
15219    ast_cli(a->fd, "  T.38 EC mode:           %s\n", faxec2str(ast_test_flag(&global_flags[1], SIP_PAGE2_T38SUPPORT)));
15220    ast_cli(a->fd, "  T.38 MaxDtgrm:          %d\n", global_t38_maxdatagram);
15221 
15222    if (!realtimepeers && !realtimeregs)
15223       ast_cli(a->fd, "  SIP realtime:           Disabled\n" );
15224    else
15225       ast_cli(a->fd, "  SIP realtime:           Enabled\n" );
15226    ast_cli(a->fd, "  Qualify Freq :          %d ms\n", global_qualifyfreq);
15227    ast_cli(a->fd, "\nNetwork QoS Settings:\n");
15228    ast_cli(a->fd, "---------------------------\n");
15229    ast_cli(a->fd, "  IP ToS SIP:             %s\n", ast_tos2str(global_tos_sip));
15230    ast_cli(a->fd, "  IP ToS RTP audio:       %s\n", ast_tos2str(global_tos_audio));
15231    ast_cli(a->fd, "  IP ToS RTP video:       %s\n", ast_tos2str(global_tos_video));
15232    ast_cli(a->fd, "  IP ToS RTP text:        %s\n", ast_tos2str(global_tos_text));
15233    ast_cli(a->fd, "  802.1p CoS SIP:         %d\n", global_cos_sip);
15234    ast_cli(a->fd, "  802.1p CoS RTP audio:   %d\n", global_cos_audio);
15235    ast_cli(a->fd, "  802.1p CoS RTP video:   %d\n", global_cos_video);
15236    ast_cli(a->fd, "  802.1p CoS RTP text:    %d\n", global_cos_text);
15237    ast_cli(a->fd, "  Jitterbuffer enabled:   %s\n", cli_yesno(ast_test_flag(&global_jbconf, AST_JB_ENABLED)));
15238    ast_cli(a->fd, "  Jitterbuffer forced:    %s\n", cli_yesno(ast_test_flag(&global_jbconf, AST_JB_FORCED)));
15239    ast_cli(a->fd, "  Jitterbuffer max size:  %ld\n", global_jbconf.max_size);
15240    ast_cli(a->fd, "  Jitterbuffer resync:    %ld\n", global_jbconf.resync_threshold);
15241    ast_cli(a->fd, "  Jitterbuffer impl:      %s\n", global_jbconf.impl);
15242    ast_cli(a->fd, "  Jitterbuffer log:       %s\n", cli_yesno(ast_test_flag(&global_jbconf, AST_JB_LOG)));
15243 
15244    ast_cli(a->fd, "\nNetwork Settings:\n");
15245    ast_cli(a->fd, "---------------------------\n");
15246    /* determine if/how SIP address can be remapped */
15247    if (localaddr == NULL)
15248       msg = "Disabled, no localnet list";
15249    else if (externip.sin_addr.s_addr == 0)
15250       msg = "Disabled, externip is 0.0.0.0";
15251    else if (stunaddr.sin_addr.s_addr != 0)
15252       msg = "Enabled using STUN";
15253    else if (!ast_strlen_zero(externhost))
15254       msg = "Enabled using externhost";
15255    else
15256       msg = "Enabled using externip";
15257    ast_cli(a->fd, "  SIP address remapping:  %s\n", msg);
15258    ast_cli(a->fd, "  Externhost:             %s\n", S_OR(externhost, "<none>"));
15259    ast_cli(a->fd, "  Externip:               %s:%d\n", ast_inet_ntoa(externip.sin_addr), ntohs(externip.sin_port));
15260    ast_cli(a->fd, "  Externrefresh:          %d\n", externrefresh);
15261    ast_cli(a->fd, "  Internal IP:            %s:%d\n", ast_inet_ntoa(internip.sin_addr), ntohs(internip.sin_port));
15262    {
15263       struct ast_ha *d;
15264       const char *prefix = "Localnet:";
15265       char buf[INET_ADDRSTRLEN]; /* need to print two addresses */
15266 
15267       for (d = localaddr; d ; prefix = "", d = d->next) {
15268          ast_cli(a->fd, "  %-24s%s/%s\n",
15269              prefix, ast_inet_ntoa(d->netaddr),
15270              inet_ntop(AF_INET, &d->netmask, buf, sizeof(buf)) );
15271       }
15272    }
15273    ast_cli(a->fd, "  STUN server:            %s:%d\n", ast_inet_ntoa(stunaddr.sin_addr), ntohs(stunaddr.sin_port));
15274  
15275    ast_cli(a->fd, "\nGlobal Signalling Settings:\n");
15276    ast_cli(a->fd, "---------------------------\n");
15277    ast_cli(a->fd, "  Codecs:                 ");
15278    ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, global_capability);
15279    ast_cli(a->fd, "%s\n", codec_buf);
15280    ast_cli(a->fd, "  Codec Order:            ");
15281    print_codec_to_cli(a->fd, &default_prefs);
15282    ast_cli(a->fd, "\n");
15283    ast_cli(a->fd, "  Relax DTMF:             %s\n", cli_yesno(global_relaxdtmf));
15284    ast_cli(a->fd, "  RFC2833 Compensation:   %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_RFC2833_COMPENSATE)));
15285    ast_cli(a->fd, "  Compact SIP headers:    %s\n", cli_yesno(compactheaders));
15286    ast_cli(a->fd, "  RTP Keepalive:          %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" );
15287    ast_cli(a->fd, "  RTP Timeout:            %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" );
15288    ast_cli(a->fd, "  RTP Hold Timeout:       %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)");
15289    ast_cli(a->fd, "  MWI NOTIFY mime type:   %s\n", default_notifymime);
15290    ast_cli(a->fd, "  DNS SRV lookup:         %s\n", cli_yesno(global_srvlookup));
15291    ast_cli(a->fd, "  Pedantic SIP support:   %s\n", cli_yesno(pedanticsipchecking));
15292    ast_cli(a->fd, "  Reg. min duration       %d secs\n", min_expiry);
15293    ast_cli(a->fd, "  Reg. max duration:      %d secs\n", max_expiry);
15294    ast_cli(a->fd, "  Reg. default duration:  %d secs\n", default_expiry);
15295    ast_cli(a->fd, "  Outbound reg. timeout:  %d secs\n", global_reg_timeout);
15296    ast_cli(a->fd, "  Outbound reg. attempts: %d\n", global_regattempts_max);
15297    ast_cli(a->fd, "  Notify ringing state:   %s\n", cli_yesno(global_notifyringing));
15298    ast_cli(a->fd, "  Notify hold state:      %s\n", cli_yesno(global_notifyhold));
15299    ast_cli(a->fd, "  SIP Transfer mode:      %s\n", transfermode2str(global_allowtransfer));
15300    ast_cli(a->fd, "  Max Call Bitrate:       %d kbps\n", default_maxcallbitrate);
15301    ast_cli(a->fd, "  Auto-Framing:           %s\n", cli_yesno(global_autoframing));
15302    ast_cli(a->fd, "  Outb. proxy:            %s %s\n", ast_strlen_zero(global_outboundproxy.name) ? "<not set>" : global_outboundproxy.name,
15303                      global_outboundproxy.force ? "(forced)" : "");
15304    ast_cli(a->fd, "  Session Timers:         %s\n", stmode2str(global_st_mode));
15305    ast_cli(a->fd, "  Session Refresher:      %s\n", strefresher2str (global_st_refresher));
15306    ast_cli(a->fd, "  Session Expires:        %d secs\n", global_max_se);
15307    ast_cli(a->fd, "  Session Min-SE:         %d secs\n", global_min_se);
15308    ast_cli(a->fd, "  Timer T1:               %d\n", global_t1);
15309    ast_cli(a->fd, "  Timer T1 minimum:       %d\n", global_t1min);
15310    ast_cli(a->fd, "  Timer B:                %d\n", global_timer_b);
15311    ast_cli(a->fd, "  No premature media:     %s\n", global_prematuremediafilter ? "Yes" : "No");
15312 
15313    ast_cli(a->fd, "\nDefault Settings:\n");
15314    ast_cli(a->fd, "-----------------\n");
15315    ast_cli(a->fd, "  Context:                %s\n", default_context);
15316    ast_cli(a->fd, "  Nat:                    %s\n", nat2str(ast_test_flag(&global_flags[0], SIP_NAT)));
15317    ast_cli(a->fd, "  DTMF:                   %s\n", dtmfmode2str(ast_test_flag(&global_flags[0], SIP_DTMF)));
15318    ast_cli(a->fd, "  Qualify:                %d\n", default_qualify);
15319    ast_cli(a->fd, "  Use ClientCode:         %s\n", cli_yesno(ast_test_flag(&global_flags[0], SIP_USECLIENTCODE)));
15320    ast_cli(a->fd, "  Progress inband:        %s\n", (ast_test_flag(&global_flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NEVER) ? "Never" : (ast_test_flag(&global_flags[0], SIP_PROG_INBAND) == SIP_PROG_INBAND_NO) ? "No" : "Yes" );
15321    ast_cli(a->fd, "  Language:               %s\n", default_language);
15322    ast_cli(a->fd, "  MOH Interpret:          %s\n", default_mohinterpret);
15323    ast_cli(a->fd, "  MOH Suggest:            %s\n", default_mohsuggest);
15324    ast_cli(a->fd, "  Voice Mail Extension:   %s\n", default_vmexten);
15325 
15326    
15327    if (realtimepeers || realtimeregs) {
15328       ast_cli(a->fd, "\nRealtime SIP Settings:\n");
15329       ast_cli(a->fd, "----------------------\n");
15330       ast_cli(a->fd, "  Realtime Peers:         %s\n", cli_yesno(realtimepeers));
15331       ast_cli(a->fd, "  Realtime Regs:          %s\n", cli_yesno(realtimeregs));
15332       ast_cli(a->fd, "  Cache Friends:          %s\n", cli_yesno(ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)));
15333       ast_cli(a->fd, "  Update:                 %s\n", cli_yesno(sip_cfg.peer_rtupdate));
15334       ast_cli(a->fd, "  Ignore Reg. Expire:     %s\n", cli_yesno(sip_cfg.ignore_regexpire));
15335       ast_cli(a->fd, "  Save sys. name:         %s\n", cli_yesno(sip_cfg.rtsave_sysname));
15336       ast_cli(a->fd, "  Auto Clear:             %d\n", global_rtautoclear);
15337    }
15338    ast_cli(a->fd, "\n----\n");
15339    return CLI_SUCCESS;
15340 }

static char* sip_show_tcp ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Show active TCP connections.

Definition at line 13673 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ast_cli_args::argc, ast_cli(), ast_inet_ntoa(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_tcptls_session_instance::client, ast_cli_entry::command, ast_cli_args::fd, FORMAT, FORMAT2, get_transport(), ast_tcptls_session_instance::remote_address, sip_threadinfo::tcptls_session, threadt, sip_threadinfo::type, and ast_cli_entry::usage.

13674 {
13675    struct sip_threadinfo *th;
13676    struct ao2_iterator i;
13677 
13678 #define FORMAT2 "%-30.30s %3.6s %9.9s %6.6s\n"
13679 #define FORMAT  "%-30.30s %-6d %-9.9s %-6.6s\n"
13680 
13681    switch (cmd) {
13682    case CLI_INIT:
13683       e->command = "sip show tcp";
13684       e->usage =
13685          "Usage: sip show tcp\n"
13686          "       Lists all active TCP/TLS sessions.\n";
13687       return NULL;
13688    case CLI_GENERATE:
13689       return NULL;
13690    }
13691 
13692    if (a->argc != 3)
13693       return CLI_SHOWUSAGE;
13694 
13695    ast_cli(a->fd, FORMAT2, "Host", "Port", "Transport", "Type");
13696    i = ao2_iterator_init(threadt, 0);
13697    while ((th = ao2_t_iterator_next(&i, "iterate through tcp threads for 'sip show tcp'"))) {
13698       ast_cli(a->fd, FORMAT, ast_inet_ntoa(th->tcptls_session->remote_address.sin_addr), 
13699          ntohs(th->tcptls_session->remote_address.sin_port), 
13700          get_transport(th->type), 
13701          (th->tcptls_session->client ? "Client" : "Server"));
13702       ao2_t_ref(th, -1, "decrement ref from iterator");
13703    }
13704    ao2_iterator_destroy(&i);
13705    return CLI_SUCCESS;
13706 #undef FORMAT
13707 #undef FORMAT2
13708 }

static char* sip_show_user ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Show one user in detail.

Definition at line 14858 of file chan_sip.c.

References ao2_lock(), ao2_unlock(), ast_cli_args::argc, ast_cli_args::argv, ast_callerid_merge(), ast_cdr_flags2str(), ast_cli(), ast_describe_caller_presentation(), ast_strlen_zero(), ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, cli_yesno(), ast_cli_entry::command, complete_sip_show_user(), FALSE, ast_cli_args::fd, find_peer(), FINDUSERS, ast_cli_args::line, ast_cli_args::n, ast_variable::name, ast_variable::next, ast_cli_args::pos, print_codec_to_cli(), print_group(), SIP_PAGE2_IGNORESDPVERSION, stmode2str(), strefresher2str(), transfermode2str(), TRUE, unref_peer(), ast_cli_entry::usage, user, ast_variable::value, and ast_cli_args::word.

14859 {
14860    char cbuf[256];
14861    struct sip_peer *user;
14862    struct ast_variable *v;
14863    int load_realtime;
14864 
14865    switch (cmd) {
14866    case CLI_INIT:
14867       e->command = "sip show user";
14868       e->usage =
14869          "Usage: sip show user <name> [load]\n"
14870          "       Shows all details on one SIP user and the current status.\n"
14871          "       Option \"load\" forces lookup of peer in realtime storage.\n";
14872       return NULL;
14873    case CLI_GENERATE:
14874       return complete_sip_show_user(a->line, a->word, a->pos, a->n);
14875    }
14876 
14877    if (a->argc < 4)
14878       return CLI_SHOWUSAGE;
14879 
14880    /* Load from realtime storage? */
14881    load_realtime = (a->argc == 5 && !strcmp(a->argv[4], "load")) ? TRUE : FALSE;
14882 
14883    if ((user = find_peer(a->argv[3], NULL, load_realtime, FINDUSERS, FALSE, 0))) {
14884       ao2_lock(user);
14885       ast_cli(a->fd, "\n\n");
14886       ast_cli(a->fd, "  * Name       : %s\n", user->name);
14887       ast_cli(a->fd, "  Secret       : %s\n", ast_strlen_zero(user->secret)?"<Not set>":"<Set>");
14888       ast_cli(a->fd, "  MD5Secret    : %s\n", ast_strlen_zero(user->md5secret)?"<Not set>":"<Set>");
14889       ast_cli(a->fd, "  Context      : %s\n", user->context);
14890       ast_cli(a->fd, "  Language     : %s\n", user->language);
14891       if (!ast_strlen_zero(user->accountcode))
14892          ast_cli(a->fd, "  Accountcode  : %s\n", user->accountcode);
14893       ast_cli(a->fd, "  AMA flags    : %s\n", ast_cdr_flags2str(user->amaflags));
14894       ast_cli(a->fd, "  Transfer mode: %s\n", transfermode2str(user->allowtransfer));
14895       ast_cli(a->fd, "  MaxCallBR    : %d kbps\n", user->maxcallbitrate);
14896       ast_cli(a->fd, "  CallingPres  : %s\n", ast_describe_caller_presentation(user->callingpres));
14897       ast_cli(a->fd, "  Call limit   : %d\n", user->call_limit);
14898       ast_cli(a->fd, "  Callgroup    : ");
14899       print_group(a->fd, user->callgroup, 0);
14900       ast_cli(a->fd, "  Pickupgroup  : ");
14901       print_group(a->fd, user->pickupgroup, 0);
14902       ast_cli(a->fd, "  Callerid     : %s\n", ast_callerid_merge(cbuf, sizeof(cbuf), user->cid_name, user->cid_num, "<unspecified>"));
14903       ast_cli(a->fd, "  ACL          : %s\n", cli_yesno(user->ha != NULL));
14904       ast_cli(a->fd, "  Sess-Timers  : %s\n", stmode2str(user->stimer.st_mode_oper));
14905       ast_cli(a->fd, "  Sess-Refresh : %s\n", strefresher2str(user->stimer.st_ref));
14906       ast_cli(a->fd, "  Sess-Expires : %d secs\n", user->stimer.st_max_se);
14907       ast_cli(a->fd, "  Sess-Min-SE  : %d secs\n", user->stimer.st_min_se);
14908       ast_cli(a->fd, "  Ign SDP ver  : %s\n", cli_yesno(ast_test_flag(&user->flags[1], SIP_PAGE2_IGNORESDPVERSION)));
14909 
14910       ast_cli(a->fd, "  Codec Order  : (");
14911       print_codec_to_cli(a->fd, &user->prefs);
14912       ast_cli(a->fd, ")\n");
14913 
14914       ast_cli(a->fd, "  Auto-Framing:  %s \n", cli_yesno(user->autoframing));
14915       if (user->chanvars) {
14916          ast_cli(a->fd, "  Variables    :\n");
14917          for (v = user->chanvars ; v ; v = v->next)
14918             ast_cli(a->fd, "                 %s = %s\n", v->name, v->value);
14919       }
14920 
14921       ast_cli(a->fd, "\n");
14922 
14923       ao2_unlock(user);
14924       unref_peer(user, "sip show user");
14925    } else {
14926       ast_cli(a->fd, "User %s not found.\n", a->argv[3]);
14927       ast_cli(a->fd, "\n");
14928    }
14929 
14930    return CLI_SUCCESS;
14931 }

static char* sip_show_users ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

CLI Command 'SIP Show Users'.

Definition at line 13711 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_iterator_next, ao2_lock(), ao2_unlock(), ast_cli_args::argc, ast_cli_args::argv, ast_cli(), ast_test_flag, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, cli_yesno(), ast_cli_entry::command, FALSE, ast_cli_args::fd, FORMAT, nat2str(), peers, SIP_NAT, SIP_TYPE_USER, TRUE, unref_peer(), ast_cli_entry::usage, and user.

13712 {
13713    regex_t regexbuf;
13714    int havepattern = FALSE;
13715    struct ao2_iterator user_iter;
13716    struct sip_peer *user;
13717 
13718 #define FORMAT  "%-25.25s  %-15.15s  %-15.15s  %-15.15s  %-5.5s%-10.10s\n"
13719 
13720    switch (cmd) {
13721    case CLI_INIT:
13722       e->command = "sip show users";
13723       e->usage =
13724          "Usage: sip show users [like <pattern>]\n"
13725          "       Lists all known SIP users.\n"
13726          "       Optional regular expression pattern is used to filter the user list.\n";
13727       return NULL;
13728    case CLI_GENERATE:
13729       return NULL;
13730    }
13731 
13732    switch (a->argc) {
13733    case 5:
13734       if (!strcasecmp(a->argv[3], "like")) {
13735          if (regcomp(&regexbuf, a->argv[4], REG_EXTENDED | REG_NOSUB))
13736             return CLI_SHOWUSAGE;
13737          havepattern = TRUE;
13738       } else
13739          return CLI_SHOWUSAGE;
13740    case 3:
13741       break;
13742    default:
13743       return CLI_SHOWUSAGE;
13744    }
13745 
13746    ast_cli(a->fd, FORMAT, "Username", "Secret", "Accountcode", "Def.Context", "ACL", "NAT");
13747 
13748    user_iter = ao2_iterator_init(peers, 0);
13749    while ((user = ao2_iterator_next(&user_iter))) {
13750       ao2_lock(user);
13751       if (!(user->type & SIP_TYPE_USER)) {
13752          ao2_unlock(user);
13753          unref_peer(user, "sip show users");
13754          continue;
13755       }
13756 
13757       if (havepattern && regexec(&regexbuf, user->name, 0, NULL, 0)) {
13758          ao2_unlock(user);
13759          unref_peer(user, "sip show users");
13760          continue;
13761       }
13762 
13763       ast_cli(a->fd, FORMAT, user->name, 
13764          user->secret, 
13765          user->accountcode,
13766          user->context,
13767          cli_yesno(user->ha != NULL),
13768          nat2str(ast_test_flag(&user->flags[0], SIP_NAT)));
13769       ao2_unlock(user);
13770       unref_peer(user, "sip show users");
13771    }
13772    ao2_iterator_destroy(&user_iter);
13773 
13774    if (havepattern)
13775       regfree(&regexbuf);
13776 
13777    return CLI_SUCCESS;
13778 #undef FORMAT
13779 }

static int sip_sipredirect ( struct sip_pvt p,
const char *  dest 
) [static]

Transfer call before connect with a 302 redirect.

Note:
Called by the transfer() dialplan application through the sip_transfer() pbx interface function if the call is in ringing state
Todo:
Fix this function so that we wait for reply to the REFER and react to errors, denials or other issues the other end might have.

Definition at line 24478 of file chan_sip.c.

References ast_copy_string(), ast_log(), ast_strdupa, ast_string_field_build, ast_strlen_zero(), get_header(), sip_pvt::initreq, LOG_ERROR, sip_pvt::our_contact, sip_alreadygone(), sip_scheddestroy(), SIP_TRANS_TIMEOUT, strcasestr(), strsep(), and transmit_response_reliable().

Referenced by sip_transfer().

24479 {
24480    char *cdest;
24481    char *extension, *host, *port;
24482    char tmp[80];
24483 
24484    cdest = ast_strdupa(dest);
24485    
24486    extension = strsep(&cdest, "@");
24487    host = strsep(&cdest, ":");
24488    port = strsep(&cdest, ":");
24489    if (ast_strlen_zero(extension)) {
24490       ast_log(LOG_ERROR, "Missing mandatory argument: extension\n");
24491       return 0;
24492    }
24493 
24494    /* we'll issue the redirect message here */
24495    if (!host) {
24496       char *localtmp;
24497 
24498       ast_copy_string(tmp, get_header(&p->initreq, "To"), sizeof(tmp));
24499       if (ast_strlen_zero(tmp)) {
24500          ast_log(LOG_ERROR, "Cannot retrieve the 'To' header from the original SIP request!\n");
24501          return 0;
24502       }
24503       if ( ( (localtmp = strcasestr(tmp, "sip:")) || (localtmp = strcasestr(tmp, "sips:")) ) 
24504          && (localtmp = strchr(localtmp, '@'))) {
24505          char lhost[80], lport[80];
24506 
24507          memset(lhost, 0, sizeof(lhost));
24508          memset(lport, 0, sizeof(lport));
24509          localtmp++;
24510          /* This is okey because lhost and lport are as big as tmp */
24511          sscanf(localtmp, "%80[^<>:; ]:%80[^<>:; ]", lhost, lport);
24512          if (ast_strlen_zero(lhost)) {
24513             ast_log(LOG_ERROR, "Can't find the host address\n");
24514             return 0;
24515          }
24516          host = ast_strdupa(lhost);
24517          if (!ast_strlen_zero(lport)) {
24518             port = ast_strdupa(lport);
24519          }
24520       }
24521    }
24522 
24523    ast_string_field_build(p, our_contact, "Transfer <sip:%s@%s%s%s>", extension, host, port ? ":" : "", port ? port : "");
24524    transmit_response_reliable(p, "302 Moved Temporarily", &p->initreq);
24525 
24526    sip_scheddestroy(p, SIP_TRANS_TIMEOUT);   /* Make sure we stop send this reply. */
24527    sip_alreadygone(p);
24528    /* hangup here */
24529    return 0;
24530 }

static struct sip_st_dlg * sip_st_alloc ( struct sip_pvt *const   p  )  [static]

Allocate Session-Timers struct w/in dialog.

Definition at line 6714 of file chan_sip.c.

References ast_calloc, ast_log(), LOG_ERROR, sip_st_dlg::st_schedid, and sip_pvt::stimer.

Referenced by handle_request_invite(), and st_get_mode().

06715 {
06716    struct sip_st_dlg *stp;
06717 
06718    if (p->stimer) {
06719       ast_log(LOG_ERROR, "Session-Timer struct already allocated\n");
06720       return p->stimer;
06721    }
06722 
06723    if (!(stp = ast_calloc(1, sizeof(struct sip_st_dlg))))
06724       return NULL;
06725 
06726    p->stimer = stp;
06727 
06728    stp->st_schedid = -1;           /* Session-Timers ast_sched scheduler id */
06729 
06730    return p->stimer;
06731 }

static int sip_standard_port ( enum sip_transport  type,
int  port 
) [static]

Returns the port to use for this socket.

Parameters:
type The type of transport used
port Port we are checking to see if it's the standard port.
Note:
port is expected in host byte order

Definition at line 21123 of file chan_sip.c.

References SIP_TRANSPORT_TLS, STANDARD_SIP_PORT, and STANDARD_TLS_PORT.

Referenced by build_contact(), initreqprep(), and transmit_notify_with_mwi().

21124 {
21125    if (type & SIP_TRANSPORT_TLS)
21126       return port == STANDARD_TLS_PORT;
21127    else
21128       return port == STANDARD_SIP_PORT;
21129 }

static int sip_t38_abort ( const void *  data  )  [static]

Definition at line 18769 of file chan_sip.c.

References change_t38_state(), dialog_unref(), T38_DISABLED, and transmit_response_reliable().

Referenced by handle_request_invite().

18770 {
18771    struct sip_pvt *p = (struct sip_pvt *) data;
18772 
18773    change_t38_state(p, T38_DISABLED);
18774    transmit_response_reliable(p, "488 Not acceptable here", &p->initreq);
18775    p->t38id = -1;
18776    dialog_unref(p, "unref the dialog ptr from sip_t38_abort, because it held a dialog ptr");
18777 
18778    return 0;
18779 }

static struct ast_tcptls_session_instance* sip_tcp_locate ( struct sockaddr_in *  s  )  [static]

Find thread for TCP/TLS session (based on IP/Port.

Note:
This function returns an astobj2 reference

Definition at line 21148 of file chan_sip.c.

References ao2_callback, ao2_ref, ao2_t_ref, sip_threadinfo::tcptls_session, threadinfo_locate_cb(), and threadt.

Referenced by sip_prepare_socket().

21149 {
21150    struct sip_threadinfo *th;
21151    struct ast_tcptls_session_instance *tcptls_instance = NULL;
21152 
21153    if ((th = ao2_callback(threadt, 0, threadinfo_locate_cb, s))) {
21154       tcptls_instance = (ao2_ref(th->tcptls_session, +1), th->tcptls_session);
21155       ao2_t_ref(th, -1, "decrement ref from callback");
21156    }
21157    return tcptls_instance;
21158 }

static void * sip_tcp_worker_fn ( void *   )  [static]

SIP TCP connection handler.

Definition at line 2536 of file chan_sip.c.

References _sip_tcp_helper_thread().

Referenced by sip_prepare_socket().

02537 {
02538    struct ast_tcptls_session_instance *tcptls_session = data;
02539 
02540    return _sip_tcp_helper_thread(NULL, tcptls_session);
02541 }

static void sip_tcptls_client_args_destructor ( void *  obj  )  [static]

Definition at line 2419 of file chan_sip.c.

References ast_free, ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, ast_tls_config::cipher, ast_tcptls_session_args::name, and ast_tcptls_session_args::tls_cfg.

Referenced by sip_prepare_socket().

02420 {
02421    struct ast_tcptls_session_args *args = obj;
02422    if (args->tls_cfg) {
02423       ast_free(args->tls_cfg->certfile);
02424       ast_free(args->tls_cfg->cipher);
02425       ast_free(args->tls_cfg->cafile);
02426       ast_free(args->tls_cfg->capath);
02427    }
02428    ast_free(args->tls_cfg);
02429    ast_free((char *) args->name);
02430 }

static int sip_tcptls_write ( struct ast_tcptls_session_instance tcptls_session,
const void *  buf,
size_t  len 
) [static]

used to indicate to a tcptls thread that data is ready to be written

Definition at line 2478 of file chan_sip.c.

References sip_threadinfo::alert_pipe, ao2_alloc, ao2_lock(), ao2_t_find, ao2_t_ref, ao2_unlock(), AST_LIST_INSERT_TAIL, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_str_create(), ast_str_set(), errno, ast_tcptls_session_instance::fd, ast_tcptls_session_instance::lock, LOG_ERROR, OBJ_POINTER, sip_threadinfo::packet_q, TCPTLS_ALERT_DATA, tcptls_packet_destructor(), sip_threadinfo::tcptls_session, threadt, and XMIT_ERROR.

Referenced by __sip_xmit().

02479 {
02480    int res = len;
02481    struct sip_threadinfo *th = NULL;
02482    struct tcptls_packet *packet = NULL;
02483    struct sip_threadinfo tmp = {
02484       .tcptls_session = tcptls_session,
02485    };
02486    enum sip_tcptls_alert alert = TCPTLS_ALERT_DATA;
02487 
02488    if (!tcptls_session) {
02489       return XMIT_ERROR;
02490    }
02491 
02492    ast_mutex_lock(&tcptls_session->lock);
02493 
02494    if ((tcptls_session->fd == -1) ||
02495       !(th = ao2_t_find(threadt, &tmp, OBJ_POINTER, "ao2_find, getting sip_threadinfo in tcp helper thread")) ||
02496       !(packet = ao2_alloc(sizeof(*packet), tcptls_packet_destructor)) ||
02497       !(packet->data = ast_str_create(len))) {
02498       goto tcptls_write_setup_error;
02499    }
02500 
02501    /* goto tcptls_write_error should _NOT_ be used beyond this point */
02502    ast_str_set(&packet->data, 0, "%s", (char *) buf);
02503    packet->len = len;
02504 
02505    /* alert tcptls thread handler that there is a packet to be sent.
02506     * must lock the thread info object to guarantee control of the
02507     * packet queue */
02508    ao2_lock(th);
02509    if (write(th->alert_pipe[1], &alert, sizeof(alert)) == -1) {
02510       ast_log(LOG_ERROR, "write() to alert pipe failed: %s\n", strerror(errno));
02511       ao2_t_ref(packet, -1, "could not write to alert pipe, remove packet");
02512       packet = NULL;
02513       res = XMIT_ERROR;
02514    } else { /* it is safe to queue the frame after issuing the alert when we hold the threadinfo lock */
02515       AST_LIST_INSERT_TAIL(&th->packet_q, packet, entry);
02516    }
02517    ao2_unlock(th);
02518 
02519    ast_mutex_unlock(&tcptls_session->lock);
02520    ao2_t_ref(th, -1, "In sip_tcptls_write, unref threadinfo object after finding it");
02521    return res;
02522 
02523 tcptls_write_setup_error:
02524    if (th) {
02525       ao2_t_ref(th, -1, "In sip_tcptls_write, unref threadinfo obj, could not create packet");
02526    }
02527    if (packet) {
02528       ao2_t_ref(packet, -1, "could not allocate packet's data");
02529    }
02530    ast_mutex_unlock(&tcptls_session->lock);
02531 
02532    return XMIT_ERROR;
02533 }

static struct sip_threadinfo* sip_threadinfo_create ( struct ast_tcptls_session_instance tcptls_session,
int  transport 
) [static]

creates a sip_threadinfo object and links it into the threadt table.

Definition at line 2454 of file chan_sip.c.

References sip_threadinfo::alert_pipe, ao2_alloc, ao2_t_link, ao2_t_ref, ast_log(), errno, LOG_ERROR, sip_threadinfo_destructor(), SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, ast_tcptls_session_instance::ssl, sip_threadinfo::tcptls_session, and threadt.

Referenced by _sip_tcp_helper_thread(), and sip_prepare_socket().

02455 {
02456    struct sip_threadinfo *th;
02457 
02458    if (!tcptls_session || !(th = ao2_alloc(sizeof(*th), sip_threadinfo_destructor))) {
02459       return NULL;
02460    }
02461 
02462    th->alert_pipe[0] = th->alert_pipe[1] = -1;
02463 
02464    if (pipe(th->alert_pipe) == -1) {
02465       ao2_t_ref(th, -1, "Failed to open alert pipe on sip_threadinfo");
02466       ast_log(LOG_ERROR, "Could not create sip alert pipe in tcptls thread, error %s\n", strerror(errno));
02467       return NULL;
02468    }
02469    ao2_t_ref(tcptls_session, +1, "tcptls_session ref for sip_threadinfo object");
02470    th->tcptls_session = tcptls_session;
02471    th->type = transport ? transport : (tcptls_session->ssl ? SIP_TRANSPORT_TLS: SIP_TRANSPORT_TCP);
02472    ao2_t_link(threadt, th, "Adding new tcptls helper thread");
02473    ao2_t_ref(th, -1, "Decrementing threadinfo ref from alloc, only table ref remains");
02474    return th;
02475 }

static void sip_threadinfo_destructor ( void *  obj  )  [static]

Definition at line 2432 of file chan_sip.c.

References sip_threadinfo::alert_pipe, ao2_t_ref, AST_LIST_REMOVE_HEAD, tcptls_packet::entry, sip_threadinfo::packet_q, and sip_threadinfo::tcptls_session.

Referenced by sip_threadinfo_create().

02433 {
02434    struct sip_threadinfo *th = obj;
02435    struct tcptls_packet *packet;
02436    if (th->alert_pipe[1] > -1) {
02437       close(th->alert_pipe[0]);
02438    }
02439    if (th->alert_pipe[1] > -1) {
02440       close(th->alert_pipe[1]);
02441    }
02442    th->alert_pipe[0] = th->alert_pipe[1] = -1;
02443 
02444    while ((packet = AST_LIST_REMOVE_HEAD(&th->packet_q, entry))) {
02445       ao2_t_ref(packet, -1, "thread destruction, removing packet from frame queue");
02446    }
02447 
02448    if (th->tcptls_session) {
02449       ao2_t_ref(th->tcptls_session, -1, "remove tcptls_session for sip_threadinfo object");
02450    }
02451 }

static int sip_transfer ( struct ast_channel ast,
const char *  dest 
) [static]

Transfer SIP call.

Definition at line 5999 of file chan_sip.c.

References ast_channel::_state, AST_STATE_RING, sip_pvt_lock, sip_pvt_unlock, sip_sipredirect(), ast_channel::tech_pvt, and transmit_refer().

06000 {
06001    struct sip_pvt *p = ast->tech_pvt;
06002    int res;
06003 
06004    if (dest == NULL) /* functions below do not take a NULL */
06005       dest = "";
06006    sip_pvt_lock(p);
06007    if (ast->_state == AST_STATE_RING)
06008       res = sip_sipredirect(p, dest);
06009    else
06010       res = transmit_refer(p, dest);
06011    sip_pvt_unlock(p);
06012    return res;
06013 }

static char * sip_unregister ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Unregister (force expiration) a SIP peer in the registry via CLI.

Note:
This function does not tell the SIP device what's going on, so use it with great care.

Definition at line 15023 of file chan_sip.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_SCHED_DEL_UNREF, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_sip_unregister(), sip_peer::expire, expire_register(), ast_cli_args::fd, find_peer(), FINDPEERS, ast_cli_args::line, ast_cli_args::n, ast_cli_args::pos, ref_peer(), sched, TRUE, unref_peer(), ast_cli_entry::usage, and ast_cli_args::word.

15024 {
15025    struct sip_peer *peer;
15026    int load_realtime = 0;
15027 
15028    switch (cmd) {
15029    case CLI_INIT:
15030       e->command = "sip unregister";
15031       e->usage =
15032          "Usage: sip unregister <peer>\n"
15033          "       Unregister (force expiration) a SIP peer from the registry\n";
15034       return NULL;
15035    case CLI_GENERATE:
15036       return complete_sip_unregister(a->line, a->word, a->pos, a->n);
15037    }
15038    
15039    if (a->argc != 3)
15040       return CLI_SHOWUSAGE;
15041    
15042    if ((peer = find_peer(a->argv[2], NULL, load_realtime, FINDPEERS, TRUE, 0))) {
15043       if (peer->expire > 0) {
15044          AST_SCHED_DEL_UNREF(sched, peer->expire,
15045             unref_peer(peer, "remove register expire ref"));
15046          expire_register(ref_peer(peer, "ref for expire_register"));
15047          ast_cli(a->fd, "Unregistered peer \'%s\'\n\n", a->argv[2]);
15048       } else {
15049          ast_cli(a->fd, "Peer %s not registered\n", a->argv[2]);
15050       }
15051       unref_peer(peer, "sip_unregister: unref_peer via sip_unregister: done with peer from find_peer call");
15052    } else {
15053       ast_cli(a->fd, "Peer unknown: \'%s\'. Not unregistered.\n", a->argv[2]);
15054    }
15055    
15056    return CLI_SUCCESS;
15057 }

static int sip_uri_cmp ( const char *  input1,
const char *  input2 
) [static]

Definition at line 18686 of file chan_sip.c.

References ast_strdupa, S_OR, sip_uri_headers_cmp(), sip_uri_params_cmp(), and strsep().

Referenced by handle_request_invite().

18687 {
18688    char *uri1 = ast_strdupa(input1);
18689    char *uri2 = ast_strdupa(input2);
18690    char *host1;
18691    char *host2;
18692    char *params1;
18693    char *params2;
18694    char *headers1;
18695    char *headers2;
18696 
18697    /* Strip off "sip:" from the URI. We know this is present
18698     * because it was checked back in parse_request()
18699     */
18700    strsep(&uri1, ":");
18701    strsep(&uri2, ":");
18702 
18703    if ((host1 = strchr(uri1, '@'))) {
18704       *host1++ = '\0';
18705    }
18706    if ((host2 = strchr(uri2, '@'))) {
18707       *host2++ = '\0';
18708    }
18709 
18710    /* Check for mismatched username and passwords. This is the
18711     * only case-sensitive comparison of a SIP URI
18712     */
18713    if ((host1 && !host2) ||
18714          (host2 && !host1) ||
18715          (host1 && host2 && strcmp(uri1, uri2))) {
18716       return 1;
18717    }
18718 
18719    if (!host1)
18720       host1 = uri1;
18721    if (!host2)
18722       host2 = uri2;
18723 
18724    /* Strip off the parameters and headers so we can compare
18725     * host and port
18726     */
18727 
18728    if ((params1 = strchr(host1, ';'))) {
18729       *params1++ = '\0';
18730    }
18731    if ((params2 = strchr(host2, ';'))) {
18732       *params2++ = '\0';
18733    }
18734 
18735    /* Headers come after parameters, but there may be headers without
18736     * parameters, thus the S_OR
18737     */
18738    if ((headers1 = strchr(S_OR(params1, host1), '?'))) {
18739       *headers1++ = '\0';
18740    }
18741    if ((headers2 = strchr(S_OR(params2, host2), '?'))) {
18742       *headers2++ = '\0';
18743    }
18744 
18745    /* Now the host/port are properly isolated. We can get by with a string comparison
18746     * because the SIP URI checking rules have some interesting exceptions that make
18747     * this possible. I will note 2 in particular
18748     * 1. hostnames which resolve to the same IP address as well as a hostname and its
18749     *    IP address are not considered a match with SIP URI's.
18750     * 2. If one URI specifies a port and the other does not, then the URIs do not match.
18751     *    This includes if one URI explicitly contains port 5060 and the other implies it
18752     *    by not having a port specified.
18753     */
18754 
18755    if (strcasecmp(host1, host2)) {
18756       return 1;
18757    }
18758 
18759    /* Headers have easier rules to follow, so do those first */
18760    if (sip_uri_headers_cmp(headers1, headers2)) {
18761       return 1;
18762    }
18763 
18764    /* And now the parameters. Ugh */
18765    return sip_uri_params_cmp(params1, params2);
18766 }

static int sip_uri_headers_cmp ( const char *  input1,
const char *  input2 
) [static]

helper routine for sip_uri_cmp

This takes the "headers" from two SIP URIs and determines if the URIs match. The rules for headers is simple. If a header appears in one URI, then it must also appear in the other URI. The order in which the headers appear does not matter.

Parameters:
input1 Headers from URI 1
input2 Headers from URI 2
Returns:
Return 0 if the URIs' headers match, 1 if they do not

Definition at line 18640 of file chan_sip.c.

References ast_strdupa, ast_strlen_zero(), strcasestr(), and strsep().

Referenced by sip_uri_cmp().

18641 {
18642    char *headers1 = NULL;
18643    char *headers2 = NULL;
18644    int zerolength1 = 0;
18645    int zerolength2 = 0;
18646    int different = 0;
18647    char *header1;
18648 
18649    if (ast_strlen_zero(input1)) {
18650       zerolength1 = 1;
18651    } else {
18652       headers1 = ast_strdupa(input1);
18653    }
18654    
18655    if (ast_strlen_zero(input2)) {
18656       zerolength2 = 1;
18657    } else {
18658       headers2 = ast_strdupa(input2);
18659    }
18660 
18661    if ((zerolength1 && !zerolength2) ||
18662          (zerolength2 && !zerolength1))
18663       return 1;
18664 
18665    if (zerolength1 && zerolength2)
18666       return 0;
18667 
18668    /* At this point, we can definitively state that both inputs are
18669     * not zero-length. First, one more optimization. If the length
18670     * of the headers is not equal, then we definitely have no match
18671     */
18672    if (strlen(headers1) != strlen(headers2)) {
18673       return 1;
18674    }
18675 
18676    for (header1 = strsep(&headers1, "&"); header1; header1 = strsep(&headers1, "&")) {
18677       if (!strcasestr(headers2, header1)) {
18678          different = 1;
18679          break;
18680       }
18681    }
18682 
18683    return different;
18684 }

static int sip_uri_params_cmp ( const char *  input1,
const char *  input2 
) [static]

helper routine for sip_uri_cmp

This takes the parameters from two SIP URIs and determines if the URIs match. The rules for parameters *suck*. Here's a breakdown 1. If a parameter appears in both URIs, then they must have the same value in order for the URIs to match 2. If one URI has a user, maddr, ttl, or method parameter, then the other URI must also have that parameter and must have the same value in order for the URIs to match 3. All other headers appearing in only one URI are not considered when determining if URIs match

Parameters:
input1 Parameters from URI 1
input2 Parameters from URI 2
Returns:
Return 0 if the URIs' parameters match, 1 if they do not

Definition at line 18500 of file chan_sip.c.

References ast_strdupa, and ast_strlen_zero().

Referenced by sip_uri_cmp().

18501 {
18502    char *params1 = NULL;
18503    char *params2 = NULL;
18504    char *pos1;
18505    char *pos2;
18506    int zerolength1 = 0;
18507    int zerolength2 = 0;
18508    int maddrmatch = 0;
18509    int ttlmatch = 0;
18510    int usermatch = 0;
18511    int methodmatch = 0;
18512 
18513    if (ast_strlen_zero(input1)) {
18514       zerolength1 = 1;
18515    } else {
18516       params1 = ast_strdupa(input1);
18517    }
18518    if (ast_strlen_zero(input2)) {
18519       zerolength2 = 1;
18520    } else {
18521       params2 = ast_strdupa(input2);
18522    }
18523 
18524    /*Quick optimization. If both params are zero-length, then
18525     * they match
18526     */
18527    if (zerolength1 && zerolength2) {
18528       return 0;
18529    }
18530 
18531    pos1 = params1;
18532    while (!ast_strlen_zero(pos1)) {
18533       char *name1 = pos1;
18534       char *value1 = strchr(pos1, '=');
18535       char *semicolon1 = strchr(pos1, ';');
18536       int matched = 0;
18537       if (semicolon1) {
18538          *semicolon1++ = '\0';
18539       }
18540       if (!value1) {
18541          goto fail;
18542       }
18543       *value1++ = '\0';
18544       /* Checkpoint reached. We have the name and value parsed for param1 
18545        * We have to duplicate params2 each time through the second loop
18546        * or else we can't search and replace the semicolons with \0 each
18547        * time
18548        */
18549       pos2 = ast_strdupa(params2);
18550       while (!ast_strlen_zero(pos2)) {
18551          char *name2 = pos2;
18552          char *value2 = strchr(pos2, '=');
18553          char *semicolon2 = strchr(pos2, ';');
18554          if (semicolon2) {
18555             *semicolon2++ = '\0';
18556          }
18557          if (!value2) {
18558             goto fail;
18559          }
18560          *value2++ = '\0';
18561          if (!strcasecmp(name1, name2)) {
18562             if (strcasecmp(value1, value2)) {
18563                goto fail;
18564             } else {
18565                matched = 1;
18566                break;
18567             }
18568          }
18569          pos2 = semicolon2;
18570       }
18571       /* Need to see if the parameter we're looking at is one of the 'must-match' parameters */
18572       if (!strcasecmp(name1, "maddr")) {
18573          if (matched) {
18574             maddrmatch = 1;
18575          } else {
18576             goto fail;
18577          }
18578       } else if (!strcasecmp(name1, "ttl")) {
18579          if (matched) {
18580             ttlmatch = 1;
18581          } else {
18582             goto fail;
18583          }
18584       } else if (!strcasecmp(name1, "user")) {
18585          if (matched) {
18586             usermatch = 1;
18587          } else {
18588             goto fail;
18589          }
18590       } else if (!strcasecmp(name1, "method")) {
18591          if (matched) {
18592             methodmatch = 1;
18593          } else {
18594             goto fail;
18595          }
18596       }
18597       pos1 = semicolon1;
18598    }
18599 
18600    /* We've made it out of that horrible O(m*n) construct and there are no
18601     * failures yet. We're not done yet, though, because params2 could have
18602     * an maddr, ttl, user, or method header and params1 did not.
18603     */
18604    pos2 = params2;
18605    while (!ast_strlen_zero(pos2)) {
18606       char *name2 = pos2;
18607       char *value2 = strchr(pos2, '=');
18608       char *semicolon2 = strchr(pos2, ';');
18609       if (semicolon2) {
18610          *semicolon2++ = '\0';
18611       }
18612       if (!value2) {
18613          goto fail;
18614       }
18615       *value2++ = '\0';
18616       if ((!strcasecmp(name2, "maddr") && !maddrmatch) ||
18617             (!strcasecmp(name2, "ttl") && !ttlmatch) ||
18618             (!strcasecmp(name2, "user") && !usermatch) ||
18619             (!strcasecmp(name2, "method") && !methodmatch)) {
18620          goto fail;
18621       }
18622    }
18623    return 0;
18624 
18625 fail:
18626    return 1;
18627 }

static int sip_write ( struct ast_channel ast,
struct ast_frame frame 
) [static]

Send frame to media channel (rtp).

Definition at line 5799 of file chan_sip.c.

References ast_channel::_state, AST_FORMAT_AUDIO_MASK, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_getformatname_multiple(), ast_log(), ast_rtp_new_source(), ast_rtp_write(), ast_set_flag, AST_STATE_UP, ast_test_flag, ast_udptl_write(), ast_frame::frametype, INV_EARLY_MEDIA, LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, red_buffer_t140(), SIP_OUTGOING, SIP_PROGRESS_SENT, sip_pvt_lock, sip_pvt_unlock, ast_frame::subclass, T38_ENABLED, ast_channel::tech_pvt, transmit_provisional_response(), TRUE, and ast_channel::writeformat.

05800 {
05801    struct sip_pvt *p = ast->tech_pvt;
05802    int res = 0;
05803 
05804    switch (frame->frametype) {
05805    case AST_FRAME_VOICE:
05806       if (!(frame->subclass & ast->nativeformats)) {
05807          char s1[512], s2[512], s3[512];
05808          ast_log(LOG_WARNING, "Asked to transmit frame type %d, while native formats is %s(%d) read/write = %s(%d)/%s(%d)\n",
05809             frame->subclass, 
05810             ast_getformatname_multiple(s1, sizeof(s1) - 1, ast->nativeformats & AST_FORMAT_AUDIO_MASK),
05811             ast->nativeformats & AST_FORMAT_AUDIO_MASK,
05812             ast_getformatname_multiple(s2, sizeof(s2) - 1, ast->readformat),
05813             ast->readformat,
05814             ast_getformatname_multiple(s3, sizeof(s3) - 1, ast->writeformat),
05815             ast->writeformat);
05816          return 0;
05817       }
05818       if (p) {
05819          sip_pvt_lock(p);
05820          if (p->rtp) {
05821             /* If channel is not up, activate early media session */
05822             if ((ast->_state != AST_STATE_UP) &&
05823                 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
05824                 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
05825                ast_rtp_new_source(p->rtp);
05826                if (!global_prematuremediafilter) {
05827                   p->invitestate = INV_EARLY_MEDIA;
05828                   transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
05829                   ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
05830                }
05831             } else if (p->t38.state == T38_ENABLED) {
05832                /* drop frame, can't sent VOICE frames while in T.38 mode */
05833             } else {
05834                p->lastrtptx = time(NULL);
05835                res = ast_rtp_write(p->rtp, frame);
05836             }
05837          }
05838          sip_pvt_unlock(p);
05839       }
05840       break;
05841    case AST_FRAME_VIDEO:
05842       if (p) {
05843          sip_pvt_lock(p);
05844          if (p->vrtp) {
05845             /* Activate video early media */
05846             if ((ast->_state != AST_STATE_UP) &&
05847                 !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
05848                 !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
05849                p->invitestate = INV_EARLY_MEDIA;
05850                transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
05851                ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
05852             }
05853             p->lastrtptx = time(NULL);
05854             res = ast_rtp_write(p->vrtp, frame);
05855          }
05856          sip_pvt_unlock(p);
05857       }
05858       break;
05859    case AST_FRAME_TEXT:
05860       if (p) {
05861          sip_pvt_lock(p);
05862          if (p->red) {
05863             red_buffer_t140(p->trtp, frame);
05864          } else {
05865             if (p->trtp) {
05866                /* Activate text early media */
05867                if ((ast->_state != AST_STATE_UP) &&
05868                    !ast_test_flag(&p->flags[0], SIP_PROGRESS_SENT) &&
05869                    !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
05870                   p->invitestate = INV_EARLY_MEDIA;
05871                   transmit_provisional_response(p, "183 Session Progress", &p->initreq, TRUE);
05872                   ast_set_flag(&p->flags[0], SIP_PROGRESS_SENT);
05873                }
05874                p->lastrtptx = time(NULL);
05875                res = ast_rtp_write(p->trtp, frame);
05876             }
05877          }
05878          sip_pvt_unlock(p);
05879       }
05880       break;
05881    case AST_FRAME_IMAGE:
05882       return 0;
05883       break;
05884    case AST_FRAME_MODEM:
05885       if (p) {
05886          sip_pvt_lock(p);
05887          /* UDPTL requires two-way communication, so early media is not needed here.
05888             we simply forget the frames if we get modem frames before the bridge is up.
05889             Fax will re-transmit.
05890          */
05891          if ((ast->_state == AST_STATE_UP) &&
05892              p->udptl &&
05893              (p->t38.state == T38_ENABLED)) {
05894             res = ast_udptl_write(p->udptl, frame);
05895          }
05896          sip_pvt_unlock(p);
05897       }
05898       break;
05899    default: 
05900       ast_log(LOG_WARNING, "Can't send %d type frames with SIP write\n", frame->frametype);
05901       return 0;
05902    }
05903 
05904    return res;
05905 }

static int sipsock_read ( int *  id,
int  fd,
short  events,
void *  ignore 
) [static]

Read data from SIP socket.

Note:
sipsock_read locks the owner channel while we are processing the SIP message
Returns:
1 on error, 0 on success
Note:
Successful messages is connected to SIP call and forwarded to handle_incoming()

Definition at line 20962 of file chan_sip.c.

References AST_DYNSTR_BUILD_FAILED, ast_free, ast_log(), ast_str_create(), ast_str_set(), errno, handle_request_do(), LOG_NOTICE, LOG_WARNING, set_socket_transport(), SIP_MIN_PACKET, and SIP_TRANSPORT_UDP.

Referenced by do_monitor().

20963 {
20964    struct sip_request req;
20965    struct sockaddr_in sin = { 0, };
20966    int res;
20967    socklen_t len = sizeof(sin);
20968    static char readbuf[65535];
20969 
20970    memset(&req, 0, sizeof(req));
20971    res = recvfrom(fd, readbuf, sizeof(readbuf) - 1, 0, (struct sockaddr *)&sin, &len);
20972    if (res < 0) {
20973 #if !defined(__FreeBSD__)
20974       if (errno == EAGAIN)
20975          ast_log(LOG_NOTICE, "SIP: Received packet with bad UDP checksum\n");
20976       else 
20977 #endif
20978       if (errno != ECONNREFUSED)
20979          ast_log(LOG_WARNING, "Recv error: %s\n", strerror(errno));
20980       return 1;
20981    }
20982 
20983    readbuf[res] = '\0';
20984 
20985    if (!(req.data = ast_str_create(SIP_MIN_PACKET))) {
20986       return 1;
20987    }
20988 
20989    if (ast_str_set(&req.data, 0, "%s", readbuf) == AST_DYNSTR_BUILD_FAILED) {
20990       return -1;
20991    }
20992 
20993    req.len = res;
20994    req.socket.fd = sipsock;
20995    set_socket_transport(&req.socket, SIP_TRANSPORT_UDP);
20996    req.socket.tcptls_session  = NULL;
20997    req.socket.port = bindaddr.sin_port;
20998 
20999    handle_request_do(&req, &sin);
21000    if (req.data) {
21001       ast_free(req.data);
21002       req.data = NULL;
21003    }
21004 
21005    return 1;
21006 }

enum st_mode st_get_mode ( struct sip_pvt p  )  [static]

Get the session-timer mode.

Parameters:
p pointer to the SIP dialog

Definition at line 21893 of file chan_sip.c.

References FALSE, find_peer(), FINDPEERS, sip_pvt::peername, pp, SESSION_TIMER_MODE_INVALID, sip_st_alloc(), sip_st_dlg::st_cached_mode, sip_pvt::stimer, TRUE, and unref_peer().

Referenced by handle_request_invite(), handle_response_invite(), and transmit_invite().

21894 {
21895    if (!p->stimer) 
21896       sip_st_alloc(p);
21897 
21898    if (p->stimer->st_cached_mode != SESSION_TIMER_MODE_INVALID) 
21899       return p->stimer->st_cached_mode;
21900 
21901    if (p->peername) {
21902       struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDPEERS, FALSE, 0);
21903       if (pp) {
21904          p->stimer->st_cached_mode = pp->stimer.st_mode_oper;
21905          unref_peer(pp, "unref peer pointer from find_peer call in st_get_mode");
21906          return pp->stimer.st_mode_oper;
21907       }
21908    }
21909 
21910    p->stimer->st_cached_mode = global_st_mode;
21911    return global_st_mode;
21912 }

enum st_refresher st_get_refresher ( struct sip_pvt p  )  [static]

Get the entity (UAC or UAS) that's acting as the session-timer refresher.

Parameters:
p pointer to the SIP dialog

Definition at line 21871 of file chan_sip.c.

References FALSE, find_peer(), FINDPEERS, sip_pvt::peername, pp, SESSION_TIMER_REFRESHER_AUTO, sip_st_dlg::st_cached_ref, sip_pvt::stimer, TRUE, and unref_peer().

Referenced by handle_request_invite().

21872 {
21873    if (p->stimer->st_cached_ref != SESSION_TIMER_REFRESHER_AUTO) 
21874       return p->stimer->st_cached_ref;
21875 
21876    if (p->peername) {
21877       struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDPEERS, FALSE, 0);
21878       if (pp) {
21879          p->stimer->st_cached_ref = pp->stimer.st_ref;
21880          unref_peer(pp, "unref peer pointer from find_peer call in st_get_refresher");
21881          return pp->stimer.st_ref;
21882       }
21883    }
21884    
21885    p->stimer->st_cached_ref = global_st_refresher;
21886    return global_st_refresher;
21887 }

int st_get_se ( struct sip_pvt p,
int  max 
) [static]

Get Max or Min SE (session timer expiry).

Parameters:
p pointer to the SIP dialog
max if true, get max se, otherwise min se

Definition at line 21836 of file chan_sip.c.

References FALSE, find_peer(), FINDPEERS, sip_pvt::peername, pp, sip_st_dlg::st_cached_max_se, sip_st_dlg::st_cached_min_se, sip_pvt::stimer, TRUE, and unref_peer().

Referenced by handle_request_invite(), reqprep(), and transmit_invite().

21837 {
21838    if (max == TRUE) {
21839       if (p->stimer->st_cached_max_se) {
21840          return p->stimer->st_cached_max_se;
21841       } else if (p->peername) {
21842          struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDPEERS, FALSE, 0);
21843          if (pp) {
21844             p->stimer->st_cached_max_se = pp->stimer.st_max_se;
21845             unref_peer(pp, "unref peer pointer from find_peer call in st_get_se");
21846             return (p->stimer->st_cached_max_se);
21847          }
21848       }
21849       p->stimer->st_cached_max_se = global_max_se;
21850       return (p->stimer->st_cached_max_se);
21851    } else {
21852       if (p->stimer->st_cached_min_se) {
21853          return p->stimer->st_cached_min_se;
21854       } else if (p->peername) {
21855          struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDPEERS, FALSE, 0);
21856          if (pp) {
21857             p->stimer->st_cached_min_se = pp->stimer.st_min_se;
21858             unref_peer(pp, "unref peer pointer from find_peer call in st_get_se (2)");
21859             return (p->stimer->st_cached_min_se);
21860          }
21861       }
21862       p->stimer->st_cached_min_se = global_min_se;
21863       return (p->stimer->st_cached_min_se);
21864    }
21865 }

static void start_session_timer ( struct sip_pvt p  )  [static]

Session-Timers: Start session timer.

Definition at line 21633 of file chan_sip.c.

References ast_debug, ast_log(), ast_sched_add(), sip_pvt::callid, dialog_ref(), dialog_unref(), LOG_ERROR, LOG_WARNING, proc_session_timer(), sched, sip_st_dlg::st_interval, sip_st_dlg::st_schedid, and sip_pvt::stimer.

Referenced by handle_request_invite(), handle_response_invite(), and restart_session_timer().

21634 {
21635    if (!p->stimer) {
21636       ast_log(LOG_WARNING, "Null stimer in start_session_timer - %s\n", p->callid);
21637       return;
21638    }
21639 
21640    p->stimer->st_schedid  = ast_sched_add(sched, p->stimer->st_interval * 1000 / 2, proc_session_timer, 
21641          dialog_ref(p, "adding session timer ref"));
21642    if (p->stimer->st_schedid < 0) {
21643       dialog_unref(p, "removing session timer ref");
21644       ast_log(LOG_ERROR, "ast_sched_add failed.\n");
21645    }
21646    ast_debug(2, "Session timer started: %d - %s\n", p->stimer->st_schedid, p->callid);
21647 }

static const char* stmode2str ( enum st_mode  m  )  [static]

Definition at line 13610 of file chan_sip.c.

References map_x_s(), and stmodes.

Referenced by _sip_show_peer(), sip_show_channel(), sip_show_settings(), and sip_show_user().

13611 {
13612    return map_x_s(stmodes, m, "Unknown");
13613 }

static void stop_media_flows ( struct sip_pvt p  )  [static]

Immediately stop RTP, VRTP and UDPTL as applicable.

Definition at line 17445 of file chan_sip.c.

References ast_rtp_stop(), ast_udptl_stop(), sip_pvt::rtp, sip_pvt::trtp, sip_pvt::udptl, and sip_pvt::vrtp.

Referenced by handle_request_bye(), handle_request_cancel(), handle_response(), and sip_hangup().

17446 {
17447    /* Immediately stop RTP, VRTP and UDPTL as applicable */
17448    if (p->rtp)
17449       ast_rtp_stop(p->rtp);
17450    if (p->vrtp)
17451       ast_rtp_stop(p->vrtp);
17452    if (p->trtp)
17453       ast_rtp_stop(p->trtp);
17454    if (p->udptl)
17455       ast_udptl_stop(p->udptl);
17456 }

static void stop_session_timer ( struct sip_pvt p  )  [static]

Session-Timers: Stop session timer.

Definition at line 21616 of file chan_sip.c.

References ast_debug, ast_log(), AST_SCHED_DEL_UNREF, sip_pvt::callid, dialog_unref(), FALSE, LOG_WARNING, sched, sip_st_dlg::st_active, sip_st_dlg::st_schedid, sip_pvt::stimer, and TRUE.

Referenced by handle_request_bye(), proc_session_timer(), sip_hangup(), and sip_scheddestroy().

21617 {
21618    if (!p->stimer) {
21619       ast_log(LOG_WARNING, "Null stimer in stop_session_timer - %s\n", p->callid);
21620       return;
21621    }
21622 
21623    if (p->stimer->st_active == TRUE) {
21624       p->stimer->st_active = FALSE;
21625       AST_SCHED_DEL_UNREF(sched, p->stimer->st_schedid,
21626             dialog_unref(p, "removing session timer ref"));
21627       ast_debug(2, "Session timer stopped: %d - %s\n", p->stimer->st_schedid, p->callid);
21628    }
21629 }

static int str2dtmfmode ( const char *  str  )  [static]

maps a string to dtmfmode, returns -1 on error

Definition at line 14134 of file chan_sip.c.

References dtmfstr, and map_s_x().

14135 {
14136    return map_s_x(dtmfstr, str, -1);
14137 }

static enum st_mode str2stmode ( const char *  s  )  [static]

Definition at line 13615 of file chan_sip.c.

References map_s_x(), and stmodes.

Referenced by build_peer().

13616 {
13617    return map_s_x(stmodes, s, -1);
13618 }

static enum st_refresher str2strefresher ( const char *  s  )  [static]

Definition at line 13633 of file chan_sip.c.

References map_s_x(), and strefreshers.

Referenced by build_peer().

13634 {
13635    return map_s_x(strefreshers, s, -1);
13636 }

static const char * strefresher2str ( enum st_refresher  r  )  [static]

Definition at line 13628 of file chan_sip.c.

References map_x_s(), and strefreshers.

Referenced by _sip_show_peer(), reqprep(), respprep(), sip_show_channel(), sip_show_settings(), and sip_show_user().

13629 {
13630    return map_x_s(strefreshers, r, "Unknown");
13631 }

static const char * subscription_type2str ( enum subscriptiontype  subtype  )  [static]

Show subscription type in string format.

Definition at line 15343 of file chan_sip.c.

References ARRAY_LEN, subscription_types, and cfsubscription_types::text.

Referenced by show_channels_cb(), and sip_show_channel().

15344 {
15345    int i;
15346 
15347    for (i = 1; i < ARRAY_LEN(subscription_types); i++) {
15348       if (subscription_types[i].type == subtype) {
15349          return subscription_types[i].text;
15350       }
15351    }
15352    return subscription_types[0].text;
15353 }

static unsigned int t38_get_rate ( enum ast_control_t38_rate  rate  )  [static]

Get Max T.38 Transmission rate from T38 capabilities.

Definition at line 9287 of file chan_sip.c.

References AST_T38_RATE_12000, AST_T38_RATE_14400, AST_T38_RATE_2400, AST_T38_RATE_4800, AST_T38_RATE_7200, and AST_T38_RATE_9600.

Referenced by add_sdp().

09288 {
09289    switch (rate) {
09290    case AST_T38_RATE_2400:
09291       return 2400;
09292    case AST_T38_RATE_4800:
09293       return 4800;
09294    case AST_T38_RATE_7200:
09295       return 7200;
09296    case AST_T38_RATE_9600:
09297       return 9600;
09298    case AST_T38_RATE_12000:
09299       return 12000;
09300    case AST_T38_RATE_14400:
09301       return 14400;
09302    default:
09303       return 0;
09304    }
09305 }

static void tcptls_packet_destructor ( void *  obj  )  [static]

Definition at line 2412 of file chan_sip.c.

References ast_free, and tcptls_packet::data.

Referenced by sip_tcptls_write().

02413 {
02414    struct tcptls_packet *packet = obj;
02415 
02416    ast_free(packet->data);
02417 }

static struct sip_peer * temp_peer ( const char *  name  )  [static]

Create temporary peer (used in autocreatepeer mode).

Definition at line 22719 of file chan_sip.c.

References ao2_t_alloc, ast_atomic_fetchadd_int(), ast_copy_string(), default_prefs, reg_source_db(), set_peer_defaults(), sip_destroy_peer_fn(), and TRUE.

Referenced by register_verify().

22720 {
22721    struct sip_peer *peer;
22722 
22723    if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct")))
22724       return NULL;
22725 
22726    ast_atomic_fetchadd_int(&apeerobjs, 1);
22727    set_peer_defaults(peer);
22728 
22729    ast_copy_string(peer->name, name, sizeof(peer->name));
22730 
22731    peer->selfdestruct = TRUE;
22732    peer->host_dynamic = TRUE;
22733    peer->prefs = default_prefs;
22734    reg_source_db(peer);
22735 
22736    return peer;
22737 }

static void temp_pvt_cleanup ( void *   )  [static]

Definition at line 8958 of file chan_sip.c.

References ast_free, and ast_string_field_free_memory.

08959 {
08960    struct sip_pvt *p = data;
08961 
08962    ast_string_field_free_memory(p);
08963 
08964    ast_free(data);
08965 }

static int temp_pvt_init ( void *   )  [static]

Definition at line 8950 of file chan_sip.c.

References ast_string_field_init, and sip_pvt::do_history.

08951 {
08952    struct sip_pvt *p = data;
08953 
08954    p->do_history = 0;   /* XXX do we need it ? isn't already all 0 ? */
08955    return ast_string_field_init(p, 512);
08956 }

static char* terminate_uri ( char *  uri  )  [static]

Terminate the uri at the first ';' or space. Technically we should ignore escaped space per RFC3261 (19.1.1 etc) but don't do it for the time being. Remember the uri format is:

 *
 *	sip:user:password@host:port;uri-parameters?headers
 *	sips:user:password@host:port;uri-parameters?headers
 *
 *

Definition at line 12126 of file chan_sip.c.

Referenced by check_user_full(), and register_verify().

12127 {
12128    char *t = uri;
12129    while (*t && *t > ' ' && *t != ';')
12130       t++;
12131    *t = '\0';
12132    return uri;
12133 }

static int threadinfo_locate_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 21131 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, inaddrcmp(), ast_tcptls_session_instance::remote_address, s, and sip_threadinfo::tcptls_session.

Referenced by sip_tcp_locate().

21132 {
21133    struct sip_threadinfo *th = obj;
21134    struct sockaddr_in *s = arg;
21135 
21136    if (!inaddrcmp(&th->tcptls_session->remote_address, s)) {
21137       return CMP_MATCH | CMP_STOP;
21138    }
21139 
21140    return 0;
21141 }

static int threadt_cmp_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 1773 of file chan_sip.c.

References CMP_MATCH, CMP_STOP, and sip_threadinfo::tcptls_session.

Referenced by load_module().

01774 {
01775    struct sip_threadinfo *th = obj, *th2 = arg;
01776 
01777    return (th->tcptls_session == th2->tcptls_session) ? CMP_MATCH | CMP_STOP : 0;
01778 }

static int threadt_hash_cb ( const void *  obj,
const int  flags 
) [static]

Definition at line 1766 of file chan_sip.c.

References ast_tcptls_session_instance::remote_address, and sip_threadinfo::tcptls_session.

Referenced by load_module().

01767 {
01768    const struct sip_threadinfo *th = obj;
01769 
01770    return (int) th->tcptls_session->remote_address.sin_addr.s_addr;
01771 }

static char * transfermode2str ( enum transfermodes  mode  )  const [static]

Convert transfer mode to text string.

Definition at line 13554 of file chan_sip.c.

References TRANSFER_CLOSED, and TRANSFER_OPENFORALL.

Referenced by _sip_show_peer(), sip_show_channel(), sip_show_settings(), and sip_show_user().

13555 {
13556    if (mode == TRANSFER_OPENFORALL)
13557       return "open";
13558    else if (mode == TRANSFER_CLOSED)
13559       return "closed";
13560    return "strict";
13561 }

static void transmit_fake_auth_response ( struct sip_pvt p,
int  sipmethod,
struct sip_request req,
enum xmittype  reliable 
) [static]

Send a fake 401 Unauthorized response when the administrator wants to hide the names of local devices from fishers.

Definition at line 12023 of file chan_sip.c.

References AST_DYNSTR_BUILD_FAILED, ast_skip_blanks(), ast_str_set(), ast_str_thread_get(), ast_strlen_zero(), buf, check_auth_buf, CHECK_AUTH_BUF_INITLEN, DEFAULT_TRANS_TIMEOUT, get_header(), sip_request::ignore, sip_pvt::initreq, sip_pvt::randdata, s, set_nonce_randdata(), SIP_REGISTER, sip_scheddestroy(), SIP_SUBSCRIBE, strsep(), transmit_response(), and transmit_response_with_auth().

Referenced by handle_request_invite(), handle_request_subscribe(), and register_verify().

12024 {
12025    /* We have to emulate EXACTLY what we'd get with a good peer
12026     * and a bad password, or else we leak information. */
12027    const char *response = "407 Proxy Authentication Required";
12028    const char *reqheader = "Proxy-Authorization";
12029    const char *respheader = "Proxy-Authenticate";
12030    const char *authtoken;
12031    struct ast_str *buf;
12032    char *c;
12033 
12034    /* table of recognised keywords, and their value in the digest */
12035    enum keys { K_NONCE, K_LAST };
12036    struct x {
12037       const char *key;
12038       const char *s;
12039    } *i, keys[] = {
12040       [K_NONCE] = { "nonce=", "" },
12041       [K_LAST] = { NULL, NULL}
12042    };
12043 
12044    if (sipmethod == SIP_REGISTER || sipmethod == SIP_SUBSCRIBE) {
12045       response = "401 Unauthorized";
12046       reqheader = "Authorization";
12047       respheader = "WWW-Authenticate";
12048    }
12049    authtoken = get_header(req, reqheader);
12050    if (req->ignore && !ast_strlen_zero(p->randdata) && ast_strlen_zero(authtoken)) {
12051       /* This is a retransmitted invite/register/etc, don't reconstruct authentication
12052        * information */
12053       transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0);
12054       /* Schedule auto destroy in 32 seconds (according to RFC 3261) */
12055       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12056       return;
12057    } else if (ast_strlen_zero(p->randdata) || ast_strlen_zero(authtoken)) {
12058       /* We have no auth, so issue challenge and request authentication */
12059       set_nonce_randdata(p, 1);
12060       transmit_response_with_auth(p, response, req, p->randdata, 0, respheader, 0);
12061       /* Schedule auto destroy in 32 seconds */
12062       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12063       return;
12064    }
12065 
12066    if (!(buf = ast_str_thread_get(&check_auth_buf, CHECK_AUTH_BUF_INITLEN))) {
12067       transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
12068       return;
12069    }
12070 
12071    /* Make a copy of the response and parse it */
12072    if (ast_str_set(&buf, 0, "%s", authtoken) == AST_DYNSTR_BUILD_FAILED) {
12073       transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
12074       return;
12075    }
12076 
12077    c = buf->str;
12078 
12079    while (c && *(c = ast_skip_blanks(c))) { /* lookup for keys */
12080       for (i = keys; i->key != NULL; i++) {
12081          const char *separator = ",";  /* default */
12082 
12083          if (strncasecmp(c, i->key, strlen(i->key)) != 0) {
12084             continue;
12085          }
12086          /* Found. Skip keyword, take text in quotes or up to the separator. */
12087          c += strlen(i->key);
12088          if (*c == '"') { /* in quotes. Skip first and look for last */
12089             c++;
12090             separator = "\"";
12091          }
12092          i->s = c;
12093          strsep(&c, separator);
12094          break;
12095       }
12096       if (i->key == NULL) { /* not found, jump after space or comma */
12097          strsep(&c, " ,");
12098       }
12099    }
12100 
12101    /* Verify nonce from request matches our nonce.  If not, send 401 with new nonce */
12102    if (strcasecmp(p->randdata, keys[K_NONCE].s)) {
12103       if (!req->ignore) {
12104          set_nonce_randdata(p, 1);
12105       }
12106       transmit_response_with_auth(p, response, req, p->randdata, reliable, respheader, FALSE);
12107 
12108       /* Schedule auto destroy in 32 seconds */
12109       sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
12110    } else {
12111       transmit_response(p, "403 Forbidden (Bad auth)", &p->initreq);
12112    }
12113 }

static int transmit_info_with_digit ( struct sip_pvt p,
const char  digit,
unsigned int  duration 
) [static]

Send SIP INFO dtmf message, see Cisco documentation on cisco.com.

Definition at line 11115 of file chan_sip.c.

References add_digit(), ast_test_flag, sip_pvt::flags, sip_pvt::ocseq, reqprep(), send_request(), SIP_DTMF, SIP_DTMF_SHORTINFO, SIP_INFO, and XMIT_RELIABLE.

Referenced by sip_senddigit_end().

11116 {
11117    struct sip_request req;
11118    
11119    reqprep(&req, p, SIP_INFO, 0, 1);
11120    add_digit(&req, digit, duration, (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_SHORTINFO));
11121    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
11122 }

static int transmit_info_with_vidupdate ( struct sip_pvt p  )  [static]

Send SIP INFO with video update request.

Definition at line 11125 of file chan_sip.c.

References add_vidupdate(), sip_pvt::ocseq, reqprep(), send_request(), SIP_INFO, and XMIT_RELIABLE.

Referenced by sip_indicate().

11126 {
11127    struct sip_request req;
11128    
11129    reqprep(&req, p, SIP_INFO, 0, 1);
11130    add_vidupdate(&req);
11131    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
11132 }

static int transmit_invite ( struct sip_pvt p,
int  sipmethod,
int  sdp,
int  init 
) [static]

Build REFER/INVITE/OPTIONS message and transmit it.

Parameters:
init 0 = Prepare request within dialog, 1= prepare request, new branch, 2= prepare new request and new dialog. do_proxy_auth calls this with init!=2
p sip_pvt structure
sdp unknown
sipmethod unknown

Definition at line 10185 of file chan_sip.c.

References add_header(), add_header_contentLength(), add_sdp(), sip_invite_param::addsipheaders, ALLOWED_METHODS, append_date(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_debug, AST_LIST_TRAVERSE, ast_log(), ast_random(), ast_skip_blanks(), ast_strdupa, ast_strlen_zero(), ast_unescape_semicolon(), ast_var_name(), ast_var_value(), sip_invite_param::auth, sip_invite_param::authheader, sip_pvt::branch, buf, build_via(), chan, ast_var_t::entries, FALSE, sip_request::header, sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::invite_branch, sip_pvt::lastinvite, LOG_WARNING, sip_request::method, ast_channel::name, sip_pvt::notify_headers, sip_pvt::ocseq, sip_pvt::offered_media, sip_pvt::options, sip_pvt::owner, sip_pvt::refer, sip_refer::refer_to, sip_refer::referred_by, sip_refer::referred_by_name, sip_invite_param::replaces, reqprep(), sip_pvt::rtp, send_request(), SESSION_TIMER_MODE_ORIGINATE, SIP_REFER, SIPBUFSIZE, sip_st_dlg::st_active, st_get_mode(), st_get_se(), sip_st_dlg::st_interval, t38properties::state, sip_pvt::stimer, SUPPORTED_EXTENSIONS, sip_pvt::t38, T38_LOCAL_REINVITE, TRUE, sip_pvt::udptl, var, ast_channel::varshead, XMIT_CRITICAL, and XMIT_RELIABLE.

Referenced by do_proxy_auth(), proc_422_rsp(), sip_call(), and sip_poke_peer().

10186 {
10187    struct sip_request req;
10188    struct ast_variable *var;
10189    
10190    req.method = sipmethod;
10191    if (init) {/* Bump branch even on initial requests */
10192       p->branch ^= ast_random();
10193       p->invite_branch = p->branch;
10194       build_via(p);
10195    }
10196    if (init > 1)
10197       initreqprep(&req, p, sipmethod);
10198    else
10199       /* If init=1, we should not generate a new branch. If it's 0, we need a new branch. */
10200       reqprep(&req, p, sipmethod, 0, init ? 0 : 1);
10201       
10202    if (p->options && p->options->auth)
10203       add_header(&req, p->options->authheader, p->options->auth);
10204    append_date(&req);
10205    if (sipmethod == SIP_REFER) { /* Call transfer */
10206       if (p->refer) {
10207          char buf[SIPBUFSIZE];
10208          if (!ast_strlen_zero(p->refer->refer_to))
10209             add_header(&req, "Refer-To", p->refer->refer_to);
10210          if (!ast_strlen_zero(p->refer->referred_by)) {
10211             snprintf(buf, sizeof(buf), "%s <%s>", p->refer->referred_by_name, p->refer->referred_by);
10212             add_header(&req, "Referred-By", buf);
10213          }
10214       }
10215    }
10216    /* This new INVITE is part of an attended transfer. Make sure that the
10217    other end knows and replace the current call with this new call */
10218    if (p->options && !ast_strlen_zero(p->options->replaces)) {
10219       add_header(&req, "Replaces", p->options->replaces);
10220       add_header(&req, "Require", "replaces");
10221    }
10222 
10223    /* Add Session-Timers related headers */
10224    if (st_get_mode(p) == SESSION_TIMER_MODE_ORIGINATE) {
10225       char i2astr[10];
10226 
10227       if (!p->stimer->st_interval)
10228          p->stimer->st_interval = st_get_se(p, TRUE);
10229 
10230       p->stimer->st_active = TRUE;
10231       
10232       snprintf(i2astr, sizeof(i2astr), "%d", p->stimer->st_interval);
10233       add_header(&req, "Session-Expires", i2astr);
10234       snprintf(i2astr, sizeof(i2astr), "%d", st_get_se(p, FALSE));
10235       add_header(&req, "Min-SE", i2astr);
10236    }
10237 
10238    add_header(&req, "Allow", ALLOWED_METHODS);
10239    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
10240 
10241    if(p->notify_headers) {
10242       char buf[512];
10243       for (var = p->notify_headers; var; var = var->next) {
10244          ast_copy_string(buf, var->value, sizeof(buf));
10245          add_header(&req, var->name, ast_unescape_semicolon(buf));
10246       }
10247    }
10248    if (p->options && p->options->addsipheaders && p->owner) {
10249       struct ast_channel *chan = p->owner; /* The owner channel */
10250       struct varshead *headp;
10251    
10252       ast_channel_lock(chan);
10253 
10254       headp = &chan->varshead;
10255 
10256       if (!headp)
10257          ast_log(LOG_WARNING, "No Headp for the channel...ooops!\n");
10258       else {
10259          const struct ast_var_t *current;
10260          AST_LIST_TRAVERSE(headp, current, entries) {  
10261             /* SIPADDHEADER: Add SIP header to outgoing call */
10262             if (!strncasecmp(ast_var_name(current), "SIPADDHEADER", strlen("SIPADDHEADER"))) {
10263                char *content, *end;
10264                const char *header = ast_var_value(current);
10265                char *headdup = ast_strdupa(header);
10266 
10267                /* Strip of the starting " (if it's there) */
10268                if (*headdup == '"')
10269                   headdup++;
10270                if ((content = strchr(headdup, ':'))) {
10271                   *content++ = '\0';
10272                   content = ast_skip_blanks(content); /* Skip white space */
10273                   /* Strip the ending " (if it's there) */
10274                   end = content + strlen(content) -1; 
10275                   if (*end == '"')
10276                      *end = '\0';
10277                
10278                   add_header(&req, headdup, content);
10279                   if (sipdebug)
10280                      ast_debug(1, "Adding SIP Header \"%s\" with content :%s: \n", headdup, content);
10281                }
10282             }
10283          }
10284       }
10285 
10286       ast_channel_unlock(chan);
10287    }
10288    if (sdp) {
10289       memset(p->offered_media, 0, sizeof(p->offered_media));
10290       if (p->udptl && p->t38.state == T38_LOCAL_REINVITE) {
10291          ast_debug(1, "T38 is in state %d on channel %s\n", p->t38.state, p->owner ? p->owner->name : "<none>");
10292          add_sdp(&req, p, FALSE, FALSE, TRUE);
10293       } else if (p->rtp) 
10294          add_sdp(&req, p, FALSE, TRUE, FALSE);
10295    } else {
10296       if (!p->notify_headers) {
10297          add_header_contentLength(&req, 0);
10298       }
10299    }
10300 
10301    if (!p->initreq.headers || init > 2)
10302       initialize_initreq(p, &req);
10303    p->lastinvite = p->ocseq;
10304    return send_request(p, &req, init ? XMIT_CRITICAL : XMIT_RELIABLE, p->ocseq);
10305 }

static int transmit_message_with_text ( struct sip_pvt p,
const char *  text 
) [static]

Transmit text with SIP MESSAGE method.

Definition at line 11021 of file chan_sip.c.

References add_text(), sip_pvt::ocseq, reqprep(), send_request(), SIP_MESSAGE, and XMIT_RELIABLE.

Referenced by sip_park_thread(), and sip_sendtext().

11022 {
11023    struct sip_request req;
11024    
11025    reqprep(&req, p, SIP_MESSAGE, 0, 1);
11026    add_text(&req, text);
11027    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
11028 }

static int transmit_notify_custom ( struct sip_pvt p,
struct ast_variable vars 
) [static]

Notify device with custom headers from sip_notify.conf.

Definition at line 10569 of file chan_sip.c.

References add_header(), ast_copy_string(), ast_debug, ast_unescape_semicolon(), ast_variable_new(), buf, sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), ast_variable::name, ast_variable::next, sip_pvt::notify_headers, sip_pvt::ocseq, send_request(), SIP_NOTIFY, ast_variable::value, var, and XMIT_UNRELIABLE.

Referenced by manager_sipnotify(), and sip_cli_notify().

10569                                                                                 {
10570    struct sip_request req;
10571    struct ast_variable *var, *newvar;
10572 
10573    initreqprep(&req, p, SIP_NOTIFY);
10574 
10575    /* Copy notify vars and add headers */
10576    p->notify_headers = newvar = ast_variable_new("Subscription-State", "terminated", "");
10577    add_header(&req, newvar->name, newvar->value);
10578    for (var = vars; var; var = var->next) {
10579       char buf[512];
10580       ast_debug(2, "  Adding pair %s=%s\n", var->name, var->value);
10581       ast_copy_string(buf, var->value, sizeof(buf));
10582       add_header(&req, var->name, ast_unescape_semicolon(buf));
10583       newvar->next = ast_variable_new(var->name, var->value, "");
10584       newvar = newvar->next;
10585    }
10586 
10587    if (!p->initreq.headers) { /* Initialize first request before sending */
10588       initialize_initreq(p, &req);
10589    }
10590 
10591    return send_request(p, &req, XMIT_UNRELIABLE, p->ocseq);
10592 }

static int transmit_notify_with_mwi ( struct sip_pvt p,
int  newmsgs,
int  oldmsgs,
char *  vmexten 
) [static]

Notify user of messages waiting in voicemail (RFC3842).

Note:
- Notification only works for registered peers with mailbox= definitions in sip.conf
  • We use the SIP Event package message-summary MIME type defaults to "application/simple-message-summary";

Definition at line 10496 of file chan_sip.c.

References add_header(), add_header_contentLength(), add_line(), ast_inet_ntoa(), ast_str_alloca, ast_str_append(), ast_strlen_zero(), ast_test_flag, sip_pvt::expiry, exten, sip_pvt::flags, sip_pvt::fromdomain, get_transport(), sip_request::headers, initialize_initreq(), sip_pvt::initreq, initreqprep(), sip_pvt::ocseq, sip_pvt::ourip, ourport, S_OR, send_request(), SIP_NOTIFY, SIP_PAGE2_BUGGY_MWI, sip_standard_port(), SIP_TRANSPORT_UDP, sip_pvt::socket, ast_str::str, sip_pvt::subscribed, sip_socket::type, ast_str::used, and XMIT_RELIABLE.

Referenced by sip_send_mwi_to_peer().

10497 {
10498    struct sip_request req;
10499    struct ast_str *out = ast_str_alloca(500);
10500    int ourport = ntohs(p->ourip.sin_port);
10501    const char *exten = S_OR(vmexten, default_vmexten);
10502 
10503    initreqprep(&req, p, SIP_NOTIFY);
10504    add_header(&req, "Event", "message-summary");
10505    add_header(&req, "Content-Type", default_notifymime);
10506    ast_str_append(&out, 0, "Messages-Waiting: %s\r\n", newmsgs ? "yes" : "no");
10507 
10508    if (!ast_strlen_zero(p->fromdomain)) {
10509       ast_str_append(&out, 0, "Message-Account: sip:%s@%s\r\n", exten, p->fromdomain);
10510    } else if (!sip_standard_port(p->socket.type, ourport)) {
10511       if (p->socket.type == SIP_TRANSPORT_UDP) {
10512          ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d\r\n", exten, ast_inet_ntoa(p->ourip.sin_addr), ourport);
10513       } else {
10514          ast_str_append(&out, 0, "Message-Account: sip:%s@%s:%d;transport=%s\r\n", exten, ast_inet_ntoa(p->ourip.sin_addr), ourport, get_transport(p->socket.type));
10515       }
10516    } else {
10517       if (p->socket.type == SIP_TRANSPORT_UDP) {
10518          ast_str_append(&out, 0, "Message-Account: sip:%s@%s\r\n", exten, ast_inet_ntoa(p->ourip.sin_addr));
10519       } else {
10520          ast_str_append(&out, 0, "Message-Account: sip:%s@%s;transport=%s\r\n", exten, ast_inet_ntoa(p->ourip.sin_addr), get_transport(p->socket.type));
10521       }
10522    }
10523    /* Cisco has a bug in the SIP stack where it can't accept the
10524       (0/0) notification. This can temporarily be disabled in
10525       sip.conf with the "buggymwi" option */
10526    ast_str_append(&out, 0, "Voice-Message: %d/%d%s\r\n",
10527       newmsgs, oldmsgs, (ast_test_flag(&p->flags[1], SIP_PAGE2_BUGGY_MWI) ? "" : " (0/0)"));
10528 
10529    if (p->subscribed) {
10530       if (p->expiry)
10531          add_header(&req, "Subscription-State", "active");
10532       else  /* Expired */
10533          add_header(&req, "Subscription-State", "terminated;reason=timeout");
10534    }
10535 
10536    add_header_contentLength(&req, out->used);
10537    add_line(&req, out->str);
10538 
10539    if (!p->initreq.headers) 
10540       initialize_initreq(p, &req);
10541    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
10542 }

static int transmit_notify_with_sipfrag ( struct sip_pvt p,
int  cseq,
char *  message,
int  terminate 
) [static]

Notify a transferring party of the status of transfer (RFC3515).

Definition at line 10545 of file chan_sip.c.

References add_header(), add_header_contentLength(), add_line(), ALLOWED_METHODS, sip_request::headers, initialize_initreq(), sip_pvt::initreq, sip_pvt::ocseq, reqprep(), send_request(), SIP_NOTIFY, SIPBUFSIZE, SUPPORTED_EXTENSIONS, and XMIT_RELIABLE.

Referenced by handle_request_refer(), local_attended_transfer(), and sip_park_thread().

10546 {
10547    struct sip_request req;
10548    char tmp[SIPBUFSIZE/2];
10549    
10550    reqprep(&req, p, SIP_NOTIFY, 0, 1);
10551    snprintf(tmp, sizeof(tmp), "refer;id=%d", cseq);
10552    add_header(&req, "Event", tmp);
10553    add_header(&req, "Subscription-state", terminate ? "terminated;reason=noresource" : "active");
10554    add_header(&req, "Content-Type", "message/sipfrag;version=2.0");
10555    add_header(&req, "Allow", ALLOWED_METHODS);
10556    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
10557 
10558    snprintf(tmp, sizeof(tmp), "SIP/2.0 %s\r\n", message);
10559    add_header_contentLength(&req, strlen(tmp));
10560    add_line(&req, tmp);
10561 
10562    if (!p->initreq.headers)
10563       initialize_initreq(p, &req);
10564 
10565    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
10566 }

static int transmit_provisional_response ( struct sip_pvt p,
const char *  msg,
const struct sip_request req,
int  with_sdp 
) [static]

Definition at line 9115 of file chan_sip.c.

References FALSE, transmit_response(), transmit_response_with_sdp(), update_provisional_keepalive(), and XMIT_UNRELIABLE.

Referenced by handle_request_invite(), sip_indicate(), and sip_write().

09116 {
09117    int res;
09118 
09119    if (!(res = with_sdp ? transmit_response_with_sdp(p, msg, req, XMIT_UNRELIABLE, FALSE) : transmit_response(p, msg, req))) {
09120       p->last_provisional = msg;
09121       update_provisional_keepalive(p, with_sdp);
09122    }
09123 
09124    return res;
09125 }

static int transmit_refer ( struct sip_pvt p,
const char *  dest 
) [static]

Transmit SIP REFER message (initiated by the transfer() dialplan application.

Note:
this is currently broken as we have no way of telling the dialplan engine whether a transfer succeeds or fails.
Todo:
Fix the transfer() dialplan function so that a transfer may fail

Todo:
In theory, we should hang around and wait for a reply, before returning to the dial plan here. Don't know really how that would affect the transfer() app or the pbx, but, well, to make this useful we should have a STATUS code on transfer().

Definition at line 11042 of file chan_sip.c.

References add_header(), ALLOWED_METHODS, ast_copy_string(), ast_debug, ast_log(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_test_flag, sip_pvt::callid, sip_pvt::flags, get_header(), get_in_brackets(), sip_request::headers, sip_pvt::initreq, LOG_NOTICE, sip_pvt::ocseq, sip_pvt::our_contact, sip_pvt::refer, REFER_SENT, sip_refer::refer_to, sip_refer::referred_by, reqprep(), send_request(), SIP_OUTGOING, SIP_REFER, sip_refer_allocate(), sip_refer::status, SUPPORTED_EXTENSIONS, sip_pvt::tag, sip_pvt::theirtag, and XMIT_RELIABLE.

Referenced by sip_transfer().

11043 {
11044    struct sip_request req = { 
11045       .headers = 0,  
11046    };
11047    char from[256];
11048    const char *of;
11049    char *c;
11050    char referto[256];
11051    char *ttag, *ftag;
11052    char *theirtag = ast_strdupa(p->theirtag);
11053 
11054    if (sipdebug)
11055       ast_debug(1, "SIP transfer of %s to %s\n", p->callid, dest);
11056 
11057    /* Are we transfering an inbound or outbound call ? */
11058    if (ast_test_flag(&p->flags[0], SIP_OUTGOING))  {
11059       of = get_header(&p->initreq, "To");
11060       ttag = theirtag;
11061       ftag = p->tag;
11062    } else {
11063       of = get_header(&p->initreq, "From");
11064       ftag = theirtag;
11065       ttag = p->tag;
11066    }
11067 
11068    ast_copy_string(from, of, sizeof(from));
11069    of = get_in_brackets(from);
11070    ast_string_field_set(p, from, of);
11071    if (!strncasecmp(of, "sip:", 4))
11072       of += 4;
11073    else if (!strncasecmp(of, "sips:", 5))
11074       of += 5;
11075    else
11076       ast_log(LOG_NOTICE, "From address missing 'sip(s):', using it anyway\n");
11077    /* Get just the username part */
11078    if ((c = strchr(dest, '@')))
11079       c = NULL;
11080    else if ((c = strchr(of, '@')))
11081       *c++ = '\0';
11082    if (c) 
11083       snprintf(referto, sizeof(referto), "<sip:%s@%s>", dest, c);
11084    else
11085       snprintf(referto, sizeof(referto), "<sip:%s>", dest);
11086 
11087    /* save in case we get 407 challenge */
11088    sip_refer_allocate(p);
11089    ast_copy_string(p->refer->refer_to, referto, sizeof(p->refer->refer_to));
11090    ast_copy_string(p->refer->referred_by, p->our_contact, sizeof(p->refer->referred_by));
11091    p->refer->status = REFER_SENT;   /* Set refer status */
11092 
11093    reqprep(&req, p, SIP_REFER, 0, 1);
11094 
11095    add_header(&req, "Refer-To", referto);
11096    add_header(&req, "Allow", ALLOWED_METHODS);
11097    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
11098    if (!ast_strlen_zero(p->our_contact))
11099       add_header(&req, "Referred-By", p->our_contact);
11100 
11101    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
11102 
11103    /* We should propably wait for a NOTIFY here until we ack the transfer */
11104    /* Maybe fork a new thread and wait for a STATUS of REFER_200OK on the refer status before returning to app_transfer */
11105 
11106    /*! \todo In theory, we should hang around and wait for a reply, before
11107    returning to the dial plan here. Don't know really how that would
11108    affect the transfer() app or the pbx, but, well, to make this
11109    useful we should have a STATUS code on transfer().
11110    */
11111 }

static int transmit_register ( struct sip_registry r,
int  sipmethod,
const char *  auth,
const char *  authheader 
) [static]

Transmit register to SIP proxy or UA auth = NULL on the initial registration (from sip_reregister()).

Definition at line 10773 of file chan_sip.c.

References add_header(), add_header_contentLength(), append_history, ast_debug, ast_dnsmgr_lookup(), ast_log(), ast_random(), ast_sched_add(), AST_SCHED_REPLACE_UNREF, ast_set_flag, ast_sip_ouraddrfor(), ast_string_field_set, ast_strlen_zero(), ast_verbose, sip_peer::auth, sip_registry::authuser, sip_pvt::branch, build_callid_registry(), build_contact(), build_reply_digest(), build_via(), sip_registry::call, sip_registry::callback, sip_pvt::callid, sip_registry::callid, sip_registry::callid_valid, create_addr(), DEFAULT_MAX_FORWARDS, dialog_ref(), dialog_unlink_all(), dialog_unref(), sip_registry::dnsmgr, sip_pvt::do_history, sip_registry::domain, sip_registry::expiry, exten, FALSE, find_peer(), FINDPEERS, sip_pvt::flags, sip_pvt::fromdomain, sip_peer::fromdomain, sip_peer::fromuser, get_transport(), sip_request::headers, sip_registry::hostname, init_req(), initialize_initreq(), sip_pvt::initreq, sip_request::lines, ast_tcptls_session_args::local_address, LOG_NOTICE, LOG_WARNING, make_our_tag(), MAXHOSTNAMELEN, sip_registry::md5secret, sip_registry::nonce, sip_registry::noncecount, sip_pvt::noncecount, obproxy_get(), sip_pvt::ocseq, sip_registry::ocseq, sip_registry::opaque, sip_pvt::our_contact, sip_pvt::ourip, sip_pvt::peerauth, sip_registry::peername, sip_socket::port, sip_registry::portno, sip_registry::qop, sip_registry::realm, sip_pvt::recv, ref_proxy(), REG_STATE_AUTHSENT, REG_STATE_REGSENT, sip_registry::regattempts, sip_pvt::registry, registry_addref(), registry_unref(), sip_registry::regstate, sip_pvt::sa, sched, sip_registry::secret, send_request(), set_socket_transport(), sip_alloc(), sip_debug_test_pvt(), sip_methods, SIP_OUTGOING, sip_reg_timeout(), SIP_REGISTER, sip_tcp_desc, SIP_TRANSPORT_TCP, SIP_TRANSPORT_TLS, sip_pvt::socket, STANDARD_SIP_PORT, sip_pvt::tag, cfsip_methods::text, sip_pvt::theirtag, sip_registry::timeout, sip_pvt::tohost, sip_peer::tohost, sip_registry::transport, TRUE, unref_peer(), sip_registry::us, sip_peer::username, sip_registry::username, sip_pvt::via, and XMIT_CRITICAL.

Referenced by __sip_do_register(), do_register_auth(), handle_response_register(), and sip_reg_timeout().

10774 {
10775    struct sip_request req;
10776    char from[256];
10777    char to[256];
10778    char tmp[80];
10779    char addr[80];
10780    struct sip_pvt *p;
10781    struct sip_peer *peer = NULL;
10782    int res;
10783    char *fromdomain;
10784 
10785    /* exit if we are already in process with this registrar ?*/
10786    if (r == NULL || ((auth == NULL) && (r->regstate == REG_STATE_REGSENT || r->regstate == REG_STATE_AUTHSENT))) {
10787       if (r) {
10788          ast_log(LOG_NOTICE, "Strange, trying to register %s@%s when registration already pending\n", r->username, r->hostname);
10789       }
10790       return 0;
10791    }
10792 
10793    if (r->dnsmgr == NULL) {
10794       char transport[MAXHOSTNAMELEN];
10795       peer = find_peer(r->hostname, NULL, TRUE, FINDPEERS, FALSE, 0);
10796       snprintf(transport, sizeof(transport), "_sip._%s", get_transport(r->transport)); /* have to use static get_transport function */
10797       ast_dnsmgr_lookup(peer ? peer->tohost : r->hostname, &r->us, &r->dnsmgr, global_srvlookup ? transport : NULL);
10798       if (peer) {
10799          peer = unref_peer(peer, "removing peer ref for dnsmgr_lookup");
10800       }
10801    }
10802 
10803    if (r->call) { /* We have a registration */
10804       if (!auth) {
10805          ast_log(LOG_WARNING, "Already have a REGISTER going on to %s@%s?? \n", r->username, r->hostname);
10806          return 0;
10807       } else {
10808          p = dialog_ref(r->call, "getting a copy of the r->call dialog in transmit_register");
10809          make_our_tag(p->tag, sizeof(p->tag));  /* create a new local tag for every register attempt */
10810          ast_string_field_set(p, theirtag, NULL);  /* forget their old tag, so we don't match tags when getting response */
10811       }
10812    } else {
10813       /* Build callid for registration if we haven't registered before */
10814       if (!r->callid_valid) {
10815          build_callid_registry(r, internip.sin_addr, default_fromdomain);
10816          r->callid_valid = TRUE;
10817       }
10818       /* Allocate SIP dialog for registration */
10819       if (!(p = sip_alloc( r->callid, NULL, 0, SIP_REGISTER, NULL))) {
10820          ast_log(LOG_WARNING, "Unable to allocate registration transaction (memory or socket error)\n");
10821          return 0;
10822       }
10823       
10824       if (p->do_history)
10825          append_history(p, "RegistryInit", "Account: %s@%s", r->username, r->hostname);
10826 
10827       if (!ast_strlen_zero(r->peername)) {
10828          if (!(peer = find_peer(r->peername, NULL, 1, FINDPEERS, FALSE, 0))) {
10829             ast_log(LOG_WARNING, "Could not find peer %s in transmit_register\n", r->peername);
10830          } else {
10831             p->peerauth = peer->auth;
10832          }
10833       }
10834       ref_proxy(p, obproxy_get(p, peer)); /* it is ok to pass a NULL peer into obproxy_get() */
10835       if (peer) {
10836          unref_peer(peer, "transmit_registration: from find_peer operation");
10837       }
10838       /* Use port number specified if no SRV record was found */
10839       if (!r->us.sin_port && r->portno)
10840          r->us.sin_port = htons(r->portno);
10841 
10842       /* Find address to hostname */
10843       if (create_addr(p, r->hostname, &r->us, 0)) {
10844          /* we have what we hope is a temporary network error,
10845           * probably DNS.  We need to reschedule a registration try */
10846          dialog_unlink_all(p, TRUE, TRUE);
10847          p = dialog_unref(p, "unref dialog after unlink_all");
10848          if (r->timeout > -1) {
10849             AST_SCHED_REPLACE_UNREF(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r,
10850                               registry_unref(_data, "del for REPLACE of registry ptr"), 
10851                               registry_unref(r, "object ptr dec when SCHED_REPLACE add failed"),
10852                               registry_addref(r,"add for REPLACE registry ptr"));
10853             ast_log(LOG_WARNING, "Still have a registration timeout for %s@%s (create_addr() error), %d\n", r->username, r->hostname, r->timeout);
10854          } else {
10855             r->timeout = ast_sched_add(sched, global_reg_timeout * 1000, sip_reg_timeout, registry_addref(r, "add for REPLACE registry ptr"));
10856             ast_log(LOG_WARNING, "Probably a DNS error for registration to %s@%s, trying REGISTER again (after %d seconds)\n", r->username, r->hostname, global_reg_timeout);
10857          }
10858          r->regattempts++;
10859          return 0;
10860       }
10861 
10862       /* Copy back Call-ID in case create_addr changed it */
10863       ast_string_field_set(r, callid, p->callid);
10864       if (!r->dnsmgr && r->portno) {
10865          p->sa.sin_port = htons(r->portno);
10866          p->recv.sin_port = htons(r->portno);
10867       } else { /* Set registry port to the port set from the peer definition/srv or default */
10868          r->portno = ntohs(p->sa.sin_port);
10869       }
10870       ast_set_flag(&p->flags[0], SIP_OUTGOING); /* Registration is outgoing call */
10871       r->call = dialog_ref(p, "copying dialog into registry r->call");     /* Save pointer to SIP dialog */
10872       p->registry = registry_addref(r, "transmit_register: addref to p->registry in transmit_register"); /* Add pointer to registry in packet */
10873       if (!ast_strlen_zero(r->secret)) /* Secret (password) */
10874          ast_string_field_set(p, peersecret, r->secret);
10875       if (!ast_strlen_zero(r->md5secret))
10876          ast_string_field_set(p, peermd5secret, r->md5secret);
10877       /* User name in this realm  
10878       - if authuser is set, use that, otherwise use username */
10879       if (!ast_strlen_zero(r->authuser)) {   
10880          ast_string_field_set(p, peername, r->authuser);
10881          ast_string_field_set(p, authname, r->authuser);
10882       } else if (!ast_strlen_zero(r->username)) {
10883          ast_string_field_set(p, peername, r->username);
10884          ast_string_field_set(p, authname, r->username);
10885          ast_string_field_set(p, fromuser, r->username);
10886       }
10887       if (!ast_strlen_zero(r->username))
10888          ast_string_field_set(p, username, r->username);
10889       /* Save extension in packet */
10890       if (!ast_strlen_zero(r->callback))
10891          ast_string_field_set(p, exten, r->callback);
10892 
10893       /* Set transport and port so the correct contact is built */
10894       set_socket_transport(&p->socket, r->transport);
10895       if (r->transport == SIP_TRANSPORT_TLS || r->transport == SIP_TRANSPORT_TCP) {
10896          p->socket.port = sip_tcp_desc.local_address.sin_port;
10897       }
10898 
10899       /*
10900         check which address we should use in our contact header 
10901         based on whether the remote host is on the external or
10902         internal network so we can register through nat
10903        */
10904       ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip, p);
10905       build_contact(p);
10906    }
10907 
10908    /* set up a timeout */
10909    if (auth == NULL)  {
10910       if (r->timeout > -1)
10911          ast_log(LOG_WARNING, "Still have a registration timeout, #%d - deleting it\n", r->timeout);
10912       AST_SCHED_REPLACE_UNREF(r->timeout, sched, global_reg_timeout * 1000, sip_reg_timeout, r,
10913                         registry_unref(_data,"reg ptr unrefed from del in SCHED_REPLACE"),
10914                         registry_unref(r,"reg ptr unrefed from add failure in SCHED_REPLACE"),
10915                         registry_addref(r,"reg ptr reffed from add in SCHED_REPLACE"));
10916       ast_debug(1, "Scheduled a registration timeout for %s id  #%d \n", r->hostname, r->timeout);
10917    }
10918 
10919    if ((fromdomain = strchr(r->username, '@'))) {
10920       /* the domain name is just behind '@' */
10921       fromdomain++ ;
10922       /* We have a domain in the username for registration */
10923       snprintf(from, sizeof(from), "<sip:%s>;tag=%s", r->username, p->tag);
10924       if (!ast_strlen_zero(p->theirtag))
10925          snprintf(to, sizeof(to), "<sip:%s>;tag=%s", r->username, p->theirtag);
10926       else
10927          snprintf(to, sizeof(to), "<sip:%s>", r->username);
10928 
10929       /* If the registration username contains '@', then the domain should be used as
10930          the equivalent of "fromdomain" for the registration */
10931       if (ast_strlen_zero(p->fromdomain)) {
10932          ast_string_field_set(p, fromdomain, fromdomain);
10933       }
10934    } else {
10935       snprintf(from, sizeof(from), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->tag);
10936       if (!ast_strlen_zero(p->theirtag))
10937          snprintf(to, sizeof(to), "<sip:%s@%s>;tag=%s", r->username, p->tohost, p->theirtag);
10938       else
10939          snprintf(to, sizeof(to), "<sip:%s@%s>", r->username, p->tohost);
10940    }
10941    
10942    /* Fromdomain is what we are registering to, regardless of actual
10943       host name from SRV */
10944    if (!ast_strlen_zero(p->fromdomain)) {
10945       if (r->portno && r->portno != STANDARD_SIP_PORT)
10946          snprintf(addr, sizeof(addr), "sip:%s:%d", p->fromdomain, r->portno);
10947       else
10948          snprintf(addr, sizeof(addr), "sip:%s", p->fromdomain);
10949    } else {
10950       if (r->portno && r->portno != STANDARD_SIP_PORT)
10951          snprintf(addr, sizeof(addr), "sip:%s:%d", r->hostname, r->portno);
10952       else
10953          snprintf(addr, sizeof(addr), "sip:%s", r->hostname);
10954    }
10955    ast_string_field_set(p, uri, addr);
10956 
10957    p->branch ^= ast_random();
10958 
10959    init_req(&req, sipmethod, addr);
10960 
10961    /* Add to CSEQ */
10962    snprintf(tmp, sizeof(tmp), "%u %s", ++r->ocseq, sip_methods[sipmethod].text);
10963    p->ocseq = r->ocseq;
10964 
10965    build_via(p);
10966    add_header(&req, "Via", p->via);
10967    add_header(&req, "Max-Forwards", DEFAULT_MAX_FORWARDS);
10968    add_header(&req, "From", from);
10969    add_header(&req, "To", to);
10970    add_header(&req, "Call-ID", p->callid);
10971    add_header(&req, "CSeq", tmp);
10972    if (!ast_strlen_zero(global_useragent))
10973       add_header(&req, "User-Agent", global_useragent);
10974 
10975    
10976    if (auth)   /* Add auth header */
10977       add_header(&req, authheader, auth);
10978    else if (!ast_strlen_zero(r->nonce)) {
10979       char digest[1024];
10980 
10981       /* We have auth data to reuse, build a digest header.
10982        * Note, this is not always useful because some parties do not
10983        * like nonces to be reused (for good reasons!) so they will
10984        * challenge us anyways.
10985        */
10986       if (sipdebug)
10987          ast_debug(1, "   >>> Re-using Auth data for %s@%s\n", r->username, r->hostname);
10988       ast_string_field_set(p, realm, r->realm);
10989       ast_string_field_set(p, nonce, r->nonce);
10990       ast_string_field_set(p, domain, r->domain);
10991       ast_string_field_set(p, opaque, r->opaque);
10992       ast_string_field_set(p, qop, r->qop);
10993       p->noncecount = ++r->noncecount;
10994 
10995       memset(digest, 0, sizeof(digest));
10996       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest)))
10997          add_header(&req, "Authorization", digest);
10998       else
10999          ast_log(LOG_NOTICE, "No authorization available for authentication of registration to %s@%s\n", r->username, r->hostname);
11000    
11001    }
11002 
11003    snprintf(tmp, sizeof(tmp), "%d", r->expiry);
11004    add_header(&req, "Expires", tmp);
11005    add_header(&req, "Contact", p->our_contact);
11006    add_header_contentLength(&req, 0);
11007 
11008    initialize_initreq(p, &req);
11009    if (sip_debug_test_pvt(p)) {
11010       ast_verbose("REGISTER %d headers, %d lines\n", p->initreq.headers, p->initreq.lines);
11011    }
11012    r->regstate = auth ? REG_STATE_AUTHSENT : REG_STATE_REGSENT;
11013    r->regattempts++; /* Another attempt */
11014    ast_debug(4, "REGISTER attempt %d to %s@%s\n", r->regattempts, r->username, r->hostname);
11015    res = send_request(p, &req, XMIT_CRITICAL, p->ocseq);
11016    dialog_unref(p, "p is finished here at the end of transmit_register");
11017    return res;
11018 }

static int transmit_reinvite_with_sdp ( struct sip_pvt p,
int  t38version,
int  oldsdp 
) [static]

Transmit reinvite with SDP.

Note:
A re-invite is basically a new INVITE with the same CALL-ID and TAG as the INVITE that opened the SIP dialogue We reinvite so that the audio stream (RTP) go directly between the SIP UAs. SIP Signalling stays with * in the path.
If t38version is TRUE, we send T38 SDP for re-invite from audio/video to T38 UDPTL transmission on the channel

If oldsdp is TRUE then the SDP version number is not incremented. This is needed for Session-Timers so we can send a re-invite to refresh the SIP session without modifying the media session.

Definition at line 9865 of file chan_sip.c.

References add_header(), add_sdp(), ALLOWED_METHODS, append_history, ast_set_flag, ast_test_flag, sip_pvt::do_history, FALSE, sip_pvt::flags, initialize_initreq(), sip_pvt::lastinvite, sip_pvt::ocseq, sip_pvt::offered_media, reqprep(), send_request(), SIP_INVITE, SIP_OUTGOING, SIP_REINVITE_UPDATE, SIP_UPDATE, SUPPORTED_EXTENSIONS, TRUE, and XMIT_CRITICAL.

Referenced by check_pendings(), handle_response_invite(), interpret_t38_parameters(), proc_session_timer(), sip_sendhtml(), sip_set_rtp_peer(), and sip_set_udptl_peer().

09866 {
09867    struct sip_request req;
09868    
09869    reqprep(&req, p, ast_test_flag(&p->flags[0], SIP_REINVITE_UPDATE) ?  SIP_UPDATE : SIP_INVITE, 0, 1);
09870 
09871    add_header(&req, "Allow", ALLOWED_METHODS);
09872    add_header(&req, "Supported", SUPPORTED_EXTENSIONS);
09873    if (sipdebug) {
09874       if (oldsdp == TRUE)
09875          add_header(&req, "X-asterisk-Info", "SIP re-invite (Session-Timers)");
09876       else
09877          add_header(&req, "X-asterisk-Info", "SIP re-invite (External RTP bridge)");
09878    }
09879 
09880    if (p->do_history)
09881       append_history(p, "ReInv", "Re-invite sent");
09882    memset(p->offered_media, 0, sizeof(p->offered_media));
09883 
09884    if (t38version)
09885       add_sdp(&req, p, oldsdp, FALSE, TRUE);
09886    else
09887       add_sdp(&req, p, oldsdp, TRUE, FALSE);
09888 
09889    /* Use this as the basis */
09890    initialize_initreq(p, &req);
09891    p->lastinvite = p->ocseq;
09892    ast_set_flag(&p->flags[0], SIP_OUTGOING);       /* Change direction of this dialog */
09893 
09894    return send_request(p, &req, XMIT_CRITICAL, p->ocseq);
09895 }

static int transmit_request ( struct sip_pvt p,
int  sipmethod,
int  inc,
enum xmittype  reliable,
int  newbranch 
) [static]

Transmit generic SIP request returns XMIT_ERROR if transmit failed with a critical error (don't retry).

Definition at line 11137 of file chan_sip.c.

References add_header(), add_header_contentLength(), sip_pvt::answered_elsewhere, INV_CONFIRMED, sip_pvt::invitestate, sip_pvt::ocseq, reqprep(), send_request(), SIP_ACK, and SIP_CANCEL.

Referenced by check_pendings(), handle_response(), handle_response_invite(), and sip_hangup().

11138 {
11139    struct sip_request resp;
11140    
11141    if (sipmethod == SIP_ACK)
11142       p->invitestate = INV_CONFIRMED;
11143 
11144    reqprep(&resp, p, sipmethod, seqno, newbranch);
11145    if (sipmethod == SIP_CANCEL && p->answered_elsewhere) 
11146       add_header(&resp, "Reason", "SIP;cause=200;text=\"Call completed elsewhere\"");
11147 
11148    add_header_contentLength(&resp, 0);
11149    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);
11150 }

static int transmit_request_with_auth ( struct sip_pvt p,
int  sipmethod,
int  seqno,
enum xmittype  reliable,
int  newbranch 
) [static]

Transmit SIP request, auth added.

Definition at line 11168 of file chan_sip.c.

References add_header(), add_header_contentLength(), ast_cause2str(), ast_log(), ast_strlen_zero(), auth_headers(), sip_invite_param::auth_type, buf, build_reply_digest(), sip_pvt::callid, dummy(), sip_pvt::hangupcause, LOG_WARNING, sip_pvt::ocseq, sip_pvt::options, PROXY_AUTH, sip_pvt::realm, reqprep(), send_request(), and SIP_BYE.

Referenced by __sip_autodestruct(), check_pendings(), and sip_hangup().

11169 {
11170    struct sip_request resp;
11171    
11172    reqprep(&resp, p, sipmethod, seqno, newbranch);
11173    if (!ast_strlen_zero(p->realm)) {
11174       char digest[1024];
11175 
11176       memset(digest, 0, sizeof(digest));
11177       if(!build_reply_digest(p, sipmethod, digest, sizeof(digest))) {
11178          char *dummy, *response;
11179          enum sip_auth_type code = p->options ? p->options->auth_type : PROXY_AUTH; /* XXX force 407 if unknown */
11180          auth_headers(code, &dummy, &response);
11181          add_header(&resp, response, digest);
11182       } else
11183          ast_log(LOG_WARNING, "No authentication available for call %s\n", p->callid);
11184    }
11185    /* If we are hanging up and know a cause for that, send it in clear text to make
11186       debugging easier. */
11187    if (sipmethod == SIP_BYE)  {
11188       char buf[10];
11189 
11190       add_header(&resp, "X-Asterisk-HangupCause", ast_cause2str(p->hangupcause));
11191       snprintf(buf, sizeof(buf), "%d", p->hangupcause);
11192       add_header(&resp, "X-Asterisk-HangupCauseCode", buf);
11193    }
11194 
11195    add_header_contentLength(&resp, 0);
11196    return send_request(p, &resp, reliable, seqno ? seqno : p->ocseq);   
11197 }

static int transmit_response ( struct sip_pvt p,
const char *  msg,
const struct sip_request req 
) [static]

Transmit response, no retransmits.

Definition at line 9020 of file chan_sip.c.

References __transmit_response(), and XMIT_UNRELIABLE.

09021 {
09022    return __transmit_response(p, msg, req, XMIT_UNRELIABLE);
09023 }

static int transmit_response_reliable ( struct sip_pvt p,
const char *  msg,
const struct sip_request req 
) [static]

Transmit response, Make sure you get an ACK This is only used for responses to INVITEs, where we need to make sure we get an ACK.

Definition at line 9056 of file chan_sip.c.

References __transmit_response(), sip_request::ignore, XMIT_CRITICAL, and XMIT_UNRELIABLE.

Referenced by handle_incoming(), handle_invite_replaces(), handle_request_bye(), handle_request_cancel(), handle_request_invite(), handle_request_subscribe(), interpret_t38_parameters(), sip_hangup(), sip_indicate(), sip_sipredirect(), and sip_t38_abort().

09057 {
09058    return __transmit_response(p, msg, req, req->ignore ? XMIT_UNRELIABLE : XMIT_CRITICAL);
09059 }

static int transmit_response_using_temp ( ast_string_field  callid,
struct sockaddr_in *  sin,
int  useglobal_nat,
const int  intended_method,
const struct sip_request req,
const char *  msg 
) [static]

Transmit response, no retransmits, using a temporary pvt structure.

Definition at line 8968 of file chan_sip.c.

References __transmit_response(), ast_copy_flags, ast_log(), ast_random(), ast_sip_ouraddrfor(), ast_string_field_init, ast_string_field_set, ast_test_flag, ast_threadstorage_get(), build_via(), copy_socket_data(), do_setnat(), sip_pvt::fromdomain, global_flags, INITIAL_CSEQ, LOG_ERROR, make_our_tag(), SIP_NAT, SIP_NAT_ROUTE, sip_request::socket, ts_temp_pvt, and XMIT_UNRELIABLE.

Referenced by find_call().

08969 {
08970    struct sip_pvt *p = NULL;
08971 
08972    if (!(p = ast_threadstorage_get(&ts_temp_pvt, sizeof(*p)))) {
08973       ast_log(LOG_ERROR, "Failed to get temporary pvt\n");
08974       return -1;
08975    }
08976 
08977    /* XXX the structure may be dirty from previous usage.
08978     * Here we should state clearly how we should reinitialize it
08979     * before using it.
08980     * E.g. certainly the threadstorage should be left alone,
08981     * but other thihngs such as flags etc. maybe need cleanup ?
08982     */
08983     
08984    /* Initialize the bare minimum */
08985    p->method = intended_method;
08986 
08987    if (!sin)
08988       p->ourip = internip;
08989    else {
08990       p->sa = *sin;
08991       ast_sip_ouraddrfor(&p->sa.sin_addr, &p->ourip, p);
08992    }
08993 
08994    p->branch = ast_random();
08995    make_our_tag(p->tag, sizeof(p->tag));
08996    p->ocseq = INITIAL_CSEQ;
08997 
08998    if (useglobal_nat && sin) {
08999       ast_copy_flags(&p->flags[0], &global_flags[0], SIP_NAT);
09000       p->recv = *sin;
09001       do_setnat(p, ast_test_flag(&p->flags[0], SIP_NAT) & SIP_NAT_ROUTE);
09002    }
09003 
09004    ast_string_field_set(p, fromdomain, default_fromdomain);
09005    build_via(p);
09006    ast_string_field_set(p, callid, callid);
09007 
09008    copy_socket_data(&p->socket, &req->socket);
09009 
09010    /* Use this temporary pvt structure to send the message */
09011    __transmit_response(p, msg, req, XMIT_UNRELIABLE);
09012 
09013    /* Free the string fields, but not the pool space */
09014    ast_string_field_init(p, 0);
09015 
09016    return 0;
09017 }

static int transmit_response_with_allow ( struct sip_pvt p,
const char *  msg,
const struct sip_request req,
enum xmittype  reliable 
) [static]

Append Accept header, content length before transmitting response.

Definition at line 9084 of file chan_sip.c.

References add_header(), add_header_contentLength(), respprep(), and send_response().

Referenced by handle_incoming(), and handle_request_options().

09085 {
09086    struct sip_request resp;
09087    respprep(&resp, p, msg, req);
09088    add_header(&resp, "Accept", "application/sdp");
09089    add_header_contentLength(&resp, 0);
09090    return send_response(p, &resp, reliable, 0);
09091 }

static int transmit_response_with_auth ( struct sip_pvt p,
const char *  msg,
const struct sip_request req,
const char *  rand,
enum xmittype  reliable,
const char *  header,
int  stale 
) [static]

Respond with authorization request.

Definition at line 9094 of file chan_sip.c.

References add_header(), add_header_contentLength(), append_history, ast_log(), get_header(), LOG_WARNING, sip_pvt::noncecount, respprep(), send_response(), and sip_pvt::username.

Referenced by check_auth(), and transmit_fake_auth_response().

09095 {
09096    struct sip_request resp;
09097    char tmp[512];
09098    int seqno = 0;
09099 
09100    if (reliable && (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1)) {
09101       ast_log(LOG_WARNING, "Unable to determine sequence number from '%s'\n", get_header(req, "CSeq"));
09102       return -1;
09103    }
09104    /* Stale means that they sent us correct authentication, but 
09105       based it on an old challenge (nonce) */
09106    snprintf(tmp, sizeof(tmp), "Digest algorithm=MD5, realm=\"%s\", nonce=\"%s\"%s", global_realm, randdata, stale ? ", stale=true" : "");
09107    respprep(&resp, p, msg, req);
09108    add_header(&resp, header, tmp);
09109    add_header_contentLength(&resp, 0);
09110    append_history(p, "AuthChal", "Auth challenge sent for %s - nc %d", p->username, p->noncecount);
09111    return send_response(p, &resp, reliable, seqno);
09112 }

static int transmit_response_with_date ( struct sip_pvt p,
const char *  msg,
const struct sip_request req 
) [static]

Append date and content length before transmitting response.

Definition at line 9074 of file chan_sip.c.

References add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.

Referenced by register_verify().

09075 {
09076    struct sip_request resp;
09077    respprep(&resp, p, msg, req);
09078    append_date(&resp);
09079    add_header_contentLength(&resp, 0);
09080    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
09081 }

static int transmit_response_with_minse ( struct sip_pvt p,
const char *  msg,
const struct sip_request req,
int  minse_int 
) [static]

Transmit 422 response with Min-SE header (Session-Timers).

Definition at line 9037 of file chan_sip.c.

References add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.

Referenced by handle_request_invite().

09038 {
09039    struct sip_request resp;
09040    char minse_str[20];
09041 
09042    respprep(&resp, p, msg, req);
09043    append_date(&resp);
09044 
09045    snprintf(minse_str, sizeof(minse_str), "%d", minse_int);
09046    add_header(&resp, "Min-SE", minse_str);
09047 
09048    add_header_contentLength(&resp, 0);
09049    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
09050 }

static int transmit_response_with_sdp ( struct sip_pvt p,
const char *  msg,
const struct sip_request req,
enum xmittype  reliable,
int  oldsdp 
) [static]

Used for 200 OK and 183 early media.

Returns:
Will return XMIT_ERROR for network errors.

Definition at line 9782 of file chan_sip.c.

References add_sdp(), ast_debug, ast_log(), ast_rtp_codec_setpref(), ast_test_flag, sip_pvt::autoframing, sip_pvt::callid, FALSE, sip_pvt::flags, get_header(), LOG_ERROR, LOG_WARNING, sip_pvt::pendinginvite, sip_pvt::prefs, respprep(), sip_pvt::rtp, send_response(), SIP_OUTGOING, t38properties::state, sip_pvt::t38, T38_ENABLED, TRUE, and try_suggested_sip_codec().

Referenced by handle_invite_replaces(), handle_request_invite(), send_provisional_keepalive_full(), sip_answer(), and transmit_provisional_response().

09783 {
09784    struct sip_request resp;
09785    int seqno;
09786    if (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1) {
09787       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
09788       return -1;
09789    }
09790    respprep(&resp, p, msg, req);
09791    if (p->rtp) {
09792       if (!p->autoframing && !ast_test_flag(&p->flags[0], SIP_OUTGOING)) {
09793          ast_debug(1, "Setting framing from config on incoming call\n");
09794          ast_rtp_codec_setpref(p->rtp, &p->prefs);
09795       }
09796       try_suggested_sip_codec(p);
09797       if (p->t38.state == T38_ENABLED) {
09798          add_sdp(&resp, p, oldsdp, TRUE, TRUE);
09799       } else {
09800          add_sdp(&resp, p, oldsdp, TRUE, FALSE);
09801       }
09802    } else 
09803       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no RTP session allocated. Call-ID %s\n", p->callid);
09804    if (reliable && !p->pendinginvite)
09805       p->pendinginvite = seqno;     /* Buggy clients sends ACK on RINGING too */
09806    return send_response(p, &resp, reliable, seqno);
09807 }

static int transmit_response_with_t38_sdp ( struct sip_pvt p,
char *  msg,
struct sip_request req,
int  retrans 
) [static]

Used for 200 OK and 183 early media.

Definition at line 9736 of file chan_sip.c.

References add_sdp(), ast_log(), sip_pvt::callid, get_header(), LOG_ERROR, LOG_WARNING, sip_pvt::pendinginvite, respprep(), send_response(), and sip_pvt::udptl.

Referenced by handle_request_invite(), and interpret_t38_parameters().

09737 {
09738    struct sip_request resp;
09739    int seqno;
09740    
09741    if (sscanf(get_header(req, "CSeq"), "%30d ", &seqno) != 1) {
09742       ast_log(LOG_WARNING, "Unable to get seqno from '%s'\n", get_header(req, "CSeq"));
09743       return -1;
09744    }
09745    respprep(&resp, p, msg, req);
09746    if (p->udptl) {
09747       add_sdp(&resp, p, 0, 0, 1);
09748    } else 
09749       ast_log(LOG_ERROR, "Can't add SDP to response, since we have no UDPTL session allocated. Call-ID %s\n", p->callid);
09750    if (retrans && !p->pendinginvite)
09751       p->pendinginvite = seqno;     /* Buggy clients sends ACK on RINGING too */
09752    return send_response(p, &resp, retrans, seqno);
09753 }

static int transmit_response_with_unsupported ( struct sip_pvt p,
const char *  msg,
const struct sip_request req,
const char *  unsupported 
) [static]

Transmit response, no retransmits.

Definition at line 9026 of file chan_sip.c.

References add_header(), add_header_contentLength(), append_date(), respprep(), send_response(), and XMIT_UNRELIABLE.

Referenced by handle_request_invite().

09027 {
09028    struct sip_request resp;
09029    respprep(&resp, p, msg, req);
09030    append_date(&resp);
09031    add_header(&resp, "Unsupported", unsupported);
09032    add_header_contentLength(&resp, 0);
09033    return send_response(p, &resp, XMIT_UNRELIABLE, 0);
09034 }

static int transmit_state_notify ( struct sip_pvt p,
int  state,
int  full,
int  timeout 
) [static]

Used in the SUBSCRIBE notification subsystem (RFC3265).

Definition at line 10308 of file chan_sip.c.

References add_header(), add_header_contentLength(), add_line(), ast_copy_string(), ast_device_state(), AST_DEVICE_UNAVAILABLE, AST_EXTENSION_BUSY, AST_EXTENSION_DEACTIVATED, AST_EXTENSION_INUSE, AST_EXTENSION_NOT_INUSE, AST_EXTENSION_ONHOLD, AST_EXTENSION_REMOVED, AST_EXTENSION_RINGING, AST_EXTENSION_UNAVAILABLE, ast_get_hint(), ast_log(), AST_MAX_EXTENSION, ast_str_alloca, ast_str_append(), sip_pvt::context, CPIM_PIDF_XML, DIALOG_INFO_XML, sip_pvt::dialogver, sip_pvt::expiry, sip_pvt::exten, find_subscription_type(), get_header(), get_in_brackets(), sip_pvt::initreq, LOG_WARNING, NONE, sip_pvt::ocseq, sip_pvt::pendinginvite, PIDF_XML, remove_uri_parameters(), reqprep(), send_request(), SIP_NOTIFY, ast_str::str, strsep(), sip_pvt::subscribed, ast_str::used, XMIT_RELIABLE, and XPIDF_XML.

Referenced by __sip_autodestruct(), cb_extensionstate(), and handle_request_subscribe().

10309 {
10310    struct ast_str *tmp = ast_str_alloca(4000);
10311    char from[256], to[256];
10312    char *c, *mfrom, *mto;
10313    struct sip_request req;
10314    char hint[AST_MAX_EXTENSION];
10315    char *statestring = "terminated";
10316    const struct cfsubscription_types *subscriptiontype;
10317    enum state { NOTIFY_OPEN, NOTIFY_INUSE, NOTIFY_CLOSED } local_state = NOTIFY_OPEN;
10318    char *pidfstate = "--";
10319    char *pidfnote= "Ready";
10320    
10321    memset(from, 0, sizeof(from));
10322    memset(to, 0, sizeof(to));
10323 
10324    switch (state) {
10325    case (AST_EXTENSION_RINGING | AST_EXTENSION_INUSE):
10326       statestring = (global_notifyringing) ? "early" : "confirmed";
10327       local_state = NOTIFY_INUSE;
10328       pidfstate = "busy";
10329       pidfnote = "Ringing";
10330       break;
10331    case AST_EXTENSION_RINGING:
10332       statestring = "early";
10333       local_state = NOTIFY_INUSE;
10334       pidfstate = "busy";
10335       pidfnote = "Ringing";
10336       break;
10337    case AST_EXTENSION_INUSE:
10338       statestring = "confirmed";
10339       local_state = NOTIFY_INUSE;
10340       pidfstate = "busy";
10341       pidfnote = "On the phone";
10342       break;
10343    case AST_EXTENSION_BUSY:
10344       statestring = "confirmed";
10345       local_state = NOTIFY_CLOSED;
10346       pidfstate = "busy";
10347       pidfnote = "On the phone";
10348       break;
10349    case AST_EXTENSION_UNAVAILABLE:
10350       statestring = "terminated";
10351       local_state = NOTIFY_CLOSED;
10352       pidfstate = "away";
10353       pidfnote = "Unavailable";
10354       break;
10355    case AST_EXTENSION_ONHOLD:
10356       statestring = "confirmed";
10357       local_state = NOTIFY_CLOSED;
10358       pidfstate = "busy";
10359       pidfnote = "On hold";
10360       break;
10361    case AST_EXTENSION_NOT_INUSE:
10362    default:
10363       /* Default setting */
10364       break;
10365    }
10366 
10367    subscriptiontype = find_subscription_type(p->subscribed);
10368    
10369    /* Check which device/devices we are watching  and if they are registered */
10370    if (ast_get_hint(hint, sizeof(hint), NULL, 0, NULL, p->context, p->exten)) {
10371       char *hint2 = hint, *individual_hint = NULL;
10372       int hint_count = 0, unavailable_count = 0;
10373 
10374       while ((individual_hint = strsep(&hint2, "&"))) {
10375          hint_count++;
10376 
10377          if (ast_device_state(individual_hint) == AST_DEVICE_UNAVAILABLE)
10378             unavailable_count++;
10379       }
10380 
10381       /* If none of the hinted devices are registered, we will
10382        * override notification and show no availability.
10383        */
10384       if (hint_count > 0 && hint_count == unavailable_count) {
10385          local_state = NOTIFY_CLOSED;
10386          pidfstate = "away";
10387          pidfnote = "Not online";
10388       }
10389    }
10390 
10391    ast_copy_string(from, get_header(&p->initreq, "From"), sizeof(from));
10392    c = get_in_brackets(from);
10393    if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) {
10394       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
10395       return -1;
10396    }
10397    
10398    mfrom = remove_uri_parameters(c);
10399 
10400    ast_copy_string(to, get_header(&p->initreq, "To"), sizeof(to));
10401    c = get_in_brackets(to);
10402    if (strncasecmp(c, "sip:", 4) && strncasecmp(c, "sips:", 5)) {
10403       ast_log(LOG_WARNING, "Huh?  Not a SIP header (%s)?\n", c);
10404       return -1;
10405    }
10406    mto = remove_uri_parameters(c);
10407 
10408    reqprep(&req, p, SIP_NOTIFY, 0, 1);
10409 
10410    
10411    add_header(&req, "Event", subscriptiontype->event);
10412    add_header(&req, "Content-Type", subscriptiontype->mediatype);
10413    switch(state) {
10414    case AST_EXTENSION_DEACTIVATED:
10415       if (timeout)
10416          add_header(&req, "Subscription-State", "terminated;reason=timeout");
10417       else {
10418          add_header(&req, "Subscription-State", "terminated;reason=probation");
10419          add_header(&req, "Retry-After", "60");
10420       }
10421       break;
10422    case AST_EXTENSION_REMOVED:
10423       add_header(&req, "Subscription-State", "terminated;reason=noresource");
10424       break;
10425    default:
10426       if (p->expiry)
10427          add_header(&req, "Subscription-State", "active");
10428       else  /* Expired */
10429          add_header(&req, "Subscription-State", "terminated;reason=timeout");
10430    }
10431    switch (p->subscribed) {
10432    case XPIDF_XML:
10433    case CPIM_PIDF_XML:
10434       ast_str_append(&tmp, 0,
10435          "<?xml version=\"1.0\"?>\n"
10436          "<!DOCTYPE presence PUBLIC \"-//IETF//DTD RFCxxxx XPIDF 1.0//EN\" \"xpidf.dtd\">\n"
10437          "<presence>\n");
10438       ast_str_append(&tmp, 0, "<presentity uri=\"%s;method=SUBSCRIBE\" />\n", mfrom);
10439       ast_str_append(&tmp, 0, "<atom id=\"%s\">\n", p->exten);
10440       ast_str_append(&tmp, 0, "<address uri=\"%s;user=ip\" priority=\"0.800000\">\n", mto);
10441       ast_str_append(&tmp, 0, "<status status=\"%s\" />\n", (local_state ==  NOTIFY_OPEN) ? "open" : (local_state == NOTIFY_INUSE) ? "inuse" : "closed");
10442       ast_str_append(&tmp, 0, "<msnsubstatus substatus=\"%s\" />\n", (local_state == NOTIFY_OPEN) ? "online" : (local_state == NOTIFY_INUSE) ? "onthephone" : "offline");
10443       ast_str_append(&tmp, 0, "</address>\n</atom>\n</presence>\n");
10444       break;
10445    case PIDF_XML: /* Eyebeam supports this format */
10446       ast_str_append(&tmp, 0,
10447          "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
10448          "<presence xmlns=\"urn:ietf:params:xml:ns:pidf\" \nxmlns:pp=\"urn:ietf:params:xml:ns:pidf:person\"\nxmlns:es=\"urn:ietf:params:xml:ns:pidf:rpid:status:rpid-status\"\nxmlns:ep=\"urn:ietf:params:xml:ns:pidf:rpid:rpid-person\"\nentity=\"%s\">\n", mfrom);
10449       ast_str_append(&tmp, 0, "<pp:person><status>\n");
10450       if (pidfstate[0] != '-')
10451          ast_str_append(&tmp, 0, "<ep:activities><ep:%s/></ep:activities>\n", pidfstate);
10452       ast_str_append(&tmp, 0, "</status></pp:person>\n");
10453       ast_str_append(&tmp, 0, "<note>%s</note>\n", pidfnote); /* Note */
10454       ast_str_append(&tmp, 0, "<tuple id=\"%s\">\n", p->exten); /* Tuple start */
10455       ast_str_append(&tmp, 0, "<contact priority=\"1\">%s</contact>\n", mto);
10456       if (pidfstate[0] == 'b') /* Busy? Still open ... */
10457          ast_str_append(&tmp, 0, "<status><basic>open</basic></status>\n");
10458       else
10459          ast_str_append(&tmp, 0, "<status><basic>%s</basic></status>\n", (local_state != NOTIFY_CLOSED) ? "open" : "closed");
10460       ast_str_append(&tmp, 0, "</tuple>\n</presence>\n");
10461       break;
10462    case DIALOG_INFO_XML: /* SNOM subscribes in this format */
10463       ast_str_append(&tmp, 0, "<?xml version=\"1.0\"?>\n");
10464       ast_str_append(&tmp, 0, "<dialog-info xmlns=\"urn:ietf:params:xml:ns:dialog-info\" version=\"%d\" state=\"%s\" entity=\"%s\">\n", p->dialogver++, full ? "full":"partial", mto);
10465       if ((state & AST_EXTENSION_RINGING) && global_notifyringing)
10466          ast_str_append(&tmp, 0, "<dialog id=\"%s\" direction=\"recipient\">\n", p->exten);
10467       else
10468          ast_str_append(&tmp, 0, "<dialog id=\"%s\">\n", p->exten);
10469       ast_str_append(&tmp, 0, "<state>%s</state>\n", statestring);
10470       if (state == AST_EXTENSION_ONHOLD) {
10471          ast_str_append(&tmp, 0, "<local>\n<target uri=\"%s\">\n"
10472                                          "<param pname=\"+sip.rendering\" pvalue=\"no\"/>\n"
10473                                          "</target>\n</local>\n", mto);
10474       }
10475       ast_str_append(&tmp, 0, "</dialog>\n</dialog-info>\n");
10476       break;
10477    case NONE:
10478    default:
10479       break;
10480    }
10481 
10482    add_header_contentLength(&req, tmp->used);
10483    add_line(&req, tmp->str);
10484 
10485    p->pendinginvite = p->ocseq;  /* Remember that we have a pending NOTIFY in order not to confuse the NOTIFY subsystem */
10486 
10487    return send_request(p, &req, XMIT_RELIABLE, p->ocseq);
10488 }

static void try_suggested_sip_codec ( struct sip_pvt p  )  [static]

Try setting codec suggested by the SIP_CODEC channel variable.

Definition at line 5755 of file chan_sip.c.

References ast_getformatbyname(), ast_log(), sip_pvt::capability, sip_pvt::jointcapability, LOG_NOTICE, sip_pvt::owner, and pbx_builtin_getvar_helper().

Referenced by sip_answer(), and transmit_response_with_sdp().

05756 {
05757    int fmt;
05758    const char *codec;
05759 
05760    codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC");
05761    if (!codec) 
05762       return;
05763 
05764    fmt = ast_getformatbyname(codec);
05765    if (fmt) {
05766       ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec);
05767       if (p->jointcapability & fmt) {
05768          p->jointcapability &= fmt;
05769          p->capability &= fmt;
05770       } else
05771          ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n");
05772    } else
05773       ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because of unrecognized/not configured codec (check allow/disallow in sip.conf): %s\n", codec);
05774    return;  
05775 }

static int unload_module ( void   )  [static]

PBX unload module API.

Definition at line 24777 of file chan_sip.c.

References ao2_iterator_destroy(), ao2_iterator_init(), ao2_t_iterator_next, ao2_t_ref, ast_channel_unregister(), ast_cli_unregister_multiple(), ast_context_destroy(), ast_context_find(), ast_custom_function_unregister(), ast_free, ast_free_ha(), ast_manager_unregister(), ast_mutex_lock(), ast_mutex_unlock(), AST_PTHREADT_NULL, AST_PTHREADT_STOP, ast_rtp_proto_unregister(), ast_sched_dump(), ast_softhangup(), AST_SOFTHANGUP_APPUNLOAD, ast_tcptls_server_stop(), ast_udptl_proto_unregister(), ast_unload_realtime(), ast_unregister_application(), ASTOBJ_CONTAINER_DESTROY, ASTOBJ_CONTAINER_DESTROYALL, authl, ast_tls_config::cafile, ast_tls_config::capath, ast_tls_config::certfile, checksipdomain_function, ast_tls_config::cipher, clear_realm_authentication(), clear_sip_domains(), cli_sip, default_tls_cfg, dialog_unlink_all(), dialogs, global_contact_ha, localaddr, ast_tcptls_session_args::master, monlock, sip_pvt::owner, peers, peers_by_ip, regl, sched, sched_context_destroy(), sip_header_function, sip_registry_destroy(), sip_rtp, sip_tcp_desc, sip_tech, sip_tls_desc, sip_udptl, sipchaninfo_function, sippeer_function, sip_threadinfo::stop, thread, sip_threadinfo::threadid, threadt, and TRUE.

24778 {
24779    struct sip_pvt *p;
24780    struct sip_threadinfo *th;
24781    struct ast_context *con;
24782    struct ao2_iterator i;
24783 
24784    ast_sched_dump(sched);
24785    
24786    /* First, take us out of the channel type list */
24787    ast_channel_unregister(&sip_tech);
24788 
24789    /* Unregister dial plan functions */
24790    ast_custom_function_unregister(&sipchaninfo_function);
24791    ast_custom_function_unregister(&sippeer_function);
24792    ast_custom_function_unregister(&sip_header_function);
24793    ast_custom_function_unregister(&checksipdomain_function);
24794 
24795    /* Unregister dial plan applications */
24796    ast_unregister_application(app_dtmfmode);
24797    ast_unregister_application(app_sipaddheader);
24798 
24799    /* Unregister CLI commands */
24800    ast_cli_unregister_multiple(cli_sip, sizeof(cli_sip) / sizeof(struct ast_cli_entry));
24801 
24802    /* Disconnect from the RTP subsystem */
24803    ast_rtp_proto_unregister(&sip_rtp);
24804 
24805    /* Disconnect from UDPTL */
24806    ast_udptl_proto_unregister(&sip_udptl);
24807 
24808    /* Unregister AMI actions */
24809    ast_manager_unregister("SIPpeers");
24810    ast_manager_unregister("SIPshowpeer");
24811    ast_manager_unregister("SIPqualifypeer");
24812    ast_manager_unregister("SIPshowregistry");
24813    ast_manager_unregister("SIPnotify");
24814    
24815    /* Kill TCP/TLS server threads */
24816    if (sip_tcp_desc.master)
24817       ast_tcptls_server_stop(&sip_tcp_desc);
24818    if (sip_tls_desc.master)
24819       ast_tcptls_server_stop(&sip_tls_desc);
24820 
24821    /* Kill all existing TCP/TLS threads */
24822    i = ao2_iterator_init(threadt, 0);
24823    while ((th = ao2_t_iterator_next(&i, "iterate through tcp threads for 'sip show tcp'"))) {
24824       pthread_t thread = th->threadid;
24825       th->stop = 1;
24826       pthread_kill(thread, SIGURG);
24827       pthread_join(thread, NULL);
24828       ao2_t_ref(th, -1, "decrement ref from iterator");
24829    }
24830    ao2_iterator_destroy(&i);
24831 
24832    /* Hangup all dialogs if they have an owner */
24833    i = ao2_iterator_init(dialogs, 0);
24834    while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
24835       if (p->owner)
24836          ast_softhangup(p->owner, AST_SOFTHANGUP_APPUNLOAD);
24837       ao2_t_ref(p, -1, "toss dialog ptr from iterator_next");
24838    }
24839    ao2_iterator_destroy(&i);
24840 
24841    ast_mutex_lock(&monlock);
24842    if (monitor_thread && (monitor_thread != AST_PTHREADT_STOP) && (monitor_thread != AST_PTHREADT_NULL)) {
24843       pthread_cancel(monitor_thread);
24844       pthread_kill(monitor_thread, SIGURG);
24845       pthread_join(monitor_thread, NULL);
24846    }
24847    monitor_thread = AST_PTHREADT_STOP;
24848    ast_mutex_unlock(&monlock);
24849 
24850    /* Destroy all the dialogs and free their memory */
24851    i = ao2_iterator_init(dialogs, 0);
24852    while ((p = ao2_t_iterator_next(&i, "iterate thru dialogs"))) {
24853       dialog_unlink_all(p, TRUE, TRUE);
24854       ao2_t_ref(p, -1, "throw away iterator result"); 
24855    }
24856    ao2_iterator_destroy(&i);
24857 
24858    /* Free memory for local network address mask */
24859    ast_free_ha(localaddr);
24860 
24861    clear_realm_authentication(authl);
24862 
24863 
24864    if (default_tls_cfg.certfile)
24865       ast_free(default_tls_cfg.certfile);
24866    if (default_tls_cfg.cipher)
24867       ast_free(default_tls_cfg.cipher);
24868    if (default_tls_cfg.cafile)
24869       ast_free(default_tls_cfg.cafile);
24870    if (default_tls_cfg.capath)
24871       ast_free(default_tls_cfg.capath);
24872 
24873    ASTOBJ_CONTAINER_DESTROYALL(&regl, sip_registry_destroy);
24874    ASTOBJ_CONTAINER_DESTROY(&regl);
24875 
24876    ao2_t_ref(peers, -1, "unref the peers table");
24877    ao2_t_ref(peers_by_ip, -1, "unref the peers_by_ip table");
24878    ao2_t_ref(dialogs, -1, "unref the dialogs table");
24879    ao2_t_ref(threadt, -1, "unref the thread table");
24880 
24881    clear_sip_domains();
24882    ast_free_ha(global_contact_ha);
24883    close(sipsock);
24884    sched_context_destroy(sched);
24885    con = ast_context_find(used_context);
24886    if (con)
24887       ast_context_destroy(con, "SIP");
24888    ast_unload_realtime("sipregs");
24889    ast_unload_realtime("sippeers");
24890 
24891    return 0;
24892 }

static void* unref_peer ( struct sip_peer peer,
char *  tag 
) [static]

helper functions to unreference various types of objects. By handling them this way, we don't have to declare the destructor on each call, which removes the chance of errors.

Definition at line 2749 of file chan_sip.c.

References ao2_t_ref.

Referenced by __sip_autodestruct(), __sip_destroy(), _sip_qualify_peer(), _sip_show_peer(), _sip_show_peers(), build_peer(), check_peer_ok(), complete_sip_peer(), complete_sip_registered_peer(), complete_sip_user(), create_addr(), expire_register(), function_sippeer(), handle_request_subscribe(), handle_response_peerpoke(), parse_register_contact(), reg_source_db(), register_verify(), sip_devicestate(), sip_do_debug_peer(), sip_peer_hold(), sip_poke_all_peers(), sip_poke_noanswer(), sip_poke_peer(), sip_poke_peer_s(), sip_prune_realtime(), sip_show_inuse(), sip_show_user(), sip_show_users(), sip_unregister(), st_get_mode(), st_get_refresher(), st_get_se(), transmit_register(), and update_call_counter().

02750 {
02751    ao2_t_ref(peer, -1, tag);
02752    return NULL;
02753 }

static int update_call_counter ( struct sip_pvt fup,
int  event 
) [static]

update_call_counter: Handle call_limit for SIP devices Setting a call-limit will cause calls above the limit not to be accepted.

Remember that for a type=friend, there's one limit for the user and another for the peer, not a combined call limit. This will cause unexpected behaviour in subscriptions, since a "friend" is *two* devices in Asterisk, not one.

Thought: For realtime, we should probably update storage with inuse counter...

Returns:
0 if call is ok (no call limit, below threshold) -1 on rejection of call

Definition at line 5230 of file chan_sip.c.

References ao2_lock(), ao2_unlock(), ast_clear_flag, ast_copy_string(), ast_debug, AST_DEVICE_UNKNOWN, ast_devstate_changed(), ast_log(), ast_set_flag, ast_strlen_zero(), ast_test_flag, sip_peer::call_limit, DEC_CALL_LIMIT, DEC_CALL_RINGING, FALSE, find_peer(), FINDALLDEVICES, sip_pvt::flags, INC_CALL_LIMIT, INC_CALL_RINGING, sip_peer::inRinging, sip_peer::inUse, inuse, LOG_ERROR, sip_peer::name, name, sip_pvt::outgoing_call, sip_pvt::peername, SIP_CALL_LIMIT, SIP_INC_COUNT, SIP_INC_RINGING, SIP_PAGE2_CALL_ONHOLD, sip_peer_hold(), sip_pvt_lock, sip_pvt_unlock, TRUE, unref_peer(), and sip_pvt::username.

Referenced by __sip_destroy(), handle_request_cancel(), handle_request_invite(), handle_response_invite(), sip_call(), and sip_hangup().

05231 {
05232    char name[256];
05233    int *inuse = NULL, *call_limit = NULL, *inringing = NULL;
05234    int outgoing = fup->outgoing_call;
05235    struct sip_peer *p = NULL;
05236 
05237    ast_debug(3, "Updating call counter for %s call\n", outgoing ? "outgoing" : "incoming");
05238 
05239 
05240    /* Test if we need to check call limits, in order to avoid 
05241       realtime lookups if we do not need it */
05242    if (!ast_test_flag(&fup->flags[0], SIP_CALL_LIMIT) && !ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD))
05243       return 0;
05244 
05245    ast_copy_string(name, fup->username, sizeof(name));
05246 
05247    /* Check the list of devices */
05248    if ((p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, TRUE, FINDALLDEVICES, FALSE, 0))) { /* Try to find peer */
05249       inuse = &p->inUse;
05250       call_limit = &p->call_limit;
05251       inringing = &p->inRinging;
05252       ast_copy_string(name, fup->peername, sizeof(name));
05253    }
05254    if (!p) {
05255       ast_debug(2, "%s is not a local device, no call limit\n", name);
05256       return 0;
05257    }
05258 
05259    switch(event) {
05260    /* incoming and outgoing affects the inUse counter */
05261    case DEC_CALL_LIMIT:
05262       /* Decrement inuse count if applicable */
05263       if (inuse) {
05264          sip_pvt_lock(fup);
05265          ao2_lock(p);
05266          if (*inuse > 0) {
05267             if (ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) {
05268                (*inuse)--;
05269                ast_clear_flag(&fup->flags[0], SIP_INC_COUNT);
05270             }
05271          } else {
05272             *inuse = 0;
05273          }
05274          ao2_unlock(p);
05275          sip_pvt_unlock(fup);
05276       }
05277 
05278       /* Decrement ringing count if applicable */
05279       if (inringing) {
05280          sip_pvt_lock(fup);
05281          ao2_lock(p);
05282          if (*inringing > 0) {
05283             if (ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) {
05284                (*inringing)--;
05285                ast_clear_flag(&fup->flags[0], SIP_INC_RINGING);
05286             }
05287          } else {
05288             *inringing = 0;
05289          }
05290          ao2_unlock(p);
05291          sip_pvt_unlock(fup);
05292       }
05293 
05294       /* Decrement onhold count if applicable */
05295       sip_pvt_lock(fup);
05296       ao2_lock(p);
05297       if (ast_test_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD) && global_notifyhold) {
05298          ast_clear_flag(&fup->flags[1], SIP_PAGE2_CALL_ONHOLD);
05299          ao2_unlock(p);
05300          sip_pvt_unlock(fup);
05301          sip_peer_hold(fup, FALSE);
05302       } else {
05303          ao2_unlock(p);
05304          sip_pvt_unlock(fup);
05305       }
05306       if (sipdebug)
05307          ast_debug(2, "Call %s %s '%s' removed from call limit %d\n", outgoing ? "to" : "from", "peer", name, *call_limit);
05308       break;
05309 
05310    case INC_CALL_RINGING:
05311    case INC_CALL_LIMIT:
05312       /* If call limit is active and we have reached the limit, reject the call */
05313       if (*call_limit > 0 ) {
05314          if (*inuse >= *call_limit) {
05315             ast_log(LOG_ERROR, "Call %s %s '%s' rejected due to usage limit of %d\n", outgoing ? "to" : "from", "peer", name, *call_limit);
05316             unref_peer(p, "update_call_counter: unref peer p, call limit exceeded");
05317             return -1; 
05318          }
05319       }
05320       if (inringing && (event == INC_CALL_RINGING)) {
05321          sip_pvt_lock(fup);
05322          ao2_lock(p);
05323          if (!ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) {
05324             (*inringing)++;
05325             ast_set_flag(&fup->flags[0], SIP_INC_RINGING);
05326          }
05327          ao2_unlock(p);
05328          sip_pvt_unlock(fup);
05329       }
05330       if (inuse) {
05331          sip_pvt_lock(fup);
05332          ao2_lock(p);
05333          if (!ast_test_flag(&fup->flags[0], SIP_INC_COUNT)) {
05334             (*inuse)++;
05335             ast_set_flag(&fup->flags[0], SIP_INC_COUNT);
05336          }
05337          ao2_unlock(p);
05338          sip_pvt_unlock(fup);
05339       }
05340       if (sipdebug) {
05341          ast_debug(2, "Call %s %s '%s' is %d out of %d\n", outgoing ? "to" : "from", "peer", name, *inuse, *call_limit);
05342       }
05343       break;
05344 
05345    case DEC_CALL_RINGING:
05346       if (inringing) {
05347          sip_pvt_lock(fup);
05348          ao2_lock(p);
05349          if (ast_test_flag(&fup->flags[0], SIP_INC_RINGING)) {
05350             if (*inringing > 0) {
05351                (*inringing)--;
05352             }
05353             ast_clear_flag(&fup->flags[0], SIP_INC_RINGING);
05354          }
05355          ao2_unlock(p);
05356          sip_pvt_unlock(fup);
05357       }
05358       break;
05359 
05360    default:
05361       ast_log(LOG_ERROR, "update_call_counter(%s, %d) called with no event!\n", name, event);
05362    }
05363 
05364    if (p) {
05365       ast_devstate_changed(AST_DEVICE_UNKNOWN, "SIP/%s", p->name);
05366       unref_peer(p, "update_call_counter: unref_peer from call counter");
05367    } 
05368    return 0;
05369 }

static void update_peer ( struct sip_peer p,
int  expire 
) [static]

Update peer data in database (if used).

Definition at line 4310 of file chan_sip.c.

References sip_peer::addr, ast_test_flag, sip_peer::deprecated_username, sip_peer::flags, sip_peer::fullcontact, sip_peer::is_realtime, sip_peer::lastms, sip_peer::name, sip_settings::peer_rtupdate, realtime_update_peer(), sip_cfg, SIP_PAGE2_RTCACHEFRIENDS, sip_peer::useragent, and sip_peer::username.

Referenced by register_verify().

04311 {
04312    int rtcachefriends = ast_test_flag(&p->flags[1], SIP_PAGE2_RTCACHEFRIENDS);
04313    if (sip_cfg.peer_rtupdate &&
04314        (p->is_realtime || rtcachefriends)) {
04315       realtime_update_peer(p->name, &p->addr, p->username, rtcachefriends ? p->fullcontact : NULL, p->useragent, expire, p->deprecated_username, p->lastms);
04316    }
04317 }

static void update_provisional_keepalive ( struct sip_pvt pvt,
int  with_sdp 
) [static]

Definition at line 3804 of file chan_sip.c.

References ast_sched_add(), AST_SCHED_DEL_UNREF, dialog_ref(), dialog_unref(), PROVIS_KEEPALIVE_TIMEOUT, sip_pvt::provisional_keepalive_sched_id, sched, send_provisional_keepalive(), and send_provisional_keepalive_with_sdp().

Referenced by transmit_provisional_response().

03805 {
03806    AST_SCHED_DEL_UNREF(sched, pvt->provisional_keepalive_sched_id, dialog_unref(pvt, "when you delete the provisional_keepalive_sched_id, you should dec the refcount for the stored dialog ptr"));
03807 
03808    pvt->provisional_keepalive_sched_id = ast_sched_add(sched, PROVIS_KEEPALIVE_TIMEOUT,
03809       with_sdp ? send_provisional_keepalive_with_sdp : send_provisional_keepalive, dialog_ref(pvt, "Increment refcount to pass dialog pointer to sched callback"));
03810 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Session Initiation Protocol (SIP)" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, .reload = reload, } [static]

Definition at line 24898 of file chan_sip.c.

int allow_external_domains [static]

Accept calls to external SIP domains?

Definition at line 795 of file chan_sip.c.

int apeerobjs = 0 [static]

Autocreated peer objects

Definition at line 828 of file chan_sip.c.

char* app_dtmfmode = "SIPDtmfMode" [static]

Definition at line 24361 of file chan_sip.c.

char* app_sipaddheader = "SIPAddHeader" [static]

Definition at line 24363 of file chan_sip.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 24898 of file chan_sip.c.

struct sip_auth* authl = NULL [static]

Authentication list for realm authentication.

Todo:
Move the sip_auth list to AST_LIST

Definition at line 1816 of file chan_sip.c.

Referenced by build_reply_digest(), reload_config(), sip_show_settings(), and unload_module().

int autocreatepeer [static]

Auto creation of peers at registration? Default off.

Definition at line 762 of file chan_sip.c.

struct sockaddr_in bindaddr [static]

UDP: The address we bind to

Definition at line 1837 of file chan_sip.c.

unsigned int chan_idx [static]

Definition at line 561 of file chan_sip.c.

struct ast_threadstorage check_auth_buf = { .once = PTHREAD_ONCE_INIT , .key_init = __init_check_auth_buf , .custom_init = NULL , } [static]

Definition at line 11766 of file chan_sip.c.

Referenced by check_auth(), and transmit_fake_auth_response().

struct ast_custom_function checksipdomain_function [static]

Definition at line 16490 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_sip[] [static]

SIP Cli commands definition.

Definition at line 24656 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct ast_cli_entry cli_sip_do_history_deprecated = { .handler = sip_do_history_deprecated , .summary = "Enable/Disable SIP history" ,__VA_ARGS__ } [static]

Definition at line 24654 of file chan_sip.c.

int compactheaders [static]

send compact sip headers

Definition at line 787 of file chan_sip.c.

const char config[] = "sip.conf" [static]

Main configuration file

Definition at line 286 of file chan_sip.c.

struct sockaddr_in debugaddr [static]

Definition at line 1882 of file chan_sip.c.

char default_callerid[AST_MAX_EXTENSION] [static]

Definition at line 728 of file chan_sip.c.

char default_context[AST_MAX_CONTEXT] [static]

Definition at line 725 of file chan_sip.c.

int default_expiry = DEFAULT_DEFAULT_EXPIRY [static]

Definition at line 244 of file chan_sip.c.

char default_fromdomain[AST_MAX_EXTENSION] [static]

Definition at line 729 of file chan_sip.c.

struct ast_jb_conf default_jbconf [static]

Global jitterbuffer configuration - by default, jb is disabled.

Definition at line 276 of file chan_sip.c.

char default_language[MAX_LANGUAGE] [static]

Definition at line 727 of file chan_sip.c.

int default_maxcallbitrate [static]

Maximum bitrate for call

Definition at line 737 of file chan_sip.c.

char default_mohinterpret[MAX_MUSICCLASS] [static]

Global setting for moh class to use when put on hold

Definition at line 733 of file chan_sip.c.

char default_mohsuggest[MAX_MUSICCLASS] [static]

Global setting for moh class to suggest when putting a bridged channel on hold

Definition at line 734 of file chan_sip.c.

char default_notifymime[AST_MAX_EXTENSION] [static]

Definition at line 730 of file chan_sip.c.

char default_parkinglot[AST_MAX_CONTEXT] [static]

Parkinglot

Definition at line 736 of file chan_sip.c.

struct ast_codec_pref default_prefs [static]

Default codec prefs

Definition at line 738 of file chan_sip.c.

Referenced by build_device(), reload_config(), set_peer_defaults(), sip_alloc(), sip_show_settings(), and temp_peer().

int default_qualify [static]

Default Qualify= setting

Definition at line 731 of file chan_sip.c.

char default_subscribecontext[AST_MAX_CONTEXT] [static]

Definition at line 726 of file chan_sip.c.

struct ast_tls_config default_tls_cfg [static]

Default TLS connection configuration.

Definition at line 2347 of file chan_sip.c.

Referenced by reload_config(), sip_prepare_socket(), sip_show_settings(), and unload_module().

char default_vmexten[AST_MAX_EXTENSION] [static]

Definition at line 732 of file chan_sip.c.

char* descrip_dtmfmode = " SIPDtmfMode(inband|info|rfc2833): Changes the dtmfmode for a SIP call\n" [static]

Definition at line 24360 of file chan_sip.c.

char* descrip_sipaddheader [static]

Definition at line 24366 of file chan_sip.c.

struct ao2_container* dialogs

Here we implement the container for dialogs (sip_pvt), defining generic wrapper functions to ease the transition from the current implementation (a single linked list) to a different container. In addition to a reference to the container, we need functions to lock/unlock the container and individual items, and functions to add/remove references to the individual items.

Definition at line 1419 of file chan_sip.c.

Referenced by complete_sipch(), create_addr_from_peer(), dialog_needdestroy(), dialog_unlink_all(), do_monitor(), find_call(), get_sip_pvt_byid_locked(), handle_request_subscribe(), load_module(), manager_sipnotify(), sip_alloc(), sip_cli_notify(), sip_poke_peer(), sip_request_call(), sip_send_mwi_to_peer(), sip_show_channel(), sip_show_channels(), sip_show_channelstats(), sip_show_history(), sip_show_objects(), and unload_module().

struct _map_x_s dtmfstr[] [static]

mapping between dtmf flags and strings

Definition at line 14118 of file chan_sip.c.

Referenced by conf_run(), dtmfmode2str(), handle_link_data(), handle_remote_data(), send_dtmf(), and str2dtmfmode().

int dumphistory [static]

Dump history to verbose before destroying SIP dialog

Definition at line 789 of file chan_sip.c.

time_t externexpire [static]

Expiration counter for re-resolving external host name in dynamic DNS

Definition at line 1868 of file chan_sip.c.

char externhost[MAXHOSTNAMELEN] [static]

External host name

Definition at line 1867 of file chan_sip.c.

struct sockaddr_in externip [static]

our external IP address/port for SIP sessions. externip.sin_addr is only set when we know we might be behind a NAT, and this is done using a variety of (mutually exclusive) ways from the config file:

+ with "externip = host[:port]" we specify the address/port explicitly. The address is looked up only once when (re)loading the config file;

+ with "externhost = host[:port]" we do a similar thing, but the hostname is stored in externhost, and the hostname->IP mapping is refreshed every 'externrefresh' seconds;

+ with "stunaddr = host[:port]" we run queries every externrefresh seconds to the specified server, and store the result in externip.

Other variables (externhost, externexpire, externrefresh) are used to support the above functions. External IP address if we are behind NAT

Definition at line 1865 of file chan_sip.c.

int externrefresh = 10 [static]

Definition at line 1869 of file chan_sip.c.

struct _map_x_s faxecmodes[] [static]

Definition at line 14568 of file chan_sip.c.

Referenced by faxec2str().

int global_allowguest [static]

allow unauthenticated peers to connect?

Definition at line 773 of file chan_sip.c.

int global_allowsubscribe [static]

Flag for disabling ALL subscriptions, this is FALSE only if all peers are FALSE the global setting is in globals_flags[1]

Definition at line 777 of file chan_sip.c.

enum transfermodes global_allowtransfer [static]

SIP Refer restriction scheme

Definition at line 803 of file chan_sip.c.

int global_alwaysauthreject [static]

Send 401 Unauthorized for all failing requests

Definition at line 759 of file chan_sip.c.

int global_authfailureevents [static]

Whether we send authentication failure manager events or not. Default no.

Definition at line 797 of file chan_sip.c.

int global_autoframing [static]

Turn autoframing on or off.

Definition at line 802 of file chan_sip.c.

int global_callcounter [static]

Enable call counters for all devices. This is currently enabled by setting the peer call-limit to 999. When we remove the call-limit from the code, we can make it with just a boolean flag in the device structure

Definition at line 774 of file chan_sip.c.

int global_callevents [static]

Whether we send manager events or not

Definition at line 796 of file chan_sip.c.

int global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263 [static]

Codecs that we support by default:.

Definition at line 810 of file chan_sip.c.

struct ast_ha* global_contact_ha = NULL [static]

Global list of addresses dynamic peers are not allowed to use.

Definition at line 821 of file chan_sip.c.

Referenced by build_peer(), parse_register_contact(), reload_config(), and unload_module().

unsigned int global_cos_audio [static]

802.1p class of service for audio RTP packets

Definition at line 784 of file chan_sip.c.

unsigned int global_cos_sip [static]

802.1p class of service for SIP packets

Definition at line 783 of file chan_sip.c.

unsigned int global_cos_text [static]

802.1p class of service for text RTP packets

Definition at line 786 of file chan_sip.c.

unsigned int global_cos_video [static]

802.1p class of service for video RTP packets

Definition at line 785 of file chan_sip.c.

int global_directrtpsetup [static]

Enable support for Direct RTP setup (no re-invites)

Definition at line 755 of file chan_sip.c.

int global_dynamic_exclude_static = 0 [static]

Exclude static peers from contact registrations

Definition at line 817 of file chan_sip.c.

struct ast_flags global_flags[2] = {{0}} [static]

global SIP_ flags

Definition at line 832 of file chan_sip.c.

Referenced by build_peer(), build_radius_record(), get_destination(), load_module(), load_moh_classes(), local_ast_moh_start(), reload_config(), set_peer_defaults(), sip_alloc(), sip_show_settings(), and transmit_response_using_temp().

struct ast_jb_conf global_jbconf [static]

Global jitterbuffer configuration

Definition at line 284 of file chan_sip.c.

int global_match_auth_username [static]

Match auth username if available instead of From: Default off.

Definition at line 763 of file chan_sip.c.

int global_matchexterniplocally [static]

Match externip/externhost setting against localnet setting

Definition at line 805 of file chan_sip.c.

int global_max_se [static]

Highest threshold for session refresh interval

Definition at line 815 of file chan_sip.c.

int global_min_se [static]

Lowest threshold for session refresh interval

Definition at line 814 of file chan_sip.c.

int global_notifyhold [static]

Send notifications on hold

Definition at line 758 of file chan_sip.c.

int global_notifyringing [static]

Send notifications on ringing

Definition at line 757 of file chan_sip.c.

struct sip_proxy global_outboundproxy [static]

Outbound proxy

Definition at line 804 of file chan_sip.c.

Referenced by obproxy_get(), ref_proxy(), and sip_show_settings().

int global_prematuremediafilter [static]

Enable/disable premature frames in a call (causing 183 early media)

Definition at line 765 of file chan_sip.c.

int global_qualifyfreq [static]

Qualify frequency

Definition at line 806 of file chan_sip.c.

char global_realm[MAXHOSTNAMELEN] [static]

Default realm

Definition at line 790 of file chan_sip.c.

int global_reg_timeout [static]

Definition at line 770 of file chan_sip.c.

int global_regattempts_max [static]

Registration attempts before giving up

Definition at line 771 of file chan_sip.c.

char global_regcontext[AST_MAX_CONTEXT] [static]

Context for auto-extensions

Definition at line 791 of file chan_sip.c.

int global_regextenonqualify [static]

Whether to add/remove regexten when qualifying peers

Definition at line 801 of file chan_sip.c.

int global_relaxdtmf [static]

Relax DTMF

Definition at line 766 of file chan_sip.c.

int global_relaxdtmf [static]

Relax DTMF

Definition at line 764 of file chan_sip.c.

int global_rtautoclear [static]

Realtime ??

Definition at line 756 of file chan_sip.c.

int global_rtpholdtimeout [static]

Time out call if no RTP during hold

Definition at line 768 of file chan_sip.c.

int global_rtpkeepalive [static]

Send RTP keepalives

Definition at line 769 of file chan_sip.c.

int global_rtptimeout [static]

Time out call if no RTP

Definition at line 767 of file chan_sip.c.

char global_sdpowner[AST_MAX_EXTENSION] [static]

SDP owner name for the SIP channel

Definition at line 794 of file chan_sip.c.

char global_sdpsession[AST_MAX_EXTENSION] [static]

SDP session name for the SIP channel

Definition at line 793 of file chan_sip.c.

int global_shrinkcallerid [static]

enable or disable shrinking of caller id

Definition at line 772 of file chan_sip.c.

int global_srvlookup [static]

SRV Lookup on or off. Default is on

Definition at line 760 of file chan_sip.c.

enum st_mode global_st_mode [static]

Mode of operation for Session-Timers

Definition at line 812 of file chan_sip.c.

enum st_refresher global_st_refresher [static]

Session-Timer refresher

Definition at line 813 of file chan_sip.c.

int global_t1 [static]

T1 time

Definition at line 798 of file chan_sip.c.

int global_t1min [static]

T1 roundtrip time minimum

Definition at line 799 of file chan_sip.c.

int global_t38_maxdatagram [static]

global T.38 FaxMaxDatagram override

Definition at line 833 of file chan_sip.c.

int global_timer_b [static]

Timer B - RFC 3261 Section 17.1.1.2

Definition at line 800 of file chan_sip.c.

unsigned int global_tos_audio [static]

IP type of service for audio RTP packets

Definition at line 780 of file chan_sip.c.

unsigned int global_tos_sip [static]

IP type of service for SIP packets

Definition at line 779 of file chan_sip.c.

unsigned int global_tos_text [static]

IP type of service for text RTP packets

Definition at line 782 of file chan_sip.c.

unsigned int global_tos_video [static]

IP type of service for video RTP packets

Definition at line 781 of file chan_sip.c.

char global_useragent[AST_MAX_EXTENSION] [static]

Useragent for the SIP channel

Definition at line 792 of file chan_sip.c.

int hash_dialog_size = 563 [static]

Definition at line 1673 of file chan_sip.c.

int hash_peer_size = 563 [static]

Size of peer hash table, prime number preferred!

Definition at line 1672 of file chan_sip.c.

int hash_user_size = 563 [static]

Definition at line 1674 of file chan_sip.c.

struct _map_x_s insecurestr[] [static]

Definition at line 14139 of file chan_sip.c.

Referenced by insecure2str().

struct sockaddr_in internip [static]

our (internal) default address/port to put in SIP/SDP messages internip is initialized picking a suitable address from one of the interfaces, and the same port number we bind to. It is used as the default address/port in SIP messages, and as the default address (but not port) in SDP messages.

Definition at line 1845 of file chan_sip.c.

struct invstate2stringtable invitestate2string[] [static]

Readable descriptions of device states.

Note:
Should be aligned to above table as index

Referenced by show_chanstats_cb().

struct io_context* io [static]

The IO context

Definition at line 854 of file chan_sip.c.

struct ast_ha* localaddr [static]

List of local networks We store "localnet" addresses from the config file into an access list, marked as 'DENY', so the call to ast_apply_ha() will return AST_SENSE_DENY for 'local' addresses, and AST_SENSE_ALLOW for 'non local' (i.e. presumably public) addresses.

List of local networks, on the same side of NAT as this Asterisk

Definition at line 1878 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), sip_show_settings(), and unload_module().

char mandescr_show_peer[] [static]

Initial value:

 
"Description: Show one SIP peer with details on current status.\n"
"Variables: \n"
"  Peer: <name>           The peer name you want to check.\n"
"  ActionID: <id>   Optional action ID for this AMI transaction.\n"

Definition at line 14451 of file chan_sip.c.

Referenced by load_module().

char mandescr_show_peers[] [static]

Definition at line 13828 of file chan_sip.c.

Referenced by load_module().

char mandescr_show_registry[] [static]

Manager Action SIPShowRegistry description.

Definition at line 13782 of file chan_sip.c.

Referenced by load_module().

char mandescr_sipnotify[] [static]

Definition at line 10644 of file chan_sip.c.

Referenced by load_module().

int max_expiry = DEFAULT_MAX_EXPIRY [static]

Maximum accepted registration time

Definition at line 243 of file chan_sip.c.

int min_expiry = DEFAULT_MIN_EXPIRY [static]

Minimum accepted registration time

Definition at line 242 of file chan_sip.c.

pthread_t monitor_thread = AST_PTHREADT_NULL [static]

This is the thread for the monitor which checks for input on the channels which are not currently in use.

Definition at line 848 of file chan_sip.c.

ast_mutex_t monlock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static]

Protect the monitoring thread, so only one process can kill or start it, and not when it's doing something critical.

Definition at line 842 of file chan_sip.c.

struct _map_x_s natmodes[] [static]

Definition at line 13563 of file chan_sip.c.

Referenced by nat2str().

ast_mutex_t netlock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static]

Definition at line 838 of file chan_sip.c.

const char notify_config[] = "sip_notify.conf" [static]

Configuration file for sending Notify with CLI commands to reconfigure or reboot phones

Definition at line 287 of file chan_sip.c.

struct ast_config* notify_types = NULL [static]

The list of manual NOTIFY types we know how to send

Definition at line 1884 of file chan_sip.c.

Referenced by complete_sipnotify(), and sip_cli_notify().

int ourport_tcp [static]

The port used for TCP connections

Definition at line 1880 of file chan_sip.c.

int ourport_tls [static]

The port used for TCP/TLS connections

Definition at line 1881 of file chan_sip.c.

int pedanticsipchecking [static]

Extra checking ? Default off

Definition at line 761 of file chan_sip.c.

struct ao2_container* peers

The peer list: Users, Peers and Friends.

Definition at line 1681 of file chan_sip.c.

struct ao2_container* peers_by_ip

Definition at line 1682 of file chan_sip.c.

Referenced by expire_register(), find_peer(), load_module(), parse_register_contact(), register_verify(), sip_prune_realtime(), and unload_module().

int recordhistory [static]

Record SIP history. Off by default

Definition at line 788 of file chan_sip.c.

struct _map_x_s referstatusstrings[] [static]

Definition at line 1163 of file chan_sip.c.

Referenced by referstatus2str().

struct ast_register_list regl [static]

The register list: Other SIP proxies we register with and place calls to.

Referenced by load_module(), manager_show_registry(), reload_config(), sip_register(), sip_send_all_registers(), sip_show_objects(), sip_show_registry(), and unload_module().

int regobjs = 0 [static]

Registry objects

Definition at line 829 of file chan_sip.c.

struct _map_x_s regstatestrings[] [static]

Definition at line 10653 of file chan_sip.c.

Referenced by regstate2str().

int rpeerobjs = 0 [static]

Realtime peers

Definition at line 827 of file chan_sip.c.

struct sched_context* sched [static]

The scheduling context

Definition at line 853 of file chan_sip.c.

struct sip_settings sip_cfg [static]

Definition at line 747 of file chan_sip.c.

Referenced by build_peer(), destroy_association(), handle_response_peerpoke(), realtime_update_peer(), sip_poke_noanswer(), sip_show_settings(), and update_peer().

struct ast_custom_function sip_header_function [static]

Definition at line 16466 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct cfsip_methods sip_methods[] [static]

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

Referenced by __sip_autodestruct(), __sip_destroy(), __sip_pretend_ack(), __sip_semi_ack(), build_reply_digest(), check_auth(), dialog_needdestroy(), do_proxy_auth(), find_call(), find_call_cb(), find_sip_method(), get_destination(), handle_incoming(), handle_request_bye(), handle_request_invite(), handle_request_register(), handle_request_subscribe(), handle_response(), init_req(), initialize_initreq(), initreqprep(), method_match(), reqprep(), retrans_pkt(), send_request(), send_response(), sip_alloc(), sip_scheddestroy(), and transmit_register().

struct cfsip_options sip_options[] [static]

List of well-known SIP options. If we get this in a require, we should check the list and answer accordingly.

Referenced by _sip_show_peer(), parse_sip_options(), and sip_show_channel().

ast_mutex_t sip_reload_lock = ((ast_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ) [static]

Definition at line 844 of file chan_sip.c.

Referenced by do_monitor(), and sip_reload().

int sip_reloading = FALSE [static]

Flag for avoiding multiple reloads at the same time

Definition at line 850 of file chan_sip.c.

enum channelreloadreason sip_reloadreason [static]

Reason for last reload/load of configuration

Definition at line 851 of file chan_sip.c.

struct ast_rtp_protocol sip_rtp [static]

Interface structure with callbacks used to connect to RTP module.

Definition at line 2402 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct ast_tcptls_session_args sip_tcp_desc [static]

The TCP server definition.

Definition at line 2350 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), reload_config(), sip_show_settings(), transmit_register(), and unload_module().

struct ast_channel_tech sip_tech [static]

Definition of this channel for PBX channel registration.

Definition at line 2306 of file chan_sip.c.

Referenced by load_module(), sip_new(), and unload_module().

struct ast_channel_tech sip_tech_info [static]

This version of the sip channel tech has no send_digit_begin callback so that the core knows that the channel does not want DTMF BEGIN frames. The struct is initialized just before registering the channel driver, and is for use with channels using SIP INFO DTMF.

Definition at line 2340 of file chan_sip.c.

Referenced by load_module(), and sip_new().

struct ast_tls_config sip_tls_cfg [static]

Working TLS connection configuration.

Definition at line 2344 of file chan_sip.c.

struct ast_tcptls_session_args sip_tls_desc [static]

The TCP/TLS server definition.

Definition at line 2361 of file chan_sip.c.

Referenced by ast_sip_ouraddrfor(), reload_config(), sip_show_settings(), and unload_module().

struct ast_udptl_protocol sip_udptl [static]

Initial value:

 {
   type: "SIP",
   get_udptl_info: sip_get_udptl_peer,
   set_udptl_peer: sip_set_udptl_peer,
}
Interface structure with callbacks used to connect to UDPTL module.

Definition at line 2873 of file chan_sip.c.

Referenced by load_module(), and unload_module().

struct ast_custom_function sipchaninfo_function [static]

Structure to declare a dialplan function: SIPCHANINFO.

Definition at line 16681 of file chan_sip.c.

Referenced by load_module(), and unload_module().

enum sip_debug_e sipdebug [static]

Definition at line 1117 of file chan_sip.c.

int sipdebug_text [static]

extra debugging for 'text' related events. At the moment this is set together with sip_debug_console.

Note:
It should either go away or be implemented properly.

Definition at line 1123 of file chan_sip.c.

struct ast_custom_function sippeer_function

Structure to declare a dialplan function: SIPPEER.

Definition at line 16589 of file chan_sip.c.

Referenced by load_module(), and unload_module().

int sipsock = -1 [static]

Main socket for SIP communication.

sipsock is shared between the SIP manager thread (which handles reload requests), the io handler (sipsock_read()) and the user routines that issue writes (using __sip_xmit()). The socket is -1 only when opening fails (this is a permanent condition), or when we are handling a reload() that changes its address (this is a transient situation during which we might have a harmless race, see below). Because the conditions for the race to be possible are extremely rare, we don't want to pay the cost of locking on every I/O. Rather, we remember that when the race may occur, communication is bound to fail anyways, so we just live with this event and let the protocol handle this above us.

Definition at line 1835 of file chan_sip.c.

int* sipsock_read_id [static]

ID of IO entry for sipsock FD

Definition at line 855 of file chan_sip.c.

int speerobjs = 0 [static]

Static peers

Definition at line 826 of file chan_sip.c.

struct _map_x_s stmodes[] [static]

Report Peer status in character string.

Returns:
0 if peer is unreachable, 1 if peer is online, -1 if unmonitored

Definition at line 13603 of file chan_sip.c.

Referenced by stmode2str(), and str2stmode().

struct _map_x_s strefreshers[] [static]

Definition at line 13621 of file chan_sip.c.

Referenced by str2strefresher(), and strefresher2str().

struct sockaddr_in stunaddr [static]

stun server address

Definition at line 1870 of file chan_sip.c.

struct cfsubscription_types subscription_types[] [static]

Subscription types that we support. We support

Referenced by find_subscription_type(), and subscription_type2str().

char* synopsis_dtmfmode = "Change the dtmfmode for a SIP call" [static]

Definition at line 24359 of file chan_sip.c.

char* synopsis_sipaddheader = "Add a SIP header to the outbound call" [static]

Definition at line 24364 of file chan_sip.c.

struct ao2_container* threadt [static]

The table of TCP threads.

Definition at line 1678 of file chan_sip.c.

Referenced by _sip_tcp_helper_thread(), load_module(), sip_prepare_socket(), sip_show_tcp(), sip_tcp_locate(), sip_tcptls_write(), sip_threadinfo_create(), and unload_module().

struct ast_threadstorage ts_temp_pvt = { .once = PTHREAD_ONCE_INIT , .key_init = __init_ts_temp_pvt , .custom_init = temp_pvt_init , } [static]

Definition at line 1804 of file chan_sip.c.

Referenced by transmit_response_using_temp().

char used_context[AST_MAX_CONTEXT] [static]

name of automatically created context for unloading

Definition at line 835 of file chan_sip.c.


Generated on Wed Aug 18 22:34:17 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7